/*********************************************************************
// @@@ 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:         <file>
 * Description:  
 *               
 *               
 * Created:      7/10/95
 * Language:     C++
 *
 *
 *
 *
 *****************************************************************************
 */

#include "Platform.h"


#include <math.h>
#include <unistd.h>
#include <zlib.h>
#include <openssl/md5.h>
#include <openssl/sha.h>  
#include "ComSSL.h"
#define MathSqrt(op, err) sqrt(op)

#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <uuid/uuid.h>

#include "NLSConversion.h"
#include "nawstring.h"
#include "exp_stdh.h"
#include "exp_clause_derived.h"
#include "exp_function.h"

#include "ComDefs.h"
#include "SQLTypeDefs.h"
#include "exp_datetime.h"
#include "exp_interval.h"
#include "exp_bignum.h"
#include "ComSysUtils.h"
#include "wstr.h"
#include "ComDiags.h"
#include "ComAnsiNamePart.h"
#include "ComSqlId.h"
#include "ex_globals.h"

#include "NAUserId.h"
#include "ComUser.h"
#include "ExpSeqGen.h"
#include "ComJSON.h"

#undef DllImport
#define DllImport __declspec ( dllimport )
#include "rosetta/rosgen.h"

#define ptimez_h_juliantimestamp
#define ptimez_h_including_section
#include "guardian/ptimez.h"
#ifdef ptimez_h_juliantimestamp
Section missing, generate compiler error
#endif

#define ptimez_h_converttimestamp
#define ptimez_h_including_section
#include "guardian/ptimez.h"
#ifdef ptimez_h_converttimestamp
Section missing, generate compiler error
#endif

#define ptimez_h_interprettimestamp
#define ptimez_h_including_section
#include "guardian/ptimez.h"
#ifdef ptimez_h_interprettimestamp
Section missing, generate compiler error
#endif

#define ptimez_h_computetimestamp
#define ptimez_h_including_section
#include "guardian/ptimez.h"
#ifdef ptimez_h_computetimestamp
Section missing, generate compiler error
#endif

#define psecure_h_including_section
#define psecure_h_security_app_priv_
#define psecure_h_security_psb_get_
#define psecure_h_security_ntuser_set_
#include "security/psecure.h"
#ifndef dsecure_h_INCLUDED
#define dsecure_h_INCLUDED
#include "security/dsecure.h"
#endif
#include "security/uid.h"


#include "security/uid.h"
#include "fs/feerrors.h"

extern char * exClauseGetText(OperatorTypeEnum ote);

void setVCLength(char * VCLen, Lng32 VCLenSize, ULng32 value);

static void ExRaiseJSONError(CollHeap* heap, ComDiagsArea** diagsArea, JsonReturnType type);


//#define TOUPPER(c) (((c >= 'a') && (c <= 'z')) ? (c - 32) : c);
//#define TOLOWER(c) (((c >= 'A') && (c <= 'Z')) ? (c + 32) : c);

// -----------------------------------------------------------------------
// There is currently a bug in the tandem include file sys/time.h that
// prevents us to get the definition of gettimeofday from there.
// -----------------------------------------------------------------------
//extern int  gettimeofday(struct timeval *, struct timezone *);

ExFunctionAscii::ExFunctionAscii(){};
ExFunctionChar::ExFunctionChar(){};
ExFunctionConvertHex::ExFunctionConvertHex(){};
ExFunctionRepeat::ExFunctionRepeat(){};
ExFunctionReplace::ExFunctionReplace()
{
  collation_ = CharInfo::DefaultCollation;
  setArgEncodedLen( 0, 0);//initialize the first child encoded length to 0
  setArgEncodedLen( 0, 1);//initialize the second child encoded length to 0
};
ex_function_char_length::ex_function_char_length(){};
ex_function_char_length_doublebyte::ex_function_char_length_doublebyte(){};
ex_function_oct_length::ex_function_oct_length(){};
ex_function_position::ex_function_position(){};
ex_function_position_doublebyte::ex_function_position_doublebyte(){};
ex_function_concat::ex_function_concat(){};
ex_function_lower::ex_function_lower(){};
ex_function_upper::ex_function_upper(){};
ex_function_substring::ex_function_substring(){};
ex_function_trim_char::ex_function_trim_char(){};
ExFunctionTokenStr::ExFunctionTokenStr(){};
ExFunctionReverseStr::ExFunctionReverseStr(){};
ex_function_current::ex_function_current(){};
ex_function_unixtime::ex_function_unixtime(){};
ex_function_sleep::ex_function_sleep(){};
ex_function_unique_execute_id::ex_function_unique_execute_id(){};//Trigger -
ex_function_get_triggers_status::ex_function_get_triggers_status(){};//Trigger -
ex_function_get_bit_value_at::ex_function_get_bit_value_at(){};//Trigger -
ex_function_is_bitwise_and_true::ex_function_is_bitwise_and_true(){};//MV
ex_function_explode_varchar::ex_function_explode_varchar(){};
ex_function_hash::ex_function_hash(){};
ex_function_hivehash::ex_function_hivehash(){};
ExHashComb::ExHashComb(){};
ExHiveHashComb::ExHiveHashComb(){};
ExHDPHash::ExHDPHash(){};
ExHDPHashComb::ExHDPHashComb(){};
ex_function_replace_null::ex_function_replace_null(){};
ex_function_mod::ex_function_mod(){};
ex_function_mask::ex_function_mask(){};
ExFunctionShift::ExFunctionShift(){};
ex_function_converttimestamp::ex_function_converttimestamp(){};
ex_function_dateformat::ex_function_dateformat(){};
ex_function_dayofweek::ex_function_dayofweek(){};
ex_function_extract::ex_function_extract(){};
ex_function_juliantimestamp::ex_function_juliantimestamp(){};
ex_function_exec_count::ex_function_exec_count(){};
ex_function_curr_transid::ex_function_curr_transid(){};
ex_function_ansi_user::ex_function_ansi_user(){};
ex_function_user::ex_function_user(){};
ex_function_nullifzero::ex_function_nullifzero(){};
ex_function_nvl::ex_function_nvl(){};
ex_function_json_object_field_text::ex_function_json_object_field_text(){};

ex_function_queryid_extract::ex_function_queryid_extract(){};
ExFunctionUniqueId::ExFunctionUniqueId(){};
ExFunctionRowNum::ExFunctionRowNum(){};
ExFunctionHbaseColumnLookup::ExFunctionHbaseColumnLookup() {};
ExFunctionHbaseColumnsDisplay::ExFunctionHbaseColumnsDisplay() {};
ExFunctionHbaseColumnCreate::ExFunctionHbaseColumnCreate() {};
ExFunctionCastType::ExFunctionCastType() {};
ExFunctionSequenceValue::ExFunctionSequenceValue() {};
ExFunctionHbaseTimestamp::ExFunctionHbaseTimestamp() {};
ExFunctionHbaseVersion::ExFunctionHbaseVersion() {};
ExFunctionSVariance::ExFunctionSVariance(){};
ExFunctionSStddev::ExFunctionSStddev(){};
ExpRaiseErrorFunction::ExpRaiseErrorFunction(){};
ExFunctionRandomNum::ExFunctionRandomNum(){};
ExFunctionGenericUpdateOutput::ExFunctionGenericUpdateOutput(){}; // MV,
ExFunctionInternalTimestamp::ExFunctionInternalTimestamp(){}; // Triggers
ExFunctionRandomSelection::ExFunctionRandomSelection(){};
ExHash2Distrib::ExHash2Distrib(){};
ExProgDistrib::ExProgDistrib(){};
ExProgDistribKey::ExProgDistribKey(){};
ExPAGroup::ExPAGroup(){};
ExFunctionPack::ExFunctionPack(){};
ExUnPackCol::ExUnPackCol(){};
ExFunctionRangeLookup::ExFunctionRangeLookup(){};
ExFunctionCrc32::ExFunctionCrc32(){};
ExFunctionMd5::ExFunctionMd5(){};
ExFunctionSha::ExFunctionSha(){};
ExFunctionSha2::ExFunctionSha2(){};
ExFunctionIsIP::ExFunctionIsIP(){};
ExFunctionInetAton::ExFunctionInetAton(){};
ExFunctionInetNtoa::ExFunctionInetNtoa(){};
ExFunctionSoundex::ExFunctionSoundex(){};
ExFunctionAESEncrypt::ExFunctionAESEncrypt(){};
ExFunctionAESDecrypt::ExFunctionAESDecrypt(){};

ExFunctionAscii::ExFunctionAscii(OperatorTypeEnum oper_type,
				 Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 2, attr, space)
{
  
};

ExFunctionChar::ExFunctionChar(OperatorTypeEnum oper_type,
			       Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 2, attr, space)
{
  
};

ExFunctionCrc32::ExFunctionCrc32(OperatorTypeEnum oper_type,
			       Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 2, attr, space)
{
  
};

ExFunctionMd5::ExFunctionMd5(OperatorTypeEnum oper_type,
			       Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 2, attr, space)
{
  
};

ExFunctionSha::ExFunctionSha(OperatorTypeEnum oper_type,
			       Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 2, attr, space)
{
  
};

ExFunctionSha2::ExFunctionSha2(OperatorTypeEnum oper_type,
			       Attributes ** attr, Space * space, Lng32 mode)
     : ex_function_clause(oper_type, 2, attr, space), mode(mode)
{
  
};

ExFunctionIsIP::ExFunctionIsIP(OperatorTypeEnum oper_type,
			       Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 2, attr, space)
{
  
};
            
ExFunctionInetAton::ExFunctionInetAton(OperatorTypeEnum oper_type,
			       Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 2, attr, space)
{
  
};

ExFunctionInetNtoa::ExFunctionInetNtoa(OperatorTypeEnum oper_type,
			       Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 2, attr, space)
{
  
};

ExFunctionAESEncrypt::ExFunctionAESEncrypt(OperatorTypeEnum oper_type,
                       Attributes ** attr, Space * space, int args_num, Int32 aes_mode )
     : ex_function_clause(oper_type, args_num + 1, attr, space), args_num(args_num), aes_mode(aes_mode)
{
};

ExFunctionAESDecrypt::ExFunctionAESDecrypt(OperatorTypeEnum oper_type,
                       Attributes ** attr, Space * space, int args_num, Int32 aes_mode)
     : ex_function_clause(oper_type, args_num + 1, attr, space), args_num(args_num), aes_mode(aes_mode)
{
};

ExFunctionConvertHex::ExFunctionConvertHex(OperatorTypeEnum oper_type,
					   Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 2, attr, space)
{
  
};

ExFunctionRepeat::ExFunctionRepeat(OperatorTypeEnum oper_type,
				   Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 3, attr, space)
{
  
};

ExFunctionReplace::ExFunctionReplace(OperatorTypeEnum oper_type,
				     Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 4, attr, space)
{
  collation_ = CharInfo::DefaultCollation;
  //set first and second child encoded length
  setArgEncodedLen( 0, 0);//initialize the first child encoded length to 0
  setArgEncodedLen( 0, 1);//initialize the second child encoded length to 0
};

ex_function_char_length::ex_function_char_length(OperatorTypeEnum oper_type,
						 Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 2, attr, space)
{
  
};

ex_function_char_length_doublebyte::ex_function_char_length_doublebyte(
	OperatorTypeEnum oper_type,
	Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 2, attr, space)
{
};

ex_function_oct_length::ex_function_oct_length(OperatorTypeEnum oper_type,
					       Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 2, attr, space)
{
  
};

ex_function_position::ex_function_position(OperatorTypeEnum oper_type,
					   Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 3, attr, space)
{
  
};

ex_function_position_doublebyte::ex_function_position_doublebyte
(
	OperatorTypeEnum oper_type,
        Attributes ** attr, Space * space
)
: ex_function_clause(oper_type, 3, attr, space)
{
  
};

ex_function_concat::ex_function_concat(OperatorTypeEnum oper_type,
				       Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 3, attr, space)
{
  
};

ex_function_lower::ex_function_lower(OperatorTypeEnum oper_type,
				     Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 2, attr, space)
{
  
};

ex_function_upper::ex_function_upper(OperatorTypeEnum oper_type,
				     Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 2, attr, space)
{
  
};

ex_function_substring::ex_function_substring(OperatorTypeEnum oper_type,
					     short num_operands, 
					     Attributes ** attr, Space * space)
: ex_function_clause(oper_type, num_operands, attr, space)
{
  
};

ex_function_translate::ex_function_translate(OperatorTypeEnum oper_type,
                                   Attributes ** attr,
                                   Space * space,
                                   Int32 conv_type,
                                   Int16 flags)
: ex_function_clause(oper_type, 2 , attr, space)
{
  conv_type_= conv_type;
  flags_ = flags;
};

ex_function_trim::ex_function_trim(OperatorTypeEnum oper_type,
				   Attributes ** attr,
				   Space * space,
				   Int32 mode)
: ex_function_clause(oper_type, 3 , attr, space)
{
  mode_ = mode; 
};

ex_function_trim_char::ex_function_trim_char(OperatorTypeEnum oper_type,
				   Attributes ** attr,
				   Space * space,
				   Int32 mode) 
: ex_function_trim(oper_type, attr, space, mode)
{
};

ExFunctionTokenStr::ExFunctionTokenStr(OperatorTypeEnum oper_type,
				       Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 3, attr, space)
{
};

ExFunctionReverseStr::ExFunctionReverseStr(OperatorTypeEnum oper_type,
                                           Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 2, attr, space)
{
};

ex_function_current::ex_function_current(OperatorTypeEnum oper_type,
					 Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 1, attr, space)
{
  
};

ex_function_sleep::ex_function_sleep(OperatorTypeEnum oper_type, short numOperands,
					 Attributes ** attr, Space * space)
: ex_function_clause(oper_type, numOperands, attr, space)
{
  
};

ex_function_unixtime::ex_function_unixtime(OperatorTypeEnum oper_type, short numOperands,
					 Attributes ** attr, Space * space)
: ex_function_clause(oper_type, numOperands, attr, space)
{
  
};
//++ Triggers -
ex_function_unique_execute_id::ex_function_unique_execute_id(OperatorTypeEnum oper_type,
					 Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 1, attr, space)
{
  
};

//++ Triggers -
ex_function_get_triggers_status::ex_function_get_triggers_status(OperatorTypeEnum oper_type,
					 Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 1, attr, space)
{
  
};

//++ Triggers -
ex_function_get_bit_value_at::ex_function_get_bit_value_at(OperatorTypeEnum oper_type,
					     Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 3, attr, space)
{
  
};

//++ MV
ex_function_is_bitwise_and_true::ex_function_is_bitwise_and_true(OperatorTypeEnum oper_type,
					     Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 3, attr, space)
{
  
};

ex_function_explode_varchar::ex_function_explode_varchar(OperatorTypeEnum oper_type,
							 short num_operands, 
							 Attributes ** attr, 
							 Space * space,
							 NABoolean forInsert)
     : ex_function_clause(oper_type, num_operands, attr, space),
       forInsert_(forInsert)
{
  
};

ex_function_hash::ex_function_hash(OperatorTypeEnum oper_type,
				   Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 2, attr, space)
{
};

ex_function_hivehash::ex_function_hivehash(OperatorTypeEnum oper_type,
				       Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 2, attr, space)
{
};

ExHashComb::ExHashComb(OperatorTypeEnum oper_type,
                       Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 3, attr, space)
{
};

ExHiveHashComb::ExHiveHashComb(OperatorTypeEnum oper_type,
                       Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 3, attr, space)
{
};

ExHDPHash::ExHDPHash(OperatorTypeEnum oper_type,
                     Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 2, attr, space)
{
};

ExHDPHashComb::ExHDPHashComb(OperatorTypeEnum oper_type,
                             Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 3, attr, space)
{
  
};

ex_function_replace_null::ex_function_replace_null(OperatorTypeEnum oper_type,
						   Attributes ** attr, 
						   Space * space)
: ex_function_clause(oper_type, 4, attr, space)
{
  
};

ex_function_mod::ex_function_mod(OperatorTypeEnum oper_type,
				 Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 3, attr, space)
{
  
};

ex_function_mask::ex_function_mask(OperatorTypeEnum oper_type,
                                  Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 3, attr, space)
{
  
};

ExFunctionShift::ExFunctionShift(OperatorTypeEnum oper_type,
                                 Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 3, attr, space)
{
  
};

ex_function_bool::ex_function_bool(OperatorTypeEnum oper_type,
				   Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 1, attr, space)
{
  
};

ex_function_converttimestamp::ex_function_converttimestamp
( OperatorTypeEnum oper_type
, Attributes ** attr
, Space * space
)
: ex_function_clause(oper_type, 2, attr, space)
{

};

ex_function_dateformat::ex_function_dateformat(OperatorTypeEnum oper_type,
                                               Attributes ** attr,
                                               Space * space,
                                               Int32 dateformat)
: ex_function_clause(oper_type, 2 , attr, space), dateformat_(dateformat)
{

};

ex_function_dayofweek::ex_function_dayofweek(OperatorTypeEnum oper_type,
                                             Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 2, attr, space)
{

};

ex_function_extract::ex_function_extract(OperatorTypeEnum oper_type,
                                         Attributes ** attr,
                                         Space * space,
                                         rec_datetime_field extractField)
: ex_function_clause(oper_type, 2 , attr, space), extractField_(extractField)
{

};

ex_function_juliantimestamp::ex_function_juliantimestamp
( OperatorTypeEnum oper_type
, Attributes ** attr
, Space * space
)
: ex_function_clause(oper_type, 2, attr, space)
{

};

ex_function_exec_count::ex_function_exec_count
( OperatorTypeEnum oper_type
, Attributes ** attr
, Space * space
)
: ex_function_clause(oper_type, 1, attr, space)
{
  execCount_ = 0;
};

ex_function_curr_transid::ex_function_curr_transid
( OperatorTypeEnum oper_type
, Attributes ** attr
, Space * space
)
: ex_function_clause(oper_type, 1, attr, space)
{

};

ex_function_ansi_user::ex_function_ansi_user(OperatorTypeEnum oper_type,
					     Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 1, attr, space)
{
  
};

ex_function_user::ex_function_user(OperatorTypeEnum oper_type,
				   Attributes ** attr, Space * space)
: ex_function_clause(oper_type, 2, attr, space)
{
  
};

ex_function_nullifzero::ex_function_nullifzero(OperatorTypeEnum oper_type,
					       Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 2, attr, space)
{
};

ex_function_nvl::ex_function_nvl(OperatorTypeEnum oper_type,
				 Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 3, attr, space)
{
};

ex_function_json_object_field_text::ex_function_json_object_field_text (OperatorTypeEnum oper_type,
				 Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 3, attr, space)
{
};


ex_function_queryid_extract::ex_function_queryid_extract(OperatorTypeEnum oper_type,
							 Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 3, attr, space)
{
};

ExFunctionUniqueId::ExFunctionUniqueId(OperatorTypeEnum oper_type,
				       Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 1, attr, space)
{
};

ExFunctionRowNum::ExFunctionRowNum(OperatorTypeEnum oper_type,
				       Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 1, attr, space)
{
};

ExFunctionHbaseColumnLookup::ExFunctionHbaseColumnLookup(OperatorTypeEnum oper_type,
							 Attributes ** attr, 
							 const char * colName,
							 Space * space)
  : ex_function_clause(oper_type, 2, attr, space)
{
  strcpy(colName_, colName);
};

ExFunctionHbaseColumnsDisplay::ExFunctionHbaseColumnsDisplay(OperatorTypeEnum oper_type,
							     Attributes ** attr, 
							     Lng32 numCols,
							     char * colNames,
							     Space * space)
  : ex_function_clause(oper_type, 2, attr, space),
    numCols_(numCols),
    colNames_(colNames)
{
};

ExFunctionHbaseColumnCreate::ExFunctionHbaseColumnCreate(OperatorTypeEnum oper_type,
							 Attributes ** attr, 
							 short numEntries,
							 short colNameMaxLen,
							 Int32 colValMaxLen,
                                                         short colValVCIndLen,
							 Space * space)
  : ex_function_clause(oper_type, 1, attr, space),
    numEntries_(numEntries),
    colNameMaxLen_(colNameMaxLen),
    colValMaxLen_(colValMaxLen),
    colValVCIndLen_(colValVCIndLen)
{
};

ExFunctionSequenceValue::ExFunctionSequenceValue(OperatorTypeEnum oper_type,
						 Attributes ** attr, 
						 const SequenceGeneratorAttributes &sga,
						 Space * space)
  : ex_function_clause(oper_type, 1, attr, space),
    sga_(sga),
    flags_(0)
{
};

ExFunctionHbaseTimestamp::ExFunctionHbaseTimestamp(
                                                   OperatorTypeEnum oper_type,
                                                   Attributes ** attr, 
                                                   Lng32 colIndex,
                                                   Space * space)
  : ex_function_clause(oper_type, 2, attr, space),
    colIndex_(colIndex),
    flags_(0)
{
};

ExFunctionHbaseVersion::ExFunctionHbaseVersion(
                                                   OperatorTypeEnum oper_type,
                                                   Attributes ** attr, 
                                                   Lng32 colIndex,
                                                   Space * space)
  : ex_function_clause(oper_type, 2, attr, space),
    colIndex_(colIndex),
    flags_(0)
{
};

ExFunctionCastType::ExFunctionCastType(OperatorTypeEnum oper_type,
							 Attributes ** attr, 
							 Space * space)
  : ex_function_clause(oper_type, 2, attr, space)
{
};

ExFunctionSVariance::ExFunctionSVariance(Attributes **attr, Space *space)
  : ex_function_clause(ITM_VARIANCE, 4, attr, space)
{
};

ExFunctionSStddev::ExFunctionSStddev(Attributes **attr, Space *space)
  : ex_function_clause(ITM_STDDEV, 4, attr, space)
{
  
};

ExpRaiseErrorFunction::ExpRaiseErrorFunction (Attributes **attr, 
					      Space *space,
					      Lng32 sqlCode,
					      NABoolean raiseError,
					      const char *constraintName,
					      const char *tableName,
						  const NABoolean hasStringExp)  // -- Triggers
: ex_function_clause (ITM_RAISE_ERROR, (hasStringExp ? 2 : 1), attr, space),
    theSQLCODE_(sqlCode),
    constraintName_((char *)constraintName),
    tableName_((char *)tableName)
{
    setRaiseError(raiseError);
};

ExFunctionRandomNum::ExFunctionRandomNum(OperatorTypeEnum opType,
					 short num_operands,
					 NABoolean simpleRandom,
                                         Attributes **attr, 
                                         Space *space)
  : ex_function_clause(opType, num_operands, attr, space),
    flags_(0)
{
  seed_ = 0;

  if (simpleRandom)
    flags_ |= SIMPLE_RANDOM;
}

// MV,
ExFunctionGenericUpdateOutput::ExFunctionGenericUpdateOutput(OperatorTypeEnum oper_type, 
														 Attributes **attr, 
														 Space *space)
  : ex_function_clause(oper_type, 1, attr, space)
{}

// Triggers
ExFunctionInternalTimestamp::ExFunctionInternalTimestamp(OperatorTypeEnum oper_type, 
														 Attributes **attr, 
														 Space *space)
  : ex_function_clause(oper_type, 1, attr, space)
{}

ExFunctionSoundex::ExFunctionSoundex(OperatorTypeEnum oper_type,
			       Attributes ** attr, Space * space)
     : ex_function_clause(oper_type, 2, attr, space)
{

};


// Triggers
ex_expr::exp_return_type ex_function_get_bit_value_at::eval(char *op_data[],
						     CollHeap *heap,
						     ComDiagsArea** diagsArea)
{
  Lng32 buffLen = getOperand(1)->getLength(op_data[1]);
  
  // Get the position from operand 2.
  Lng32 pos = *(Lng32 *)op_data[2];

  // The character we look into
  Lng32 charnum = pos / 8;
  // The bit in the character we look into
  Lng32 bitnum = 8-(pos % 8)-1;

  // Check for error conditions.
  if ((charnum >= buffLen) || (charnum < 0))
  {
      ExRaiseSqlError(heap, diagsArea, EXE_GETBIT_ERROR);
      return ex_expr::EXPR_ERROR;
  }

  unsigned char onechar = *(unsigned char *)(op_data[1] + charnum);
  unsigned char mask = 1;
  mask = mask<<bitnum;

  *((ULng32*)op_data[0]) = (ULng32) (mask & onechar ? 1 : 0);

  return ex_expr::EXPR_OK;
}
;

//++ MV
// The function returns True if any of the bits is set in both of the strings
ex_expr::exp_return_type ex_function_is_bitwise_and_true::eval(char *op_data[],
						     CollHeap *heap,
						     ComDiagsArea** diagsArea)
{
  Lng32 leftSize = getOperand(1)->getLength(op_data[1]);
  Lng32 rightSize = getOperand(2)->getLength(op_data[2]);
  
  if (leftSize != rightSize)
  {
    ExRaiseSqlError(heap, diagsArea, EXE_IS_BITWISE_AND_ERROR);
    return ex_expr::EXPR_ERROR;
  }

  // Iterate through all characters until one "bitwise and" returns TRUE

  // Starting with False 
  *(Lng32 *)op_data[0] = 0;
  unsigned char *leftCharPtr = (unsigned char *)(op_data[1]);
  unsigned char *rightCharPtr = (unsigned char *)(op_data[2]);
  
  unsigned char *endBarrier = rightCharPtr + rightSize;

  for (; rightCharPtr < endBarrier; rightCharPtr++, leftCharPtr++)
  {
     if ((*leftCharPtr) & (*rightCharPtr))
     {
	*(Lng32 *)op_data[0] = 1;
	
	break;
     }
  }
 
  return ex_expr::EXPR_OK;
  
}

ExFunctionRandomSelection::ExFunctionRandomSelection(OperatorTypeEnum opType, 
                                                     Attributes **attr, 
                                                     Space *space,
                                                     float selProb)
  : ExFunctionRandomNum(opType, 1, FALSE, attr, space)
{
  if (selProb < 0)
    selProb = 0.0;
  selProbability_ = selProb;
  difference_ = -1;
}

ExHash2Distrib::ExHash2Distrib(Attributes **attr, Space *space)
  : ex_function_clause(ITM_HASH2_DISTRIB, 3, attr, space)
{}

ExProgDistrib::ExProgDistrib(Attributes **attr, Space *space)
  : ex_function_clause(ITM_PROGDISTRIB, 3, attr, space)
{}

ExProgDistribKey::ExProgDistribKey(Attributes **attr, Space *space)
  : ex_function_clause(ITM_PROGDISTRIBKEY, 4, attr, space)
{}

ExPAGroup::ExPAGroup(Attributes **attr, Space *space)
  : ex_function_clause(ITM_PAGROUP, 4, attr, space)
{}

ExUnPackCol::ExUnPackCol(Attributes **attr,
                         Space *space,
                         Lng32 width,
                         Lng32 base,
                         NABoolean nullsPresent)
  : width_(width),
    base_(base),
    ex_function_clause(ITM_UNPACKCOL, 3, attr, space)
{
  setNullsPresent(nullsPresent);
};

ExFunctionRangeLookup::ExFunctionRangeLookup(Attributes** attr,
					     Space* space,
					     Lng32 numParts,
					     Lng32 partKeyLen)
     : ex_function_clause(ITM_RANGE_LOOKUP, 3, attr, space),
       numParts_(numParts),
       partKeyLen_(partKeyLen)
{
} 

ex_expr::exp_return_type ex_function_concat::eval(char *op_data[],
						  CollHeap *heap,
						  ComDiagsArea** diagsArea)
{
  Lng32 len1 = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);
  Lng32 len2 = getOperand(2)->getLength(op_data[-MAX_OPERANDS+2]);

  CharInfo::CharSet cs = ((SimpleType *)getOperand(1))->getCharSet();

  if ( cs == CharInfo::UTF8 )
  {
     Int32 prec1 = ((SimpleType *)getOperand(1))->getPrecision();
     len1 = Attributes::trimFillerSpaces( op_data[1], prec1, len1, cs );

     Int32 prec2 = ((SimpleType *)getOperand(2))->getPrecision();
     len2 = Attributes::trimFillerSpaces( op_data[2], prec2, len2, cs );
  }
  
  Lng32 max_len = getOperand(0)->getLength();
  if ((len1 + len2) > max_len) {
    ExRaiseFunctionSqlError(heap, diagsArea, EXE_STRING_OVERFLOW,
			    derivedFunction(),
			    origFunctionOperType());
    return ex_expr::EXPR_ERROR;
  }

  Int32 actual_length = len1+len2;
  
  // If operand 0 is varchar, store the sum of operand 1 length and 
  // operand 2 length in the varlen area.
  getOperand(0)->setVarLength((actual_length), op_data[-MAX_OPERANDS]);
  
  // Now, copy the contents of operand 1 followed by the contents of
  // operand 2 into operand 0.
  str_cpy_all(op_data[0], op_data[1], len1); 
  str_cpy_all(&op_data[0][len1], op_data[2], len2);

  //
  // Blankpad the target (if needed).
  //
  if ((actual_length) < max_len)
    str_pad(&op_data[0][actual_length], max_len - actual_length, ' ');
  
  return ex_expr::EXPR_OK;
};

ex_expr::exp_return_type ExFunctionRepeat::eval(char *op_data[],
						CollHeap *heap,
						ComDiagsArea** diagsArea)
{
  Lng32 repeatCount = *(Lng32 *)op_data[2];

  Lng32 len1 = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);

  CharInfo::CharSet cs = ((SimpleType *)getOperand(1))->getCharSet();
  if ( cs == CharInfo::UTF8 )
  {
     Int32 prec1 = ((SimpleType *)getOperand(1))->getPrecision();
     len1 = Attributes::trimFillerSpaces( op_data[1], prec1, len1, cs );
  }

  Lng32 resultMaxLen = getOperand(0)->getLength();

  if ((repeatCount < 0) || ((repeatCount * len1) > resultMaxLen))
    {
      ExRaiseFunctionSqlError(heap, diagsArea, EXE_STRING_OVERFLOW,
                              derivedFunction(),
                              origFunctionOperType());

      return ex_expr::EXPR_ERROR;
    }

  Lng32 currPos = 0;
  for (Int32 i = 0; i < repeatCount; i++)
    {
      str_cpy_all(&op_data[0][currPos], op_data[1], len1);

      currPos += len1;
    }

  // If operand 0 is varchar, store the length.
  getOperand(0)->setVarLength(currPos, op_data[-MAX_OPERANDS]);

  return ex_expr::EXPR_OK;
};


ex_expr::exp_return_type ExFunctionReplace::eval(char *op_data[],
						CollHeap *heap,
						ComDiagsArea** diagsArea)
{
  CharInfo::CharSet cs = ((SimpleType *)getOperand(0))->getCharSet();


  // Note: all lengths are byte lengths.

 
  // source string

  Lng32 len1 = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);
  char * str1 = op_data[1];

  if ( cs == CharInfo::UTF8 )
  {
     Int32 prec1 = ((SimpleType *)getOperand(1))->getPrecision();
     len1 = Attributes::trimFillerSpaces( str1, prec1, len1, cs );
  }

  // if caseinsensitive search is to be done, make a copy of the source
  // string and upshift it. This string will be used to do the search.
  // The original string will be used to replace.
  char * searchStr1 = str1;
  if ((caseInsensitiveOperation()) && (heap) && (str1))
    {
      searchStr1 = new(heap) char[len1];
      str_cpy_convert(searchStr1, str1, len1, 1);
    }

  // string to search for in string1
  Lng32 len2 = getOperand(2)->getLength(op_data[-MAX_OPERANDS+2]);
  char * str2 = op_data[2];

  // string to replace string2 with in string1
  Lng32 len3 = getOperand(3)->getLength(op_data[-MAX_OPERANDS+3]);
  char * str3 = op_data[3];

  if ( cs == CharInfo::UTF8 )
  {
     Int32 prec2 = ((SimpleType *)getOperand(2))->getPrecision();
     len2 = Attributes::trimFillerSpaces( str2, prec2, len2, cs );

     Int32 prec3 = ((SimpleType *)getOperand(3))->getPrecision();
     len3 = Attributes::trimFillerSpaces( str3, prec3, len3, cs );
  }

  Lng32 resultMaxLen = getOperand(0)->getLength();
  char * result = op_data[0];

  char * sourceStr = searchStr1;
  char * searchStr = str2;
  Int32 lenSourceStr =  len1; //getArgEncodedLen(0);
  Int32 lenSearchStr = len2; //getArgEncodedLen(1);
  Int32 effLenSourceStr =  len1; //getArgEncodedLen(0);
  Int32 effLenSearchStr = len2; //getArgEncodedLen(1);

  Int16 nPasses = 1;

  if (CollationInfo::isSystemCollation(getCollation()))
  {
    nPasses= CollationInfo::getCollationNPasses(getCollation());
    lenSourceStr = getArgEncodedLen(0);
    lenSearchStr = getArgEncodedLen(1);

    assert (heap);

    sourceStr = new(heap) char [lenSourceStr];
    ex_function_encode::encodeCollationSearchKey(
				(UInt8 *) str1,
				len1,
				(UInt8 *) sourceStr,
				lenSourceStr,
                                (Int32 &) effLenSourceStr,
				nPasses,
				getCollation(),
				TRUE);
    
    searchStr = new(heap) char [lenSearchStr];


    ex_function_encode::encodeCollationSearchKey(
				(UInt8 *) str2,
				len2,
				(UInt8 *) searchStr,
				lenSearchStr,
                                (Int32 &)effLenSearchStr,
				nPasses,
				getCollation(),
				TRUE);

  }

  short bpc = (getOperand(1)->widechar() ? 2 : 1);

  NABoolean done = FALSE;
  Lng32 position;
  Lng32 currPosStr1 = 0;
  Lng32 currLenStr1 = len1;
  Lng32 currPosResult = 0;
  Lng32 currLenResult = 0;
  while (! done)
    {

      position = 
	  ex_function_position::findPosition(&sourceStr[currPosStr1 * nPasses], 
					      currLenStr1 * nPasses,
					      searchStr, 
                                              effLenSearchStr, 
                                              bpc, 
                                              nPasses, 
                                              getCollation(),
					      0,
					      cs);

      if(position < 0)
      {
        const char *csname = CharInfo::getCharSetName(cs);
        ExRaiseSqlError(heap, diagsArea, EXE_INVALID_CHARACTER);
        *(*diagsArea) << DgString0(csname) << DgString1("REPLACE FUNCTION"); 
        return ex_expr::EXPR_ERROR;
      }
      if (position > 0)
	{
	  position = position - 1;

	  // copy part of str1 from currPosStr1 till position into result
	  if ((currLenResult + position) > resultMaxLen) {
            if (sourceStr && sourceStr != str1)
              NADELETEBASIC(sourceStr,(heap));
            if (searchStr && searchStr != str2)
              NADELETEBASIC(searchStr,(heap));
  
            ExRaiseFunctionSqlError(heap, diagsArea, EXE_STRING_OVERFLOW,
				    derivedFunction(),
				    origFunctionOperType());

	    return ex_expr::EXPR_ERROR;
	  }

	  if (position > 0)
	    {
	      str_cpy_all(&result[currPosResult], &str1[currPosStr1], 
			  position);
	    }

	  currPosResult += position;
	  currLenResult += position;
	  
	  currPosStr1 += (position + len2) ;
	  currLenStr1 -= (position + len2) ;

	  // now copy str3 to result. This is the replacement.
	  if ((currLenResult + len3) > resultMaxLen) {
            if (sourceStr && sourceStr != str1)
              NADELETEBASIC(sourceStr,(heap));
            if (searchStr && searchStr != str2)
              NADELETEBASIC(searchStr,(heap));
  
            ExRaiseFunctionSqlError(heap, diagsArea, EXE_STRING_OVERFLOW,
				    derivedFunction(),
				    origFunctionOperType());

	    return ex_expr::EXPR_ERROR;
	  }

	  str_cpy_all(&result[currPosResult], str3, len3);
	  currLenResult += len3;
	  currPosResult += len3;
	}
      else
	{
	  done = TRUE;

	  if ((currLenResult + currLenStr1) > resultMaxLen) {
            if (sourceStr && sourceStr != str1)
              NADELETEBASIC(sourceStr,(heap));
            if (searchStr && searchStr != str2)
              NADELETEBASIC(searchStr,(heap));
  
	    ExRaiseFunctionSqlError(heap, diagsArea, EXE_STRING_OVERFLOW,
				    derivedFunction(),
				    origFunctionOperType());

	    return ex_expr::EXPR_ERROR;
	  }

	  if (currLenStr1 > 0)
	    str_cpy_all(&result[currPosResult], &str1[currPosStr1], currLenStr1);
	  currLenResult += currLenStr1;
	}
    }

  // If operand 0 is varchar, store the length.
  getOperand(0)->setVarLength(currLenResult, op_data[-MAX_OPERANDS]);
  if (sourceStr && sourceStr != str1)
    NADELETEBASIC(sourceStr,(heap));
  if (searchStr && searchStr != str2)
    NADELETEBASIC(searchStr,(heap));
  
  return ex_expr::EXPR_OK;
};
  

ex_expr::exp_return_type ex_function_substring::eval(char *op_data[],
						     CollHeap *heap,
						     ComDiagsArea** diagsArea)
{
  Int32 len1_bytes = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);
  
  // Get the starting position in characters from operand 2.
  // This may be a negative value!
  Int32 specifiedCharStartPos = *(Lng32 *)op_data[2];

  // Starting position in bytes. It can NOT be a negative value.
  Int32 startByteOffset = 0; // Assume beginning of buffer for now.
  
  CharInfo::CharSet cs = ((SimpleType *)getOperand(1))->getCharSet();


  // Convert number of character to offset in buffer.
  if(specifiedCharStartPos > 1)
  {
    startByteOffset = Attributes::convertCharToOffset(op_data[1], specifiedCharStartPos, len1_bytes, cs);

    if(startByteOffset < 0)
    {
      const char *csname = CharInfo::getCharSetName(cs);
      ExRaiseSqlError(heap, diagsArea, EXE_INVALID_CHARACTER);
      *(*diagsArea) << DgString0(csname) << DgString1("SUBSTRING FUNCTION"); 
      return ex_expr::EXPR_ERROR;
    }
  }
  else { /* Leave startByteOffset at 0 */ }

  // If operand 3 exists, get the length of substring in characters from operand
  // 3. Otherwise, if specifiedCharStartPos > 0, length is from specifiedCharStartPos char to end of buf.
  // If specifiedCharStartPos is 0, length is all of buf except last character.
  // If specifiedCharStartPos is negative, length is even less (by that negative amount).

  Int32 inputLen_bytes = len1_bytes ;      // Assume byte count = length of string for now
  Int32 specifiedLenInChars = inputLen_bytes ;  // Assume char count = byte count for now

  Int32 prec1 = 0;

  if (getNumOperands() == 4)
      specifiedLenInChars = *(Lng32 *)op_data[3]; // Use specified desired length for now

  if ( cs == CharInfo::UTF8 )
  {
     prec1 = ((SimpleType *)getOperand(1))->getPrecision();
     if ( prec1 )
        inputLen_bytes = Attributes::trimFillerSpaces( op_data[1], prec1, inputLen_bytes, cs );
  }

  // NOTE: Following formula for lastChar works even if specifiedCharStartPos is 0 or negative.

  Int32 lastChar = specifiedLenInChars + (specifiedCharStartPos - 1);

  // The end of the substr as a byte offset
  Int32 endOff_bytes = inputLen_bytes;  // Assume length of input for now.

  Int32 actualLenInBytes = 0;

  if ( startByteOffset >= inputLen_bytes )
  {
     // Nothing left in buf to copy, so endOff_bytes and actualLenInBytes are OK as is.
     startByteOffset = inputLen_bytes; // IGNORE it if specified start > end of buffer!
     ;
  }
  else if (lastChar > 0)
  {
    endOff_bytes = Attributes::convertCharToOffset (op_data[1], lastChar+1, inputLen_bytes, cs);

    if(endOff_bytes < 0)
    {
      const char *csname = CharInfo::getCharSetName(cs);
      ExRaiseSqlError(heap, diagsArea, EXE_INVALID_CHARACTER);
      *(*diagsArea) << DgString0(csname) << DgString1("SUBSTRING FUNCTION"); 
      return ex_expr::EXPR_ERROR;
    }
  }
  else endOff_bytes = 0;
  
  // Check for error conditions. endOff_bytes will be less than startByteOffset if length is
  // less than 0.
  if (endOff_bytes < startByteOffset)
    {
      ExRaiseFunctionSqlError(heap, diagsArea, EXE_SUBSTRING_ERROR,
			      derivedFunction(),
			      origFunctionOperType());
      return ex_expr::EXPR_ERROR;
    }

  actualLenInBytes = endOff_bytes - startByteOffset;

  // Now, copy the substring of operand 1 from the starting position into
  // operand 0, if actualLenInBytes is greater than 0.
  if ( actualLenInBytes > 0) 
    str_cpy_all(op_data[0], &op_data[1][startByteOffset],  actualLenInBytes);

  //
  // Blankpad the target (if needed).
  //
  Int32 len0_bytes = getOperand(0)->getLength();

  if ( (actualLenInBytes < len0_bytes)  && prec1 )
     str_pad(&op_data[0][actualLenInBytes], len0_bytes - actualLenInBytes, ' ');
       
  // store the length of substring in the varlen indicator.
  if (getOperand(0)->getVCIndicatorLength() > 0)
    getOperand(0)->setVarLength( actualLenInBytes, op_data[-MAX_OPERANDS] );

  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ex_function_trim_char::eval(char *op_data[],
						CollHeap *heap,
						ComDiagsArea** diagsArea)
{
  const Int32 lenSrcStrSmallBuf = 128;
  char srcStrSmallBuf[lenSrcStrSmallBuf];

  const Int32 lenTrimCharSmallBuf = 8;
  char trimCharSmallBuf[lenTrimCharSmallBuf];

  // find out the length of trim character.
  Lng32 len1 = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);

  CharInfo::CharSet cs = ((SimpleType *)getOperand(0))->getCharSet();


  if ( cs == CharInfo::UTF8 )
  {
     Int32 prec1 = ((SimpleType *)getOperand(1))->getPrecision();
     len1 = Attributes::trimFillerSpaces( op_data[1], prec1, len1, cs );
  }

  Int32 number_bytes = 0;
  
  number_bytes = Attributes::getFirstCharLength(op_data[1], len1, cs);
  if(number_bytes < 0)
  {
    const char *csname = CharInfo::getCharSetName(cs);
    ExRaiseSqlError(heap, diagsArea, EXE_INVALID_CHARACTER);
    *(*diagsArea) << DgString0(csname) << DgString1("TRIM FUNCTION"); 
    return ex_expr::EXPR_ERROR;
  }


  // len1 (length of trim character) must be 1 character. Raise an exception if greater
  // than 1.
  if (len1 != number_bytes)
    {
      ExRaiseFunctionSqlError(heap, diagsArea, EXE_TRIM_ERROR,
			      derivedFunction(),
			      origFunctionOperType());
      return ex_expr::EXPR_ERROR;
    }   

  Lng32 len2 = getOperand(2)->getLength(op_data[-MAX_OPERANDS+2]);

  if (cs == CharInfo::UTF8) // If so, must ignore any filler spaces at end of string
  {
     Int32 prec2 = ((SimpleType *)getOperand(2))->getPrecision();
     len2 = Attributes::trimFillerSpaces( op_data[2], prec2, len2, cs );
  }
  
  Int16 nPasses = 1; 
  char * trimChar = op_data[1];
  char * srcStr = op_data[2];
  Lng32 lenSrcStr = len2;
  Lng32 lenTrimChar = len1;
  Lng32 effLenSourceStr = len2; 
  Lng32 effLenTrimChar = len1; 

  // case of collation -- 
  if (CollationInfo::isSystemCollation(getCollation()))
  {
    nPasses = CollationInfo::getCollationNPasses(getCollation());

    //get the length of the encoded source string
    lenSrcStr = getSrcStrEncodedLength();

    //get length of encoded trim character
    lenTrimChar = getTrimCharEncodedLength();
    
    assert (heap);
    
    if (lenSrcStr <= lenSrcStrSmallBuf)
    {    
      srcStr = srcStrSmallBuf;
    }
    else
    {
      srcStr = new(heap) char [lenSrcStr];
    }
 
    //get encoded key
    ex_function_encode::encodeCollationSearchKey(
				(UInt8 *) op_data[2],
				len2,
				(UInt8 *) srcStr,
				lenSrcStr,
                                (Int32 &) effLenSourceStr,
				nPasses,
				getCollation(),
				FALSE);

    if (lenTrimChar <= lenTrimCharSmallBuf)
    {
      trimChar = trimCharSmallBuf;
    }
    else
    {
      trimChar = new(heap) char [lenTrimChar];
    }

    //get encoded key
    ex_function_encode::encodeCollationSearchKey(
				(UInt8 *) op_data[1],
				len1,
				(UInt8 *) trimChar,
				lenTrimChar,
                                (Int32 &) effLenTrimChar,
				nPasses,
				getCollation(),
				FALSE);

  }
  // Find how many leading characters in operand 2 correspond to the trim
  // character.
  Lng32  len0 = len2;
  Lng32  start = 0;   
  NABoolean notEqualFlag = 0;
  
  if ((getTrimMode() == 1) || (getTrimMode() == 2))
  {
    while (start <= len2 - len1)
    { 
	for(Int32 i= 0; i < lenTrimChar; i++)
        {
          if(trimChar[i] != srcStr[start * nPasses +i])
          {
             notEqualFlag = 1;
	     break;
          }
        }
        if (notEqualFlag == 0)
        {
          start += len1;
          len0 -= len1;
        }
        else
          break;
    }
  }
  
  // Find how many trailing characters in operand 2 correspond to the trim
  // character.
  Int32 end = len2;
  Int32 endt;
  Int32 numberOfCharacterInBuf;
  Int32 bufferLength = end - start;
  const Int32 smallBufSize = 128;
  char smallBuf[smallBufSize];

  notEqualFlag = 0;

  if ((getTrimMode() == 0) || (getTrimMode() == 2))
  {
      char *charLengthInBuf;

      if(bufferLength <= smallBufSize)
        charLengthInBuf = smallBuf;
      else
        charLengthInBuf = new(heap) char[bufferLength];

      numberOfCharacterInBuf =
         Attributes::getCharLengthInBuf(op_data[2] + start,
             op_data[2] + end, charLengthInBuf, cs);

      if(numberOfCharacterInBuf < 0)
      {
        if (srcStr && srcStr != op_data[2])
          NADELETEBASIC(srcStr,(heap));
        if (trimChar && trimChar != op_data[1])
          NADELETEBASIC(trimChar,(heap));

        const char *csname = CharInfo::getCharSetName(cs);
        ExRaiseSqlError(heap, diagsArea, EXE_INVALID_CHARACTER);
        *(*diagsArea) << DgString0(csname) << DgString1("TRIM FUNCTION"); 
        return ex_expr::EXPR_ERROR;
      }

    while (end >= start + len1) 
    {
      if (charLengthInBuf[--numberOfCharacterInBuf] != len1) break;

      endt = end - len1;
      for(Int32 i = 0; i < lenTrimChar; i++)
      {
        if (trimChar[i] != srcStr[endt *nPasses + i])
        {
          notEqualFlag = 1;
          break;
        }
      }
      if(notEqualFlag == 0)
      {
        end = endt;
        len0 -= len1;
      }
      else
        break;
    }
    if(bufferLength > smallBufSize)
      NADELETEBASIC(charLengthInBuf, heap);
  }
  
  // Result is always a varchar.
  // store the length of trimmed string in the varlen indicator.
  getOperand(0)->setVarLength(len0, op_data[-MAX_OPERANDS]);

  // Now, copy operand 2 skipping the trim characters into
  // operand 0.
  
  if (len0 > 0) 
    str_cpy_all(op_data[0], &op_data[2][start], len0); 

  if (srcStr && srcStr != srcStrSmallBuf && srcStr != op_data[2] )
    NADELETEBASIC(srcStr,(heap));
  if (trimChar  && trimChar != trimCharSmallBuf && trimChar != op_data[1])
    NADELETEBASIC(trimChar,(heap));

  
  return ex_expr::EXPR_OK;
};

ex_expr::exp_return_type ex_function_lower::eval(char *op_data[],
                                                 CollHeap* heap,
                                                 ComDiagsArea** diagsArea)
{
  Int32 len1 = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);

  CharInfo::CharSet cs = ((SimpleType *)getOperand(0))->getCharSet();


  if ( cs == CharInfo::UTF8 )
  {
     Int32 prec1 = ((SimpleType *)getOperand(1))->getPrecision();
     len1 = Attributes::trimFillerSpaces( op_data[1], prec1, len1, cs );
  }

  getOperand(0)->setVarLength(len1, op_data[-MAX_OPERANDS]);

  cnv_charset charset = convertCharsetEnum(cs);

  Int32 number_bytes;
  Int32 total_bytes_out = 0;
  char tmpBuf[4];

  UInt32 UCS4value;
  UInt16 UCS2value;

  // Now, copy the contents of operand 1 after the case change into operand 0.
  Int32 len0 = 0;
  if(cs == CharInfo::ISO88591)
  {
    while (len0 < len1)
    {
      op_data[0][len0] = TOLOWER(op_data[1][len0]);
      ++len0;
    }
  }
  else 
  {
    // If character set is UTF8 or SJIS or ?, convert the string to UCS2,
    // call UCS2 lower function and convert the string back.
    while (len0 < len1)
    {
      number_bytes =
        LocaleCharToUCS4(op_data[1] + len0, len1 - len0, &UCS4value, charset);

      if(number_bytes < 0)
      {
        const char *csname = CharInfo::getCharSetName(cs);
        ExRaiseSqlError(heap, diagsArea, EXE_INVALID_CHARACTER);
        *(*diagsArea) << DgString0(csname) << DgString1("LOWER FUNCTION"); 
        return ex_expr::EXPR_ERROR;
      }

      if(number_bytes == 1 && (op_data[1][len0] & 0x80) == 0)
      {
        op_data[0][len0] =  TOLOWER(op_data[1][len0]); 
        ++len0;
        ++total_bytes_out;
      }
      else
      {
        UCS2value = UCS4value & 0XFFFF;

        UCS4value = unicode_char_set::to_lower(*(NAWchar *)&UCS2value);

        Int32 number_bytes_out =
          UCS4ToLocaleChar((const UInt32 *)&UCS4value, tmpBuf,
          CharInfo::maxBytesPerChar(cs), charset);

        if(number_bytes_out < 0)
        {
          const char *csname = CharInfo::getCharSetName(cs);
          ExRaiseSqlError(heap, diagsArea, EXE_INVALID_CHARACTER);
          *(*diagsArea) << DgString0(csname) << DgString1("LOWER FUNCTION"); 
          return ex_expr::EXPR_ERROR;
        }

        for (Int32 j = 0; j < number_bytes_out; j++)
        {
          op_data[0][total_bytes_out] =  tmpBuf[j]; 
          total_bytes_out++;
        }
        len0 += number_bytes;
      }
    }
  }
  if (getOperand(0)->getVCIndicatorLength() > 0)
    getOperand(0)->setVarLength(total_bytes_out, op_data[-MAX_OPERANDS]);

  return ex_expr::EXPR_OK;
};

ex_expr::exp_return_type ex_function_upper::eval(char *op_data[],
                                                 CollHeap* heap,
                                                 ComDiagsArea** diagsArea)
{
  Int32 len1 = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);
  Int32 len0 = getOperand(0)->getLength();

  Int32 in_pos = 0;
  Int32 out_pos = 0;

  CharInfo::CharSet cs = ((SimpleType *)getOperand(1))->getCharSet();


  if ( cs == CharInfo::UTF8 )
  {
     Int32 prec1 = ((SimpleType *)getOperand(1))->getPrecision();
     len1 = Attributes::trimFillerSpaces( op_data[1], prec1, len1, cs );
  }

  Int32 number_bytes;

  UInt32 UCS4value = 0;
  UInt16 UCS2value = 0;

  // Now, copy the contents of operand 1 after the case change into operand 0.
  if(cs == CharInfo::ISO88591)
  {
    while(in_pos < len1)
    {
      op_data[0][out_pos] = TOUPPER(op_data[1][in_pos]);
      ++in_pos;
      ++out_pos;
    }
  }
  else
  {
    cnv_charset charset = convertCharsetEnum(cs);

    // If character set is UTF8 or SJIS or ?, convert the string to UCS2,
    // call UCS2 upper function and convert the string back.
    while(in_pos < len1)
    {
      number_bytes =
        LocaleCharToUCS4(op_data[1] + in_pos, len1 - in_pos, &UCS4value, charset);

      if(number_bytes < 0)
      {
        const char *csname = CharInfo::getCharSetName(cs);
        ExRaiseSqlError(heap, diagsArea, EXE_INVALID_CHARACTER);
        *(*diagsArea) << DgString0(csname) << DgString1("UPPER FUNCTION"); 
        return ex_expr::EXPR_ERROR;
      }

      if(number_bytes == 1  && (op_data[1][in_pos] & 0x80) == 0)
      {
        op_data[0][out_pos] =  TOUPPER(op_data[1][in_pos]); 
        ++in_pos;
        ++out_pos;
      }
      else
      {
        in_pos += number_bytes;

        UCS2value = UCS4value & 0XFFFF;
        NAWchar  wcUpshift[3];
        Int32 charCnt = 1;    // Default count to 1

        // search against unicode_lower2upper_mapping_table_full
        NAWchar* tmpWCP = unicode_char_set::to_upper_full(UCS2value);
        if ( tmpWCP )
        {
           wcUpshift[0] = *tmpWCP++;
           wcUpshift[1] = *tmpWCP++;
           wcUpshift[2] = *tmpWCP  ;
           charCnt = (*tmpWCP) ? 3 : 2;
        }
        else
           wcUpshift[0] = unicode_char_set::to_upper(UCS2value);

        for (Int32 ii = 0 ; ii < charCnt ; ii++)
        {
          UInt32 UCS4_val = wcUpshift[ii];
          char tmpBuf[8];

          Int32 out_bytes = UCS4ToLocaleChar((const UInt32 *)&UCS4_val, tmpBuf,
                         CharInfo::maxBytesPerChar(cs), charset);
          if(out_bytes < 0)
          {
            const char *csname = CharInfo::getCharSetName(cs);
            ExRaiseSqlError(heap, diagsArea, EXE_INVALID_CHARACTER);
            *(*diagsArea) << DgString0(csname) << DgString1("UPPER FUNCTION"); 
            return ex_expr::EXPR_ERROR;
          }
          if (out_pos + out_bytes > len0)
          {
            ExRaiseFunctionSqlError(heap, diagsArea, EXE_STRING_OVERFLOW,
                                    derivedFunction(),
                                    origFunctionOperType());
            return ex_expr::EXPR_ERROR;
          }
          for (Int32 j = 0; j < out_bytes; j++)
          {
            op_data[0][out_pos] =  tmpBuf[j]; 
            ++out_pos;
          }
        }
      }
    }
  }
  getOperand(0)->setVarLength(out_pos, op_data[-MAX_OPERANDS]);

  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ex_function_oct_length::eval(char *op_data[],
						      CollHeap*,
						      ComDiagsArea**)
{
  // Move operand's length into result.
  // The data type of result is long.
  Int32 len1 = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);

  CharInfo::CharSet cs = ((SimpleType *)getOperand(1))->getCharSet();
  if ( cs == CharInfo::UTF8 )
  {
     Int32 prec1 = ((SimpleType *)getOperand(1))->getPrecision();
     len1 = Attributes::trimFillerSpaces( op_data[1], prec1, len1, cs );
  }
  *(Lng32 *)op_data[0] = len1;
  
  return ex_expr::EXPR_OK;
};

ex_expr::exp_return_type ExFunctionAscii::eval(char *op_data[],CollHeap* heap,
					      ComDiagsArea** diagsArea)
{
  CharInfo::CharSet cs = ((SimpleType *)getOperand(1))->getCharSet();


  Int32 len1 = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);

  if (len1 > 0)
  {
    switch (getOperType() )
    {
    case ITM_UNICODE_CODE_VALUE:
      {
        UInt16 temp;
        str_cpy_all((char *)&temp, op_data[1], 2);
        *(Lng32 *)op_data[0] = temp;
      }
      break;

    case ITM_NCHAR_MP_CODE_VALUE:
      {
        UInt16 temp;
#if defined( NA_LITTLE_ENDIAN )
        // swap the byte order on little-endian machines as NCHAR_MP charsets are stored
        // in multi-byte form (i.e. in big-endian order).
          temp = reversebytesUS( *((NAWchar*) op_data[1]) );
#else
        str_cpy_all((char *)&temp, op_data[1], 2);
#endif
        *(UInt32 *)op_data[0] = temp;
      }
      break;

    case ITM_ASCII:
      {
        Int32 val = (unsigned char)(op_data[1][0]);

        if ( (val > 0x7F) && (cs != CharInfo::ISO88591) )
        {
          ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
          **diagsArea << DgString0("ASCII");

          if (derivedFunction())
          {
            **diagsArea << DgSqlCode(-EXE_MAPPED_FUNCTION_ERROR);
            **diagsArea << DgString0(exClauseGetText(origFunctionOperType()));
          }

          return ex_expr::EXPR_ERROR;
        }
        *(UInt32 *)op_data[0] = (unsigned char)(op_data[1][0]);
        break;
      }
    case ITM_CODE_VALUE:
    default:
      {
        UInt32 UCS4value = 0;
        if ( cs == CharInfo::ISO88591 )
           UCS4value = *(unsigned char *)(op_data[1]);
        else
        {
           UInt32 firstCharLen =
              LocaleCharToUCS4(op_data[1], len1, &UCS4value, convertCharsetEnum(cs));

           if( firstCharLen < 0 )
           {
             const char *csname = CharInfo::getCharSetName(cs);
             ExRaiseSqlError(heap, diagsArea, EXE_INVALID_CHARACTER);
             *(*diagsArea) << DgString0(csname) << DgString1("CODE_VALUE FUNCTION"); 
             return ex_expr::EXPR_ERROR;
           }
        }
        *(Int32 *)op_data[0] = UCS4value;
        break;
      }
    }
  }
  else
    *(Int32 *)op_data[0] = 0;

  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ExFunctionChar::eval(char *op_data[],CollHeap* heap,
					      ComDiagsArea** diagsArea)
{
  UInt32 asciiCode = *(Lng32 *)op_data[1];
  Int32 charLength = 1;

  CharInfo::CharSet cs = ((SimpleType *)getOperand(0))->getCharSet();


  if (getOperType() == ITM_CHAR)
  {
    if (cs == CharInfo::ISO88591)
    {
      if (asciiCode < 0 || asciiCode > 0xFF)
      {
        ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
        **diagsArea << DgString0("CHAR");
        if (derivedFunction())
        {
          **diagsArea << DgSqlCode(-EXE_MAPPED_FUNCTION_ERROR);
          **diagsArea << DgString0(exClauseGetText(origFunctionOperType()));
        }
        return ex_expr::EXPR_ERROR;
      }
      else
      {
        op_data[0][0] = (char)asciiCode;
        getOperand(0)->setVarLength(1, op_data[-MAX_OPERANDS]);
        return ex_expr::EXPR_OK;
      }
    }
    else // Must be UTF8 (at least until we support SJIS or some other multi-byte charset)
    {
      Int32 len0_bytes = getOperand(0)->getLength();

      ULng32 * UCS4ptr = (ULng32 *)op_data[1];

      Int32 charLength = UCS4ToLocaleChar( UCS4ptr, (char *)op_data[0], len0_bytes, cnv_UTF8 );

      if ( charLength < 0 )
      {
        const char *csname = CharInfo::getCharSetName(cs);
        ExRaiseSqlError(heap, diagsArea, EXE_INVALID_CHARACTER);
        *(*diagsArea) << DgString0(csname) << DgString1("CHAR FUNCTION"); 

        if (derivedFunction())
        {
          **diagsArea << DgSqlCode(-EXE_MAPPED_FUNCTION_ERROR);
          **diagsArea << DgString0(exClauseGetText(origFunctionOperType()));
        }
        return ex_expr::EXPR_ERROR;
      }
      else
      {
        if ( charLength < len0_bytes )
           str_pad(((char *)op_data[0]) + charLength, len0_bytes - charLength, ' ');
        getOperand(0)->setVarLength(charLength, op_data[-MAX_OPERANDS]);
      }
    }
  }
  else
    {
      // ITM_UNICODE_CHAR or ITM_NCHAR_MP_CHAR

      // check if the code value is legal for UNICODE only. No need 
      // for KANJI/KSC5601 as both take code-point values with any bit-patterns.
      if ( (getOperType() == ITM_UNICODE_CHAR) && (asciiCode < 0 || asciiCode >= 0xFFFE))
	{
	  ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
	  **diagsArea << DgString0("CHAR");

	  if (derivedFunction())
	    {
	      **diagsArea << DgSqlCode(-EXE_MAPPED_FUNCTION_ERROR);
	      **diagsArea << DgString0(exClauseGetText(origFunctionOperType()));
	    }

	  return ex_expr::EXPR_ERROR;
	}

      NAWchar wcharCode = (NAWchar)asciiCode;

#if defined( NA_LITTLE_ENDIAN )
      // swap the byte order on little-endian machines as NCHAR_MP charsets are stored
      // in multi-byte form (i.e. in big-endian order).
      if (getOperType() == ITM_NCHAR_MP_CHAR) 
      {
		*(NAWchar*)op_data[0] = reversebytesUS(wcharCode);
      } else
        *(NAWchar*)op_data[0] = wcharCode;
#else 
      *(NAWchar*)op_data[0] = wcharCode;
#endif
    }
  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ex_function_char_length::eval(char *op_data[],
						       CollHeap* heap,
						       ComDiagsArea** diagsArea)
{
  Int32 offset = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);
  Int32 numOfChar = 0;

  CharInfo::CharSet cs = ((SimpleType *)getOperand(1))->getCharSet();


  if(CharInfo::maxBytesPerChar(cs) == 1)
  {
    *(Int32 *)op_data[0] = offset;
    return ex_expr::EXPR_OK;
  }

  if ( cs == CharInfo::UTF8 )
  {
     Int32 prec1 = ((SimpleType *)getOperand(1))->getPrecision();
     offset = Attributes::trimFillerSpaces( op_data[1], prec1, offset, cs );
  }

  // convert to number of character
  numOfChar = Attributes::convertOffsetToChar (op_data[1], offset, cs);

  if(numOfChar < 0)
  {
    const char *csname = CharInfo::getCharSetName(cs);
    ExRaiseSqlError(heap, diagsArea, EXE_INVALID_CHARACTER);
    *(*diagsArea) << DgString0(csname) << DgString1("CHAR FUNCTION"); 
    return ex_expr::EXPR_ERROR;
  }

  // Move operand's length into result.
  // The data type of result is long.

  *(Int32 *)op_data[0] = numOfChar;
  
  return ex_expr::EXPR_OK;
};

ex_expr::exp_return_type ExFunctionConvertHex::eval(char *op_data[],
						    CollHeap* heap,
						    ComDiagsArea** diagsArea)
{
  static const char HexArray[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

  Lng32 len1 = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);
  if (getOperType() == ITM_CONVERTTOHEX)
    {
      Int32 i;
      if ( DFS2REC::isDoubleCharacter(getOperand(1)->getDatatype()) ) 
      {
        NAWchar *w_p = (NAWchar*)op_data[1];
        Int32 w_len = len1 / sizeof(NAWchar);
        for (i = 0; i < w_len; i++)
  	{
  	  op_data[0][4 * i    ]     = HexArray[0x0F & w_p[i] >> 12];
  	  op_data[0][4 * i + 1]     = HexArray[0x0F & w_p[i] >> 8];
  	  op_data[0][4 * i + 2]     = HexArray[0x0F & w_p[i] >> 4];
  	  op_data[0][4 * i + 3]     = HexArray[0x0F & w_p[i]];
  	}
      } else {
      CharInfo::CharSet cs = ((SimpleType *)getOperand(1))->getCharSet();
      if ( cs == CharInfo::UTF8 )
      {
         Int32 prec1 = ((SimpleType *)getOperand(1))->getPrecision();
         len1 = Attributes::trimFillerSpaces( op_data[1], prec1, len1, cs );
      }
      for (i = 0; i < len1; i++)
	{
	  op_data[0][2 * i]     = HexArray[0x0F & op_data[1][i] >> 4];
	  op_data[0][2 * i + 1] = HexArray[0x0F & op_data[1][i]];
        }
      }

      getOperand(0)->setVarLength(2 * len1, op_data[-MAX_OPERANDS]);
    }
  else
    {
      // convert from hex.

      // make sure that length is an even number.
      if ((len1 % 2) != 0)
	{
	  ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
	  **diagsArea << DgString0("CONVERTFROMHEX");
	  if (derivedFunction())
	    {
	      **diagsArea << DgSqlCode(-EXE_MAPPED_FUNCTION_ERROR);
	      **diagsArea << DgString0(exClauseGetText(origFunctionOperType()));
	    }
	  return ex_expr::EXPR_ERROR;
	}

      Int32 i = 0;
      Int32 j = 0;
      while (i < len1)
	{
	  if (((op_data[1][i] >= '0') && (op_data[1][i] <= '9')) ||
	      ((op_data[1][i] >= 'A') && (op_data[1][i] <= 'F')) &&
	      (((op_data[1][i+1] >= '0') && (op_data[1][i+1] <= '9')) ||
	       ((op_data[1][i+1] >= 'A') && (op_data[1][i+1] <= 'F'))))
	    {
	      unsigned char upper4Bits;
	      unsigned char lower4Bits;
	      if ((op_data[1][i] >= '0') && (op_data[1][i] <= '9'))
		upper4Bits = (unsigned char)(op_data[1][i]) - '0';
	      else
		upper4Bits = (unsigned char)(op_data[1][i]) - 'A' + 10;

	      if ((op_data[1][i+1] >= '0') && (op_data[1][i+1] <= '9'))
		lower4Bits = (unsigned char)(op_data[1][i+1]) - '0';
	      else
		lower4Bits = (unsigned char)(op_data[1][i+1]) - 'A' + 10;

	      
	      op_data[0][j] = (upper4Bits << 4) | lower4Bits;

	      i += 2;
	      j++;
	    }
	  else
	    {
	      ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
	      **diagsArea << DgString0("CONVERTFROMHEX");

	      if (derivedFunction())
		{
		  **diagsArea << DgSqlCode(-EXE_MAPPED_FUNCTION_ERROR);
		  **diagsArea << DgString0(exClauseGetText(origFunctionOperType()));
		}
	      
	      return ex_expr::EXPR_ERROR;
	    }
	} // while

      getOperand(0)->setVarLength(len1 / 2, op_data[-MAX_OPERANDS]);
    } // CONVERTFROMHEX

  return ex_expr::EXPR_OK;
}

Int32 ex_function_position::findPosition (char* pat,
                                          Int32 patLen,
                                          char* src,
                                          Int32 srcLen,
                                          NABoolean patternInFront)
{
  Int32 i, j, k;

  // Pattern must be able to "fit" in source string
  if (patLen > srcLen)
    return 0;

  // One time check at beginning of src string if flag indicate so.
  if (patternInFront)
    return ((str_cmp(pat, src, patLen) == 0) ? 1 : 0);

  // Search for pattern throughout the src string
  for (i=0; (i + patLen) <= srcLen; i++) {
    NABoolean found = TRUE ;
    for (j=i, k=0; found && (k < patLen); k++, j++) {
      if (src[j] != pat[k])
        found = 0;
    }

    if (found)
      return i+1;
  }

  return 0;
}

Lng32 ex_function_position::findPosition
			    (char * sourceStr, 
			    Lng32 sourceLen,
			    char * searchStr, 
			    Lng32 searchLen,
			    short bytesPerChar, 
                            Int16 nPasses,
                            CharInfo::Collation collation,
			    short charOffsetFlag ,  // 1: char, 0: offset
			    CharInfo::CharSet cs )

{
  // If searchLen is <= 0 or searchLen > sourceLen or 
  // if searchStr is not present in sourceStr,
  // return a position of 0; 
  // otherwise return the position of searchStr in
  // sourceStr.

  if (searchLen <= 0)
    return 0;
  Int32 position = 1;
  Int32 collPosition = 1;
  Int32 char_count = 1;
  Int32 number_bytes;
  while (position + searchLen -1 <= sourceLen)
  {
    if (str_cmp(searchStr, &sourceStr[position-1], (Int32)searchLen) != 0)
      if (CollationInfo::isSystemCollation(collation))
      {
        position += nPasses;
        collPosition ++;
      } 
      else
      {
	      number_bytes = Attributes::getFirstCharLength
	          (&sourceStr[position-1], sourceLen - position + 1, cs);

	      if(number_bytes <= 0)
	        return (Lng32)-1;

	      ++char_count;
	      position += number_bytes;
      }
    else
    {
      if (CollationInfo::isSystemCollation(collation))
      {
         return collPosition;
      }
      else
      {
	    if(charOffsetFlag)
	      return char_count;
	    else
	      return position;
      }
    }
  }
  return 0;
}


ex_expr::exp_return_type 
ex_function_char_length_doublebyte::eval(char *op_data[],
				       CollHeap*,
				       ComDiagsArea**)
{
  // Move operand's length into result.
  // The data type of result is long.

  *(Lng32 *)op_data[0] = 
	(getOperand(1)->getLength(op_data[-MAX_OPERANDS+1])) >> 1;


  return ex_expr::EXPR_OK;
};

ex_expr::exp_return_type ex_function_position::eval(char *op_data[],
						    CollHeap* heap,
						    ComDiagsArea** diagsArea)
{
  CharInfo::CharSet cs = ((SimpleType *)getOperand(1))->getCharSet();


  // search for operand 1
  Lng32 len1 = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);
  if ( cs == CharInfo::UTF8 )
  {
     Int32 prec1 = ((SimpleType *)getOperand(1))->getPrecision();
     len1 = Attributes::trimFillerSpaces( op_data[1], prec1, len1, cs );
  }
  
  // in operand 2
  Lng32 len2 = getOperand(2)->getLength(op_data[-MAX_OPERANDS+2]);
  if ( cs == CharInfo::UTF8 )
  {
     Int32 prec2 = ((SimpleType *)getOperand(2))->getPrecision();
     len2 = Attributes::trimFillerSpaces( op_data[2], prec2, len2, cs );
  }

  // If len1 is 0, return a position of 1.
  Lng32 position;
  if (len1 > 0)
    {

      short nPasses = CollationInfo::getCollationNPasses(getCollation());
      position = findPosition(op_data[2], 
			      len2, 
			      op_data[1], 
			      len1, 
			      1, 
			      nPasses, 
			      getCollation(),
			      1,
			      cs);

      if(position < 0)
      {
        const char *csname = CharInfo::getCharSetName(cs);
        ExRaiseSqlError(heap, diagsArea, EXE_INVALID_CHARACTER);
        *(*diagsArea) << DgString0(csname) << DgString1("POSITION FUNCTION"); 
        return ex_expr::EXPR_ERROR;
      }
 
    }
  else
    {
      // if len1 <= 0, return position of 1.
      position = 1;
    }

  // Now copy the position into result which is a long. 
  *(Int32 *)op_data[0] = position;
  
  return ex_expr::EXPR_OK;
};

ex_expr::exp_return_type ex_function_position_doublebyte::eval(char *op_data[],
						    CollHeap*,
						    ComDiagsArea**)
{
  Lng32 len1 = ( getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]) ) / sizeof(NAWchar);
  
  // If len1 is 0, return a position of 1.
  Lng32 position = 1;
  if (len1 > 0)
    {
      Lng32 len2 = ( getOperand(2)->getLength(op_data[-MAX_OPERANDS+2]) ) / sizeof(NAWchar);

      NAWchar* pat = (NAWchar*)op_data[1];
      NAWchar* source = (NAWchar*)op_data[2];
      
      // If len1 > len2 or if operand 1 is not present in operand 2, return 
      // a position of 0; otherwise return the position of operand 1 in 
      // operand 2.
      short found = 0;
      while (position+len1-1 <= len2 && !found)
        {
	  if (wc_str_cmp(pat, &source[position-1], (Int32)len1))
	    position++;
	  else
	    found = 1;
        }
      if (!found) position = 0;   
    } 
  
  // Now copy the position into result which is a long. 
  *(Lng32 *)op_data[0] = position;
  
  return ex_expr::EXPR_OK;
};
static Lng32 findTokenPosition(char * sourceStr, Lng32 sourceLen,
			      char * searchStr, Lng32 searchLen,
			      short bytesPerChar)
{
  // If searchLen is <= 0 or searchLen > sourceLen or 
  // if searchStr is not present in sourceStr,
  // return a position of 0; 
  // otherwise return the position of searchStr in
  // sourceStr.
  Lng32 position = 0;
  if (searchLen <= 0)
    position = 0;
  else
    {
      NABoolean found = FALSE;
      position = 1;
      while (position+searchLen-1 <= sourceLen && !found)
	{
	  if (str_cmp(searchStr, &sourceStr[position-1], (Int32)searchLen) != 0)
	    position += bytesPerChar;
	  else
	    found = 1;
	}
      if (!found) position = 0;   
    }

  return position;
}

ex_expr::exp_return_type ExFunctionTokenStr::eval(char *op_data[],
						  CollHeap* heap,
						  ComDiagsArea** diagsArea)
{
  CharInfo::CharSet cs = ((SimpleType *)getOperand(1))->getCharSet();
  // search for operand 1
  Lng32 len1 = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);
  if ( cs == CharInfo::UTF8 )
  {
     Int32 prec1 = ((SimpleType *)getOperand(1))->getPrecision();
     len1 = Attributes::trimFillerSpaces( op_data[1], prec1, len1, cs );
  }
  
  // in operand 2
  Lng32 len2 = getOperand(2)->getLength(op_data[-MAX_OPERANDS+2]);
  if ( cs == CharInfo::UTF8 )
  {
     Int32 prec2 = ((SimpleType *)getOperand(2))->getPrecision();
     len2 = Attributes::trimFillerSpaces( op_data[2], prec2, len2, cs );
  }

  Lng32 position;
  position = findTokenPosition(op_data[2], len2, op_data[1], len1, 1);
  if (position <= 0)
    {
      ExRaiseFunctionSqlError(heap, diagsArea, EXE_INTERNAL_ERROR,
			      derivedFunction(),
			      origFunctionOperType());
      
      return ex_expr::EXPR_ERROR;
    }

  Lng32 startPos = position + len1 - 1;
  Lng32 i;
  if (op_data[2][startPos] == '\'')
    {
      // find the ending single quote. 
      startPos++;
      i = startPos;
      while ((i < len2) &&
	     (op_data[2][i] != '\''))
	i++;
    }
  else
    {
      // find the ending space character
//      startPos++;
      i = startPos;
      while ((i < len2) &&
	     (op_data[2][i] != ' '))
	i++;
    }

/*  if (op_data[2][startPos] != '\'')
    {
      ExRaiseFunctionSqlError(heap, diagsArea, EXE_INTERNAL_ERROR,
			      derivedFunction(),
			      origFunctionOperType());
      
      return ex_expr::EXPR_ERROR;
    }

  if (i == len2)
    {
      ExRaiseFunctionSqlError(heap, diagsArea, EXE_INTERNAL_ERROR,
			      derivedFunction(),
			      origFunctionOperType());
      
      return ex_expr::EXPR_ERROR;
    }
*/

  str_cpy_all(op_data[0], &op_data[2][startPos], (i - startPos));
  
  if ((i - startPos) <= 0)
    {
      ExRaiseFunctionSqlError(heap, diagsArea, EXE_INTERNAL_ERROR,
			      derivedFunction(),
			      origFunctionOperType());
      
      return ex_expr::EXPR_ERROR;
    }

  // If result is a varchar, store the length of substring 
  // in the varlen indicator.
  if (getOperand(0)->getVCIndicatorLength() > 0)
    getOperand(0)->setVarLength(i - startPos, op_data[-MAX_OPERANDS]);
  else
    {
      ExRaiseFunctionSqlError(heap, diagsArea, EXE_INTERNAL_ERROR,
			      derivedFunction(),
			      origFunctionOperType());
      
      return ex_expr::EXPR_ERROR;
    }

  return ex_expr::EXPR_OK;
};

ex_expr::exp_return_type ExFunctionReverseStr::eval(char *op_data[],
                                                    CollHeap* heap,
                                                    ComDiagsArea** diagsArea)
{
  CharInfo::CharSet cs = ((SimpleType *)getOperand(1))->getCharSet();
  Lng32 len1 = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);

  char * tgt = op_data[0];
  char * src = op_data[1];
  Lng32 srcPos = 0;
  Lng32 tgtPos = 0;
  if (cs == CharInfo::ISO88591)
    {
      tgtPos = len1 - 1;
      for (srcPos = 0; srcPos < len1; srcPos++)
        {
          tgt[tgtPos--] = src[srcPos];
        }
    }
  else if (cs == CharInfo::UCS2)
    {
      Lng32 bpc = unicode_char_set::bytesPerChar();
      srcPos = 0;
      tgtPos = len1 - bpc;
      while (srcPos < len1)
        {
          str_cpy_all(&tgt[tgtPos], &src[srcPos], bpc);
          tgtPos -= bpc;
          srcPos += bpc;
        }
    }
  else if (cs == CharInfo::UTF8)
    {
      UInt32 UCS4value;
      
      cnv_charset charset = convertCharsetEnum(cs);
      Lng32 charLen;
      srcPos = 0;
      tgtPos = len1;
      while(srcPos < len1)
        {
          charLen = LocaleCharToUCS4(&op_data[1][srcPos],
                                     len1 - srcPos,
                                     &UCS4value,
                                     charset);
          if (charLen < 0)
            {
              const char *csname = CharInfo::getCharSetName(cs);
              ExRaiseSqlError(heap, diagsArea, EXE_INVALID_CHARACTER);
              *(*diagsArea) << DgString0(csname) << DgString1("REVERSE FUNCTION"); 
              return ex_expr::EXPR_ERROR;
            }

          tgtPos -= charLen;
          str_cpy_all(&tgt[tgtPos], &src[srcPos], charLen);
          srcPos += charLen;
        }
    }
  else
    {
      const char *csname = CharInfo::getCharSetName(cs);
      ExRaiseSqlError(heap, diagsArea, EXE_INVALID_CHARACTER);
      *(*diagsArea) << DgString0(csname) << DgString1("REVERSE FUNCTION"); 
      return ex_expr::EXPR_ERROR;
    }

  if (getOperand(0)->getVCIndicatorLength() > 0)
    getOperand(0)->setVarLength(len1, op_data[-MAX_OPERANDS]);

  return ex_expr::EXPR_OK;
};

ex_expr::exp_return_type ex_function_sleep::eval(char *op_data[],
						   CollHeap* heap,
						   ComDiagsArea** diagsArea)
{
  Int32 sec = 0;
  switch (getOperand(1)->getDatatype())
  {
    case REC_BIN8_SIGNED:
      sec = *(Int8 *)op_data[1] ;
      if(sec < 0 )
      {
        ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
        *(*diagsArea) << DgString0("SLEEP");
        return ex_expr::EXPR_ERROR;
      }
      sleep(sec);
      *(Int64 *)op_data[0] = 1;
      break;
      
    case REC_BIN16_SIGNED:
      sec = *(short *)op_data[1] ; 
      if(sec < 0 )
      {
        ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
        *(*diagsArea) << DgString0("SLEEP");
        return ex_expr::EXPR_ERROR;
      }
      sleep(sec);
      *(Int64 *)op_data[0] = 1;
      break;
      
    case REC_BIN32_SIGNED:
      sec = *(Lng32 *)op_data[1];
      if(sec < 0 )
      {
        ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
        *(*diagsArea) << DgString0("SLEEP");
        return ex_expr::EXPR_ERROR;
      }
      sleep(sec);
      *(Int64 *)op_data[0] = 1;
      break;
 
    case REC_BIN64_SIGNED:
      sec = *(Int64 *)op_data[1];
      if(sec < 0 )
      {
        ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
        *(*diagsArea) << DgString0("SLEEP");
        return ex_expr::EXPR_ERROR;
      }
      sleep(sec);
      *(Int64 *)op_data[0] = 1;
      break;
      
    default:
        ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
        *(*diagsArea) << DgString0("SLEEP");
      return ex_expr::EXPR_ERROR;
      break;
  }
  //get the seconds to sleep
  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ex_function_unixtime::eval(char *op_data[],
						   CollHeap* heap,
						   ComDiagsArea** diagsArea)
{
  char *opData = op_data[1];
  //if there is input value
  if( getNumOperands() == 2)
  {
    struct tm* ptr;
    char* r = strptime(opData, "%Y-%m-%d %H:%M:%S", ptr);
    if( (r == NULL) ||  (*r != '\0') )
    {
        ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
        *(*diagsArea) << DgString0("UNIX_TIMESTAMP");
      return ex_expr::EXPR_ERROR;
    }
    else
      *(Int64 *)op_data[0] = mktime(ptr);

  }
  else
  {
    time_t seconds;  
    seconds = time((time_t *)NULL);   
    *(Int64 *)op_data[0] = seconds; 
  }
  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ex_function_current::eval(char *op_data[],
						   CollHeap*,
						   ComDiagsArea**)
{
  if (getOperand())
    {
      ExpDatetime *datetimeOpType = (ExpDatetime *) getOperand(0);
      
      rec_datetime_field srcStartField;
      rec_datetime_field srcEndField;
      
      if (datetimeOpType->getDatetimeFields(datetimeOpType->getPrecision(),
                                            srcStartField,
                                            srcEndField) != 0) 
        {
          return ex_expr::EXPR_ERROR;
        }

      ExpDatetime::currentTimeStamp(op_data[0],
                                    srcStartField,
                                    srcEndField,
                                    datetimeOpType->getScale());
    }
  else
    {
      ExpDatetime::currentTimeStamp(op_data[0],
                                    REC_DATE_YEAR,
                                    REC_DATE_SECOND,
                                    ExpDatetime::MAX_DATETIME_FRACT_PREC);
    }

  return ex_expr::EXPR_OK;
};

// MV,
ex_expr::exp_return_type ExFunctionGenericUpdateOutput::eval(char *op_data[],
						   CollHeap* heap,
						   ComDiagsArea** diagsArea)
{
  // We do not set the value here.
  // The return value is written into the space allocated for it by the 
  // executor work method.
  // The value is initialized to zero here in case VSBB is rejected by the
  // optimizer, so the executor will not override this value.
  if (origFunctionOperType() == ITM_VSBBROWCOUNT)
    *(Lng32 *)op_data[0] = 1;  // Simple Insert RowCount - 1 row.
  else
    *(Lng32 *)op_data[0] = 0;  // Simple Insert RowType is 0.

  return ex_expr::EXPR_OK;
}

// Triggers -
ex_expr::exp_return_type ExFunctionInternalTimestamp::eval(char *op_data[],
						   CollHeap* heap,
						   ComDiagsArea** diagsArea)
{
  ex_function_current currentFun;
  return (currentFun.eval(op_data, heap, diagsArea));
}

ex_expr::exp_return_type ex_function_bool::eval(char *op_data[],
						CollHeap *heap,
						ComDiagsArea** diagsArea)
{
  ex_expr::exp_return_type retcode = ex_expr::EXPR_OK;
  
  switch (getOperType())
    {
    case ITM_RETURN_TRUE:
      {
	*(Lng32 *)op_data[0] = 1;
      }
      break;
      
    case ITM_RETURN_FALSE:
      {
	*(Lng32 *)op_data[0] = 0;
      }
      break;
      
    case ITM_RETURN_NULL:
      {
	*(Lng32 *)op_data[0] = -1;
      }
      break;

    default:
      {
	ExRaiseFunctionSqlError(heap, diagsArea, EXE_INTERNAL_ERROR,
				derivedFunction(),
				origFunctionOperType());
	
	retcode = ex_expr::EXPR_ERROR;
      }
      break;
    }
  
  return retcode;
}

ex_expr::exp_return_type ex_function_converttimestamp::eval(char *op_data[],
							    CollHeap *heap,
							    ComDiagsArea** diagsArea)
{
  Int64 juliantimestamp;
  str_cpy_all((char *) &juliantimestamp, op_data[1], sizeof(juliantimestamp));
  const Int64 minJuliantimestamp = (Int64) 1487311632 * (Int64) 100000000;
  const Int64 maxJuliantimestamp = (Int64) 2749273487LL * (Int64) 100000000 +
                                                        (Int64)  99999999;
  if ((juliantimestamp < minJuliantimestamp) ||
      (juliantimestamp > maxJuliantimestamp)) {
    char tmpbuf[24];
    memset(tmpbuf, 0, sizeof(tmpbuf) );
    sprintf(tmpbuf, "%ld", juliantimestamp);

    ExRaiseSqlError(heap, diagsArea, EXE_CONVERTTIMESTAMP_ERROR);
    if(*diagsArea)
      **diagsArea << DgString0(tmpbuf);

    if(derivedFunction())
    {
      **diagsArea << DgSqlCode(-EXE_MAPPED_FUNCTION_ERROR);
       **diagsArea << DgString0(exClauseGetText(origFunctionOperType()));
    }
    
    return ex_expr::EXPR_ERROR;
  }

  short timestamp[8];
  INTERPRETTIMESTAMP(juliantimestamp, timestamp);
  short year = timestamp[0];
  char month = (char) timestamp[1];
  char day = (char) timestamp[2];
  char hour = (char) timestamp[3];
  char minute = (char) timestamp[4];
  char second = (char) timestamp[5];
  Lng32 fraction = timestamp[6] * 1000 + timestamp[7];
  char *datetimeOpData = op_data[0];
  str_cpy_all(datetimeOpData, (char *) &year, sizeof(year));
  datetimeOpData += sizeof(year);
  *datetimeOpData++ = month;
  *datetimeOpData++ = day;
  *datetimeOpData++ = hour;
  *datetimeOpData++ = minute;
  *datetimeOpData++ = second;
  str_cpy_all(datetimeOpData, (char *) &fraction, sizeof(fraction));
  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ex_function_dateformat::eval(char *op_data[],
						      CollHeap *heap,
						      ComDiagsArea** diagsArea)
{
  char *opData = op_data[1];
  char *formatStr = op_data[2];
  char *result = op_data[0];
  
  if ((getDateFormat() == ExpDatetime::DATETIME_FORMAT_NUM1) ||
      (getDateFormat() == ExpDatetime::DATETIME_FORMAT_NUM2))
    {
      // numeric to TIME conversion.
      if(ExpDatetime::convNumericTimeToASCII(opData, 
					     result,
					     getOperand(0)->getLength(),
					     getDateFormat(),
					     formatStr,
					     heap,
					     diagsArea) < 0) {
	
	ExRaiseFunctionSqlError(heap, diagsArea, EXE_INTERNAL_ERROR,
				derivedFunction(),
				origFunctionOperType());
	
	return ex_expr::EXPR_ERROR;
      }
      
    }
  else
    {
      // Convert the given datetime value to an ASCII string value in the
      // given format.  
      //
      if ((DFS2REC::isAnyCharacter(getOperand(1)->getDatatype())) &&
	  (DFS2REC::isDateTime(getOperand(0)->getDatatype())))
	{
          Lng32 sourceLen = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);

	  ExpDatetime *datetimeOpType = (ExpDatetime *) getOperand(0);
	  if(datetimeOpType->convAsciiToDate(opData, 
                                             sourceLen,
                                             result,
                                             getOperand(0)->getLength(),
                                             getDateFormat(),
                                             heap,
                                             diagsArea,
                                             0) < 0) {
            
            if (diagsArea && 
                (!(*diagsArea) ||
                  ((*diagsArea) && 
                  (*diagsArea)->getNumber(DgSqlCode::ERROR_) == 0)))
              {
                // we expect convAsciiToDate to raise a diagnostic; if it
                // didn't, raise an internal error here
                ExRaiseFunctionSqlError(heap, diagsArea, EXE_INTERNAL_ERROR,
                                        derivedFunction(),
                                        origFunctionOperType());
              }
	    return ex_expr::EXPR_ERROR;
	  }
	}
      else
	{
	  ExpDatetime *datetimeOpType = (ExpDatetime *) getOperand(1);
	  if(datetimeOpType->convDatetimeToASCII(opData, 
                                                 result,
						 getOperand(0)->getLength(),
						 getDateFormat(),
						 formatStr,
						 heap,
						 diagsArea) < 0) {
	
	    ExRaiseFunctionSqlError(heap, diagsArea, EXE_INTERNAL_ERROR,
				    derivedFunction(),
				    origFunctionOperType());
	    
	    return ex_expr::EXPR_ERROR;
	  }
	}
  }

  return ex_expr::EXPR_OK;

}

ex_expr::exp_return_type ex_function_dayofweek::eval(char *op_data[],
						     CollHeap*,
						     ComDiagsArea**)
{
  Int64 interval;
  short year;
  char month;
  char day;
  ExpDatetime *datetimeOpType = (ExpDatetime *) getOperand(1);
  char *datetimeOpData = op_data[1];
  str_cpy_all((char *) &year, datetimeOpData, sizeof(year));
  datetimeOpData += sizeof(year);
  month = *datetimeOpData++;
  day = *datetimeOpData;
  interval = datetimeOpType->getTotalDays(year, month, day);
  unsigned short result = (unsigned short)((interval + 1) % 7) + 1;
  str_cpy_all(op_data[0], (char *) &result, sizeof(result));
  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ex_function_extract::eval(char *op_data[],
						   CollHeap *heap,
						   ComDiagsArea** diagsArea)
{
  Int64 result = 0;
  if (getOperand(1)->getDatatype() == REC_DATETIME) {
    ExpDatetime *datetimeOpType = (ExpDatetime *) getOperand(1);
    char *datetimeOpData = op_data[1];
    rec_datetime_field opStartField;
    rec_datetime_field opEndField;
    rec_datetime_field extractStartField = getExtractField();
    rec_datetime_field extractEndField = extractStartField;

    if (extractStartField > REC_DATE_MAX_SINGLE_FIELD) {
      extractStartField = REC_DATE_YEAR;
      if (extractEndField == REC_DATE_YEARQUARTER_EXTRACT ||
          extractEndField == REC_DATE_YEARMONTH_EXTRACT ||
          extractEndField == REC_DATE_YEARQUARTER_D_EXTRACT ||
          extractEndField == REC_DATE_YEARMONTH_D_EXTRACT)
        extractEndField = REC_DATE_MONTH;
      else {
        ExRaiseFunctionSqlError(heap, diagsArea, EXE_INTERNAL_ERROR,
                                derivedFunction(),
                                origFunctionOperType());
        return ex_expr::EXPR_ERROR;
      }
    }
    if (datetimeOpType->getDatetimeFields(datetimeOpType->getPrecision(),
                                          opStartField,
                                          opEndField) != 0) {
      ExRaiseFunctionSqlError(heap, diagsArea, EXE_INTERNAL_ERROR,
			      derivedFunction(),
			      origFunctionOperType());

      return ex_expr::EXPR_ERROR;
    }
    for (Int32 field = opStartField; field <= extractEndField; field++) {
      switch (field) {
      case REC_DATE_YEAR: {
        short value;
        if (field >= extractStartField && field <= extractEndField) {
          str_cpy_all((char *) &value, datetimeOpData, sizeof(value));
          result = value;
        }
        datetimeOpData += sizeof(value);
        break;
      }
      case REC_DATE_MONTH:
      case REC_DATE_DAY:
      case REC_DATE_HOUR:
      case REC_DATE_MINUTE:
        if (field >= extractStartField && field <= extractEndField) {
          switch (getExtractField())
            {
            case REC_DATE_YEARQUARTER_EXTRACT:
              // 10*year + quarter - human readable quarter format
              result = 10*result + ((*datetimeOpData)+2) / 3;
              break;
            case REC_DATE_YEARQUARTER_D_EXTRACT:
              // 4*year + 0-based quarter - dense quarter format, better for MDAM
              result = 4*result + (*datetimeOpData-1) / 3;
              break;
            case REC_DATE_YEARMONTH_EXTRACT:
              // 100*year + month - human readable yearmonth format
              result = 100*result + *datetimeOpData;
               break;
           case REC_DATE_YEARMONTH_D_EXTRACT:
              // 12*year + 0-based month - dense month format, better for MDAM
              result = 12*result + *datetimeOpData-1;
              break;
            default:
              // regular extract of month, day, hour, minute
              result = *datetimeOpData;
              break;
            }
        }
        datetimeOpData++;
        break;
      case REC_DATE_SECOND:
        if (field == getExtractField()) {
          result = *datetimeOpData;
          datetimeOpData++;
          short fractionPrecision = datetimeOpType->getScale();
          if (fractionPrecision > 0) {
            do {
              result *= 10;
            } while (--fractionPrecision > 0);
            Lng32 fraction;
            str_cpy_all((char *) &fraction, datetimeOpData, sizeof(fraction));
            result += fraction;
          }
        }
        break;
      default:
	ExRaiseFunctionSqlError(heap, diagsArea, EXE_INTERNAL_ERROR,
				derivedFunction(),
				origFunctionOperType());

        return ex_expr::EXPR_ERROR;
      }
    }
  } else {
    Int64 interval;
    switch (getOperand(1)->getLength()) {
    case SQL_SMALL_SIZE: {
      short value;
      str_cpy_all((char *) &value, op_data[1], sizeof(value));
      interval = value;
      break;
    }
    case SQL_INT_SIZE: {
      Lng32 value;
      str_cpy_all((char *) &value, op_data[1], sizeof(value));
      interval = value;
      break;
    }
    case SQL_LARGE_SIZE:
      str_cpy_all((char *) &interval, op_data[1], sizeof(interval));
      break;
    default:
      ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR);
      return ex_expr::EXPR_ERROR;
    }
    rec_datetime_field startField;
    if (ExpInterval::getIntervalStartField(getOperand(1)->getDatatype(), startField) != 0)
      return ex_expr::EXPR_ERROR;
    if (getExtractField() == startField)
      result = interval;
    else {
      switch (getExtractField()) {
      case REC_DATE_MONTH:
        //
        // The sign of the result of a modulus operation involving a negative
        // operand is implementation-dependent according to the C++ reference
        // manual.  In this case, we prefer the result to be negative.
        //
        result = interval % 12;
        if ((interval < 0) && (result > 0))
          result = - result;
        break;
      case REC_DATE_HOUR:
        //
        // The sign of the result of a modulus operation involving a negative
        // operand is implementation-dependent according to the C++ reference
        // manual.  In this case, we prefer the result to be negative.
        //
        result = interval % 24;
        if ((interval < 0) && (result > 0))
          result = - result;
        break;
      case REC_DATE_MINUTE:
        //
        // The sign of the result of a modulus operation involving a negative
        // operand is implementation-dependent according to the C++ reference
        // manual.  In this case, we prefer the result to be negative.
        //
        result = interval % 60;
        if ((interval < 0) && (result > 0))
          result = - result;
        break;
      case REC_DATE_SECOND: {
        Lng32 divisor = 60;
        for (short fp = getOperand(1)->getScale(); fp > 0; fp--)
          divisor *= 10;
        result = interval;
        interval = result / (Int64) divisor;
        result -= interval * (Int64) divisor;
        break;
      }
      default:
        ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR);
        return ex_expr::EXPR_ERROR;
      }
    }
  }

  copyInteger (op_data[0], getOperand(0)->getLength(), &result, sizeof(result));

  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ex_function_juliantimestamp::eval(char *op_data[],
							   CollHeap *heap,
							   ComDiagsArea** diagsArea)
{
  ex_expr::exp_return_type retcode = ex_expr::EXPR_OK;
  Int64 juliantimestamp;

  char *datetimeOpData = op_data[1];
  short year;
  char month;
  char day;
  char hour;
  char minute;
  char second;
  Lng32 fraction;
  str_cpy_all((char *) &year, datetimeOpData, sizeof(year));
  datetimeOpData += sizeof(year);
  month = *datetimeOpData++;
  day = *datetimeOpData++;
  hour = *datetimeOpData++;
  minute = *datetimeOpData++;
  second = *datetimeOpData++;
  str_cpy_all((char *) &fraction, datetimeOpData, sizeof(fraction));
  short timestamp[] = {
    year, month, day, hour, minute, second, (short)(fraction / 1000), (short)(fraction % 1000)
  };
  short error;
  juliantimestamp = COMPUTETIMESTAMP(timestamp, &error);
  if (error) {
    char tmpbuf[24];
    memset(tmpbuf, 0, sizeof(tmpbuf) );
    sprintf(tmpbuf, "%ld", juliantimestamp);

    ExRaiseSqlError(heap, diagsArea, EXE_JULIANTIMESTAMP_ERROR);
    if(*diagsArea)
      **diagsArea << DgString0(tmpbuf);

    if(derivedFunction())
    {
      **diagsArea << DgSqlCode(-EXE_MAPPED_FUNCTION_ERROR);
       **diagsArea << DgString0(exClauseGetText(origFunctionOperType()));
    }
    
    return ex_expr::EXPR_ERROR;
  }

  str_cpy_all(op_data[0], (char *) &juliantimestamp, sizeof(juliantimestamp));
  return retcode;
}

ex_expr::exp_return_type ex_function_exec_count::eval(char *op_data[],
						      CollHeap *heap,
						      ComDiagsArea** diagsArea)
{
  execCount_++;
  str_cpy_all(op_data[0], (char *) &execCount_, sizeof(execCount_));
  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ex_function_curr_transid::eval(char *op_data[],
							CollHeap *heap,
							ComDiagsArea** diagsArea)
{
  // this function is not used yet anywhere, whoever wants to start using
  // it should fill in the missing code here
  ExRaiseFunctionSqlError(heap, diagsArea, EXE_USER_FUNCTION_ERROR,
			  derivedFunction(),
			  origFunctionOperType());
  
  return ex_expr::EXPR_ERROR;
}

// -----------------------------------------------------------------------
// Helper function for CURRENT_USER and SESSION_USER function.
// Used by exp and UDR code to get the CURRENT_USER and SESSION_USER
// information. SESSION_USER is the user that is logged on to the 
// current SQL session. CURRENT_USER is the one with whose privileges
// a SQL statement is executed, With Definer Rights SPJ, the CURRENT_USER is
// the owner of the SPJ while SESSION_USER is the user who invoked the SPJ.
//
// Returns the current login user name as a C-style string (null terminated)
// in inputUserNameBuffer parameter. 
// (e.g. returns "Domain1\Administrator" on NT if logged 
//                    in as Domain1\Administrator, 
//               "role-mgr" on NSK if logged in as alias "role-mgr",
//               "ROLE.MGR" on NSK if logged in as Guardian userid ROLE.MGR)
// Returns FEOK as the return value on success, otherwise returns an error status. 
// Returns FEBUFTOOSMALL if the input buffer supplied is not big enough to 
// accommodate the actual user name.
// Optionally returns the actual length of the user name (in bytes) in 
// actualLength parameter. Returns 0 as the actual length if the function returns
// an error code, except for FEBUFTOOSMALL return code in which case it
// returns the actual length so that the caller can get an idea of the minimum 
// size of the input buffer to be provided.
// -----------------------------------------------------------------------
short exp_function_get_user(
     OperatorTypeEnum userType, // IN - CURRENT_USER or SESSION_USER
     char *inputUserNameBuffer, // IN - buffer for returning the user name
     Lng32 inputBufferLength,    // IN - length(max) of the above buffer in bytes
     Lng32 *actualLength)        // OUT optional - actual length of the user name
{
  if (actualLength)
    *actualLength = 0;

  short result = FEOK;
  Int32 lActualLen = 0;

  Int32 userID;

  if (userType == ITM_SESSION_USER)
    userID = ComUser::getSessionUser();
  else
    // Default to CURRENT_USER
    userID = ComUser::getCurrentUser();

  assert (userID != NA_UserIdDefault);

  char userName[MAX_USERNAME_LEN+1];
  Int16 status = ComUser::getUserNameFromUserID( (Int32) userID
                                               , (char *)&userName 
                                               , (Int32) inputBufferLength 
                                               ,  lActualLen ); 
  if (status == FEOK)
  {
    str_cpy_all(inputUserNameBuffer, userName, lActualLen);
    inputUserNameBuffer[lActualLen] = '\0';
  }
  else 
    result = FEBUFTOOSMALL;

  if (((result == FEOK) || (result == FEBUFTOOSMALL)) && actualLength)
    *actualLength = lActualLen;

  return result;
}

ex_expr::exp_return_type ex_function_ansi_user::eval(char *op_data[],
						     CollHeap *heap,
						     ComDiagsArea** diagsArea)
{
  const Lng32 MAX_USER_NAME_LEN = ComSqlId::MAX_LDAP_USER_NAME_LEN;

  char username[MAX_USER_NAME_LEN + 1];
  Lng32 username_len = 0;
  short retcode = FEOK;

  retcode = exp_function_get_user ( getOperType(),
                                    username,
                                    MAX_USER_NAME_LEN + 1,
                                    &username_len
                                  );

  if (((retcode != FEOK) && (retcode != FENOTFOUND)) ||
      ((retcode == FEOK) && (username_len == 0)) ) {
    ExRaiseFunctionSqlError(heap, diagsArea, EXE_USER_FUNCTION_ERROR,
			    derivedFunction(),
			    origFunctionOperType());
    
    return ex_expr::EXPR_ERROR;
  }

  str_cpy_all(op_data[0], username, username_len);
    
  getOperand(0)->setVarLength(username_len, op_data[-MAX_OPERANDS]);

  return ex_expr::EXPR_OK;

}

ex_expr::exp_return_type ex_function_user::eval(char *op_data[],
						CollHeap *heap,
						ComDiagsArea** diagsArea)
{
  Int32 userIDLen = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);

  Int64 id64;

  switch (userIDLen)
    {
    case SQL_SMALL_SIZE:
      id64 = *((short *) op_data[1]);
      break;
    case SQL_INT_SIZE:
      id64 = *((Lng32 *) op_data[1]);
      break;
    case SQL_LARGE_SIZE:
      id64 = *((Int64 *) op_data[1]);
      break;
    default:
      ExRaiseFunctionSqlError(heap, diagsArea, EXE_USER_FUNCTION_ERROR,
                              derivedFunction(),
                              origFunctionOperType());
      
      return ex_expr::EXPR_ERROR;
    }

  if (id64 < -SQL_INT32_MAX || id64 > SQL_INT32_MAX)
    {

      ExRaiseFunctionSqlError(heap, diagsArea, EXE_USER_FUNCTION_ERROR,
                              derivedFunction(),
                              origFunctionOperType());

      return ex_expr::EXPR_ERROR;
    }

  Int32 authID = (Int32)(id64);
// *****************************************************************************
// *                                                                           *
// * Code to handle functions AUTHNAME and AUTHTYPE.  Piggybacked on USER      *
// * function code in parser, binder, and optimizer.  Perhaps there is a       *
// * better way to implement.                                                  *
// *                                                                           *
// * AUTHNAME invokes the porting layer, which calls CLI, as it may be         *
// * necessary to read metadata (and therefore have a transaction within       *
// * a transaction).                                                           *
// *                                                                           *
// * AUTHTYPE calls Catman directly, as Catman knows the values and ranges     *
// * for various types of authentication ID values.  Examples include          *
// * PUBLIC, SYSTEM, users, and roles.  AUTHTYPE returns a single character    *
// * that can be used within a case, if, or where clause.                      *
// *                                                                           *
// *****************************************************************************
  
  switch (getOperType())
  {
     case ITM_AUTHNAME:
     {
        Int16 result;
        Int32 authNameLen = 0;
        char  authName[MAX_AUTHNAME_LEN + 1];
        
        result = ComUser::getAuthNameFromAuthID(authID,
                                                authName,
                                                sizeof(authName), 
                                                authNameLen);
     
        if (result != FEOK)
        {
            ExRaiseFunctionSqlError(heap, diagsArea, EXE_USER_FUNCTION_ERROR,
                                    derivedFunction(),
                                    origFunctionOperType());

            return ex_expr::EXPR_ERROR;
        }

        if (authNameLen > getOperand(0)->getLength()) 
        {
            ExRaiseFunctionSqlError(heap, diagsArea, EXE_USER_FUNCTION_ERROR,
                                    derivedFunction(),
                                    origFunctionOperType());
           
            return ex_expr::EXPR_ERROR;
        }

        getOperand(0)->setVarLength(authNameLen, op_data[-MAX_OPERANDS]);
        str_cpy_all(op_data[0], authName, authNameLen);

        return ex_expr::EXPR_OK;
     }
     case ITM_AUTHTYPE:
     {
        char authType[2];
        
        authType[1] = 0;
        authType[0] = ComUser::getAuthType(authID);
        getOperand(0)->setVarLength(1, op_data[-MAX_OPERANDS]);
        str_cpy_all(op_data[0], authType, 1);

        return ex_expr::EXPR_OK;
     }
     case ITM_USER:
     case ITM_USERID:
     default:
     {
     // Drop down to user code
     }
  }

  Int32 userNameLen = 0;
  char  userName[MAX_USERNAME_LEN+1];

  Int16 result = ComUser::getUserNameFromUserID(authID, 
                                       (char *)&userName,
                                       MAX_USERNAME_LEN+1,
                                       userNameLen);
         
  if ((result != FEOK) && (result != FENOTFOUND))
    {

      ExRaiseFunctionSqlError(heap, diagsArea, EXE_USER_FUNCTION_ERROR,
                              derivedFunction(),
                              origFunctionOperType());

      return ex_expr::EXPR_ERROR;
    }
  else if (result == FENOTFOUND || userNameLen == 0)
    {
      // set the user name same as user id
      // avoids exceptions if userID not present in USERS table

      if (authID < 0)
        {
          userName[0] = '-';
          str_itoa((ULng32)(-authID), &userName[1]);
        }
      else
        {
          str_itoa((ULng32)(authID), userName);
        }
      userNameLen = str_len(userName);
    }

  if (userNameLen > getOperand(0)->getLength()) 
    {
      ExRaiseFunctionSqlError(heap, diagsArea, EXE_USER_FUNCTION_ERROR,
                              derivedFunction(),
                              origFunctionOperType());
      
      return ex_expr::EXPR_ERROR;
    }

  getOperand(0)->setVarLength(userNameLen, op_data[-MAX_OPERANDS]);
  str_cpy_all(op_data[0], userName, userNameLen);

  return ex_expr::EXPR_OK;
};

////////////////////////////////////////////////////////////////////
//
// encodeKeyValue
//
// This routine encodes key values so that they can be sorted simply
// using binary collation.  The routine is called by the executor.
//
// Note: The target MAY point to the source to change the original
//       value.
//
////////////////////////////////////////////////////////////////////
void ex_function_encode::encodeKeyValue(Attributes * attr,
					const char *source,
					const char *varlenPtr,
					char *target,
					NABoolean isCaseInsensitive,
                                        Attributes * tgtAttr,
                                        char *tgt_varlen_ptr,
        				const Int32 tgtLength ,
					CharInfo::Collation collation,
					CollationInfo::CollationType collType)
{
  Lng32 fsDatatype = attr->getDatatype();
  Lng32 length = attr->getLength();
  Lng32 precision = attr->getPrecision();
  
  switch (fsDatatype) {
#if defined( NA_LITTLE_ENDIAN )
  case REC_BIN8_SIGNED:
    //
    // Flip the sign bit.
    //
    *(UInt8*)target = *(UInt8*)source;
    target[0] ^= 0200;
    break;

  case REC_BIN8_UNSIGNED:
  case REC_BOOLEAN:
    *(UInt8*)target = *(UInt8*)source;
    break;

  case REC_BIN16_SIGNED:
    //
    // Flip the sign bit.
    //
    *((unsigned short *) target) = reversebytes( *((unsigned short *) source) );
    target[0] ^= 0200;
    break;

  case REC_BPINT_UNSIGNED:
  case REC_BIN16_UNSIGNED:
    *((unsigned short *) target) = reversebytes( *((unsigned short *) source) );
    break;

  case REC_BIN32_SIGNED:
    //
    // Flip the sign bit.
    //
    *((ULng32 *) target) = reversebytes( *((ULng32 *) source) );
    target[0] ^= 0200;
    break;

  case REC_BIN32_UNSIGNED:
    *((ULng32 *) target) = reversebytes( *((ULng32 *) source) );
    break;

  case REC_BIN64_SIGNED:
    //
    // Flip the sign bit.
    //
    *((_int64 *) target) = reversebytes( *((_int64 *) source) );
    target[0] ^= 0200;
    break;

  case REC_BIN64_UNSIGNED:
    *((UInt64 *) target) = reversebytes( *((UInt64 *) source) );
    break;

  case REC_INT_YEAR:
  case REC_INT_MONTH:
  case REC_INT_YEAR_MONTH:
  case REC_INT_DAY:
  case REC_INT_HOUR:
  case REC_INT_DAY_HOUR:
  case REC_INT_MINUTE:
  case REC_INT_HOUR_MINUTE:
  case REC_INT_DAY_MINUTE:
  case REC_INT_SECOND:
  case REC_INT_MINUTE_SECOND:
  case REC_INT_HOUR_SECOND:
  case REC_INT_DAY_SECOND:
    switch(length)
    {
      case 2:	 // Signed 16 bit
        *((unsigned short *) target) = reversebytes( *((unsigned short *) source) );
        break;
      case 4:  // Signed 32 bit
        *((ULng32 *) target) = reversebytes( *((ULng32 *) source) );
        break;
      case 8:  // Signed 64 bit
        *((_int64 *) target) = reversebytes( *((_int64 *) source) );
        break;
      default:
        assert(FALSE);
        break;
    };  // switch(length)
    target[0] ^= 0200;
    break;
  case REC_DATETIME: {
    // This method has been modified as part of the MP Datetime
    // Compatibility project.  It has been made more generic so that
    // it depends only on the start and end fields of the datetime type.
    //
    rec_datetime_field startField;
    rec_datetime_field endField;

    ExpDatetime *dtAttr = (ExpDatetime *)attr;

    // Get the start and end fields for this Datetime type.
    //
    dtAttr->getDatetimeFields(dtAttr->getPrecision(),
                              startField,
                              endField);

    // Copy all of the source to the destination, then reverse only
    // those fields of the target that are longer than 1 byte
    //
    if (target != source)
      str_cpy_all(target, source, length);
    
    // Reverse the YEAR and Fractional precision fields if present.
    //
    char *ptr = target;
    for(Int32 field = startField; field <= endField; field++) {
      switch (field) {
      case REC_DATE_YEAR:
        // convert YYYY from little endian to big endian
        //
        *((unsigned short *) ptr) = reversebytes( *((unsigned short *) ptr) );
        ptr += sizeof(short);
        break;
      case REC_DATE_MONTH:
      case REC_DATE_DAY:
      case REC_DATE_HOUR:
      case REC_DATE_MINUTE:
        // One byte fields are copied as is...
        ptr++;
        break;
      case REC_DATE_SECOND:
        ptr++;

        // if there is a fraction, make it big endian 
        // (it is an unsigned long, beginning after the SECOND field)
        //
        if (dtAttr->getScale() > 0)
          *((ULng32 *) ptr) = reversebytes( *((ULng32 *) ptr) );
        break;

      }
    }
    break;
  }
#else
  case REC_BIN8_SIGNED:
  case REC_BIN16_SIGNED:
  case REC_BIN32_SIGNED:
  case REC_BIN64_SIGNED:
  case REC_INT_YEAR:
  case REC_INT_MONTH:
  case REC_INT_YEAR_MONTH:
  case REC_INT_DAY:
  case REC_INT_HOUR:
  case REC_INT_DAY_HOUR:
  case REC_INT_MINUTE:
  case REC_INT_HOUR_MINUTE:
  case REC_INT_DAY_MINUTE:
  case REC_INT_SECOND:
  case REC_INT_MINUTE_SECOND:
  case REC_INT_HOUR_SECOND:
  case REC_INT_DAY_SECOND:
    //
    // Flip the sign bit.
    //
    if (target != source)
      str_cpy_all(target, source, length);
    target[0] ^= 0200;
    break;
#endif

  case REC_DECIMAL_LSE:
    //
    // If the number is negative, complement all the bytes.  Otherwise, set
    // the sign bit.
    //
    if (source[0] & 0200) {
      for (Lng32 i = 0; i < length; i++)
        target[i] = ~source[i];
    } else {
      if (target != source)
        str_cpy_all(target, source, length);
      target[0] |= 0200;
    }
    break;
  case REC_NUM_BIG_UNSIGNED: {
    BigNum type(length, precision, 0, 1);
    type.encode(source, target);
    break;
  }
  case REC_NUM_BIG_SIGNED: {
    BigNum type(length, precision, 0, 0);
    type.encode(source, target);
    break;
  }
  case REC_IEEE_FLOAT32: {
    //
    // unencoded float (IEEE 754 - 1985 standard):
    //
    // +-+----------+---------------------+
    // | | exponent |  mantissa           |
    // | | (8 bits) |  (23 bits)          |
    // +-+----------+---------------------+
    //  |
    //  +- Sign bit
    //
    // Encoded float (IEEE 754 - 1985 standard):
    //
    // +-+--------+-----------------------+
    // | |Exponent| Mantissa              |
    // | |(8 bits)| (23 bits)             |
    // +-+--------+-----------------------+
    //  ||                                |
    //  |+- Complemented if sign was neg.-+
    //  |
    //  +- Sign bit complement
    //

    // the following code is independent of the "endianess" of the
    // architecture. Instead, it assumes IEEE 754 - 1985 standard
    // for representation of floats

    // source may not be aligned, move it to a temp var.
    float floatsource;
    str_cpy_all((char*)&floatsource, source, length);
    ULng32 *dblword = (ULng32 *) &floatsource;
    if (floatsource < 0)               // the sign is negative,
      *dblword = ~*dblword;            // flip all the bits
    else
      floatsource = -floatsource;      // complement the sign bit

    // here comes the dependent part
#ifdef NA_LITTLE_ENDIAN
    *(ULng32 *) target = reversebytes(*dblword);
#else
    //    *(unsigned long *) target = *dblword;
    str_cpy_all(target, (char*)&floatsource, length);
#endif
    break;
  }
  case REC_IEEE_FLOAT64: {
    //
    // unencoded double (IEEE 754 - 1985 standard):
    //
    // +-+--------- -+--------------------+
    // | | exponent  |  mantissa          |
    // | | (11 bits) |  (52 bits)         |
    // +-+--------- -+--------------------+
    //  |
    //  +- Sign bit
    //
    // Encoded double (IEEE 754 - 1985 standard):
    //
    // +-+-----------+--------------------+
    // | | Exponent  | Mantissa           |
    // | | (11 bits) | (52 bits)          |
    // +-+-----------+--------------------+
    //  ||                                |
    //  |+- Complemented if sign was neg.-+
    //  |
    //  +- Sign bit complement
    //

    // the following code is independent of the "endianess" of the
    // archtiecture. Instead, it assumes IEEE 754 - 1985 standard
    // for representation of floats
    
    //double doublesource = *(double *) source;

    // source may not be aligned, move it to a temp var.
    double doublesource;
    str_cpy_all((char*)&doublesource, source, length);

    Int64 *quadword = (Int64 *) &doublesource;
    if (doublesource < 0)               // the sign is negative,
      *quadword = ~*quadword;           // flip all the bits
    else
      doublesource = -doublesource;     // complement the sign bit

    // here comes the dependent part
#ifdef NA_LITTLE_ENDIAN
    *(Int64 *) target = reversebytes(*quadword);
#else
    //    *(Int64 *) target = *quadword;
    str_cpy_all(target, (char*)&doublesource, length);
#endif
    break;
  }

  case REC_BYTE_F_ASCII: {
      if (CollationInfo::isSystemCollation(collation )) 
      {
	Int16 nPasses = CollationInfo::getCollationNPasses(collation);

	if (collType == CollationInfo::Sort ||
	    collType == CollationInfo::Compare)
	{
	  encodeCollationKey(
			  (const UInt8 *)source,
                          length,
			  (UInt8 *)target,
			  tgtLength,
			  nPasses,
			  collation,
			  TRUE);
	}
	else //search
	{
          Int32 effEncodedKeyLength = 0;
	  encodeCollationSearchKey(
			  (const UInt8 *)source,
                          length,
			  (UInt8 *)target,
			  tgtLength,
                          effEncodedKeyLength,
			  nPasses,
			  collation,
			  TRUE);
          assert(tgtAttr && tgt_varlen_ptr);
	  tgtAttr->setVarLength(effEncodedKeyLength, tgt_varlen_ptr);
	}
      }
      else
      {
        //------------------------------------------
        if (target != source)
          str_cpy_all(target, source, length);

        if (isCaseInsensitive)
          {
	    // upcase target
	    for (Int32 i = 0; i < length; i++)
	      {
	        target[i] =  TOUPPER(source[i]);
	      }         
          }
        //--------------------------
     }

  }
  break;


  case REC_BYTE_V_ASCII: 
  case REC_BYTE_V_ASCII_LONG: 
  {
      Int32 vc_len = attr->getLength(varlenPtr);
     
      if (CollationInfo::isSystemCollation(collation))
      {
	Int16 nPasses = CollationInfo::getCollationNPasses(collation);
	NABoolean rmTspaces = getRmTSpaces(collation);
	
	if (collType == CollationInfo::Sort ||
	    collType == CollationInfo::Compare)
	{
	  encodeCollationKey(
			(UInt8 *)source,
			(Int16)vc_len,
			(UInt8 *)target,
			tgtLength,
			nPasses,
			collation,
			rmTspaces);
	}
	else
	{
          Int32 effEncodedKeyLength = 0;
	  encodeCollationSearchKey(
			(UInt8 *)source,
			(Int16)vc_len,
			(UInt8 *)target,
			tgtLength,
                        effEncodedKeyLength,
			nPasses,
			collation,
			rmTspaces);
	  
	  assert(tgtAttr && tgt_varlen_ptr);
	  tgtAttr->setVarLength(effEncodedKeyLength, tgt_varlen_ptr);
	}
      }
      else
      {

        //
        // Copy the source to the target.
        //
        if (!isCaseInsensitive)
          str_cpy_all(target, source, vc_len);
        else
          {
	    // upcase target
	    for (Int32 i = 0; i < vc_len; i++)
	      {
	        target[i] =  TOUPPER(source[i]);
	      }         
          }

        //
        // Blankpad the target (if needed).
        //
        if (vc_len < length)
          str_pad(&target[vc_len],
	          (Int32) (length - vc_len), ' ');
      }

  }
  break;

  // added for Unicode data type.
  case REC_NCHAR_V_UNICODE: 
  {
    Int32 vc_len = attr->getLength(varlenPtr);

    //
    // Copy the source to the target.
    //
    str_cpy_all(target, source, vc_len);

    //
    // Blankpad the target (if needed).
    //
    if (vc_len < length)
      wc_str_pad((NAWchar*)&target[vc_len],
                 (Int32) (length - vc_len)/sizeof(NAWchar), unicode_char_set::space_char());

#if defined( NA_LITTLE_ENDIAN )
    wc_swap_bytes((NAWchar*)target, length/sizeof(NAWchar));
#endif
    break;
  }

  // added for Unicode data type.
  case REC_NCHAR_F_UNICODE: 
  {

    if (target != source)
      str_cpy_all(target, source, length);

#if defined( NA_LITTLE_ENDIAN )
      wc_swap_bytes((NAWchar*)target, length/sizeof(NAWchar));
#endif

    break;
  }

  case REC_BYTE_V_ANSI: 
  {
      short vc_len;
      vc_len = strlen(source);

      //
      // Copy the source to the target.
      //
      str_cpy_all(target, source, vc_len);
      
      //
      // Blankpad the target (if needed).
      //
      if (vc_len < length)
	str_pad(&target[vc_len], (Int32) (length - vc_len), ' ');
  }
  break;

  default:
    //
    // Encoding is not needed.  Just copy the source to the target.
    //
    if (target != source)
      str_cpy_all(target, source, length);
    break;
  }
}

////////////////////////////////////////////////////////////////////
// class ex_function_encode
////////////////////////////////////////////////////////////////////
ex_function_encode::ex_function_encode(){};
ex_function_encode::ex_function_encode(OperatorTypeEnum oper_type,
				       Attributes ** attr,
				       Space * space,
				       short descFlag)
: ex_function_clause(oper_type, 2, attr, space),
  flags_(0),
  collation_((Int16) CharInfo::DefaultCollation)
{
  if (descFlag)
    setIsDesc(TRUE);
  else
    setIsDesc(FALSE);
  
  setCollEncodingType(CollationInfo::Sort);
};
ex_function_encode::ex_function_encode(OperatorTypeEnum oper_type,
				       Attributes ** attr,
				       Space * space,
				       CharInfo::Collation collation,
				       short descFlag,
				       CollationInfo::CollationType collType)
: ex_function_clause(oper_type, 2, attr, space),
  flags_(0),
  collation_((Int16)collation)
{
  if (descFlag)
    setIsDesc(TRUE);
  else
    setIsDesc(FALSE);

  setCollEncodingType(collType);

};

ex_expr::exp_return_type ex_function_encode::processNulls(
						      char * op_data[],
						      CollHeap *heap,
						      ComDiagsArea **diagsArea)
{
  if ((CollationInfo::isSystemCollation((CharInfo::Collation) collation_)) &&
	  getCollEncodingType() != CollationInfo::Sort)
    {
      return ex_clause::processNulls(op_data,heap,diagsArea);
    }
  else if (regularNullability())
    {
      return ex_clause::processNulls(op_data,heap,diagsArea);
    }
    
  // if value is missing, 
  // then move max or min value to result.
  if (getOperand(1)->getNullFlag() &&
      (!op_data[1]))                  // missing value (is a null value)
    {
      if (NOT isDesc())
	{
	  // NULLs sort high for ascending comparison.
	  // Pad result with highest value.

          // For SQL/MP tables, DP2 expects missing value columns to be
          // 0 padded after the null-indicator.
          str_pad(op_data[2 * MAX_OPERANDS],
                  (Int32)getOperand(0)->getStorageLength(), '\0');
          str_pad(op_data[2 * MAX_OPERANDS],
                  ExpTupleDesc::KEY_NULL_INDICATOR_LENGTH,
                  '\377');
	}
      else
	{
	  // NULLs sort low for descending comparison.
	  // Pad result with lowest value.
          str_pad(op_data[2 * MAX_OPERANDS],
                  (Int32)getOperand(0)->getStorageLength(),
                  '\377');
          str_pad(op_data[2 * MAX_OPERANDS],
                  ExpTupleDesc::KEY_NULL_INDICATOR_LENGTH,
                  '\0');
	}
      return ex_expr::EXPR_NULL;
    }
  
 
  return ex_expr::EXPR_OK;
};


ex_expr::exp_return_type ex_function_encode::evalDecode(char *op_data[],
							CollHeap* heap)
{
  char * result = op_data[0];
  Attributes *srcOp = getOperand(1);
  
  decodeKeyValue(srcOp,
		 isDesc(),
		 op_data[1],
		 op_data[-MAX_OPERANDS+1],
		 result,
                 op_data[-MAX_OPERANDS],
		 FALSE);
  
  return ex_expr::EXPR_OK;
} 

ex_expr::exp_return_type ex_function_encode::eval(char *op_data[],
						  CollHeap* heap,
						  ComDiagsArea**)
{
  if (isDecode())
    {
      return evalDecode(op_data, heap);
    }

  Int16 prependedLength = 0;
  char * result = op_data[0];
  Attributes *tgtOp = getOperand(0);
  Attributes *srcOp = getOperand(1);
  
  if ((srcOp->getNullFlag())  && // nullable
      (NOT regularNullability()))
    {
      // If target is aligned format then can't use the 2 byte null here ...
      assert( !tgtOp->isSQLMXAlignedFormat() );

      // if sort is set for char types with collations (including default)
      if (getCollEncodingType() == CollationInfo::Sort)
	{
	  // value cannot be null in this proc. That is handled in process_nulls.
	  str_pad(result, ExpTupleDesc::KEY_NULL_INDICATOR_LENGTH, '\0');
	  result += ExpTupleDesc::KEY_NULL_INDICATOR_LENGTH;
	  prependedLength = ExpTupleDesc::KEY_NULL_INDICATOR_LENGTH;
	}
    }

  if (srcOp->isComplexType())
    ((ComplexType *)srcOp)->encode(op_data[1], result, isDesc());
  else   
  {
    Int32 tgtLength =  tgtOp->getLength() - prependedLength ;
    encodeKeyValue(srcOp,
                   op_data[1],
                   op_data[-MAX_OPERANDS+1],
                   result,
                   caseInsensitive(),
                   tgtOp,
                   op_data[-MAX_OPERANDS],
                   tgtLength,
		   (CharInfo::Collation) collation_,
		   getCollEncodingType());
  }
  
  if (isDesc())  
  {
    // compliment all bytes
    for (Lng32 k = 0; k < tgtOp->getLength(); k++)
      op_data[0][k] = (char)(~(op_data[0][k]));
  }
  
  return ex_expr::EXPR_OK;
} 



void ex_function_encode::getCollationWeight( 
					CharInfo::Collation collation,
					Int16 pass,
                                        UInt16 chr,
                                        UInt8 * weightStr,
                                        Int16 & weightStrLen)
{
  UChar wght =  getCollationWeight(collation, pass, chr);
  switch (collation)
  {
    case CharInfo::CZECH_COLLATION:
    case CharInfo::CZECH_COLLATION_CI:
    {
      if ((CollationInfo::Pass)pass != CollationInfo::SecondPass)
      {
        if (wght > 0 )
        {
          weightStr[0] = wght;
          weightStrLen = 1;
        }
        else
        {
          weightStrLen = 0;
        }
      }
      else
      {
        if (getCollationWeight(collation, CollationInfo::FirstPass, chr) > 0 )
        {
          weightStr[0] = wght;
          weightStrLen = 1;
        }
        else
        {
          weightStr[0] = 0;
          weightStr[1] = wght;
          weightStrLen = 2;
        }      
      }    
    }
    break;
    default:
    {
      if (wght > 0 )
      {
        weightStr[0] = wght;
        weightStrLen = 1;
      }
      else
      {
        weightStrLen = 0;
      }
    }
  }
}
unsigned char ex_function_encode::getCollationWeight( 
                                                     CharInfo::Collation collation,
                                                     Int16 pass,
						     UInt16 chr) 
{
  return collParams[CollationInfo::getCollationParamsIndex(collation)].weightTable[pass][chr];
}

Int16 ex_function_encode::getNumberOfDigraphs( const CharInfo::Collation collation)
{ 
  return collParams[CollationInfo::getCollationParamsIndex(collation)].numberOfDigraphs ;
}

UInt8 * ex_function_encode::getDigraph(const CharInfo::Collation collation, const Int32 digraphNum)	
{ 
  return (UInt8 *) collParams[CollationInfo::getCollationParamsIndex(collation)].digraphs[digraphNum] ;
}

Int16 ex_function_encode::getDigraphIndex(const CharInfo::Collation collation, const Int32 digraphNum)	
{ 
  return collParams[CollationInfo::getCollationParamsIndex(collation)].digraphIdx[digraphNum];
}

NABoolean ex_function_encode::getRmTSpaces(const CharInfo::Collation collation)
{ 
  return collParams[CollationInfo::getCollationParamsIndex(collation)].rmTSpaces; 
}

NABoolean ex_function_encode::getNumberOfChars(const CharInfo::Collation collation)
{ 
  return collParams[CollationInfo::getCollationParamsIndex(collation)].numberOfChars; 
}

NABoolean ex_function_encode::isOneToOneCollation(const CharInfo::Collation collation)
{
  for (UInt16 i =0 ; i < getNumberOfChars(collation); i++)
  {
      for (UInt16 j =i +1 ; j < getNumberOfChars(collation); j++)
      {
        NABoolean isOneToOne = FALSE;
        for (Int16 pass=0 ; pass  < CollationInfo::getCollationNPasses(collation); pass++)
        {
          if (getCollationWeight(collation,pass,i)  != getCollationWeight(collation,pass,j)  )
          {
            isOneToOne = TRUE;
          }
        }
        if (!isOneToOne)
        {
          return FALSE;
        }

      }
  }
  return TRUE;
}


void ex_function_encode::encodeCollationKey(const UInt8 * src,
                                            Int32 srcLength,
					    UInt8 * encodeKey,
					    const Int32 encodedKeyLength,
					    Int16 nPasses,
					    CharInfo::Collation  collation,
					    NABoolean rmTSpaces )
{ 

  assert (CollationInfo::isSystemCollation(collation));

  UInt8 * ptr;

  if (src[0] == CollationInfo::getCollationMaxChar(collation))
  {
    str_pad((char*) encodeKey, srcLength, CollationInfo::getCollationMaxChar(collation));
    if (str_cmp((char*)src, (char*)encodeKey, srcLength) == 0)
    {
      str_pad((char*) encodeKey, encodedKeyLength,'\377' );
      return;
    }
  }
  
  if (src[0] == '\0')
  {
    str_pad((char*) encodeKey, encodedKeyLength, '\0');

    if (str_cmp((char*)src, (char*)encodeKey,srcLength) == 0)
    {
      return;
    }
  }

  Int16 charNum=0;
  NABoolean hasDigraphs = FALSE;
  Int32 trailingSpaceLength =0;
  UInt8 digraph[2];
  digraph[0]=digraph[1]=0;

  Int16 weightStrLength=0;
  ptr= encodeKey;

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

  for ( Int32 i = srcLength -1 ; rmTSpaces && i> 0 && src[i]== 0x20; i--)
  {
    trailingSpaceLength++;
  }

  for (short i= CollationInfo::FirstPass; i< nPasses; i++)
  {
    if (i != CollationInfo::FirstPass)
    {
       *ptr++= 0x0;
    }

    if ((i == CollationInfo::FirstPass)  || 
	    (i != CollationInfo::FirstPass && hasDigraphs))
    {
      //loop through the chars in the string, find digraphs an assighn weights
      for (Int32 srcIdx = 0; srcIdx <  srcLength- trailingSpaceLength; srcIdx++)                  
      { 
        digraph[0] = digraph[1];
        digraph[1] = src[srcIdx];
        NABoolean digraphFound = FALSE;
	for (Int32 j = 0 ; j < getNumberOfDigraphs(collation); j++)
        {
          if (digraph[0] == getDigraph(collation, j)[0] &&
              digraph[1] ==  getDigraph(collation, j)[1])           
          {
            digraphFound = hasDigraphs = TRUE;
            charNum = getDigraphIndex(collation,j);
            ptr--;
	    break;
          }
        }
        if (!digraphFound)
        {
          charNum = src[srcIdx];
        }
        getCollationWeight(collation,i, charNum,ptr,weightStrLength);
        ptr = ptr + weightStrLength;
      }
    }
    else
    {
      for (Int32 srcIdx = 0; srcIdx <  srcLength- trailingSpaceLength; srcIdx++)                  
      { 
        charNum = src[srcIdx];
        getCollationWeight(collation, i, charNum,ptr,weightStrLength);
        ptr = ptr + weightStrLength;
      }
    }
  }


  str_pad( (char *) ptr,(encodeKey - ptr) + encodedKeyLength, '\0');

} // ex_function_encode::encodeCollationKey



void ex_function_encode::encodeCollationSearchKey(const UInt8 * src,
                                            Int32 srcLength,
					    UInt8 * encodeKey,
					    const Int32 encodedKeyLength,
					    Int32 & effEncodedKeyLength,
					    Int16 nPasses,
					    CharInfo::Collation  collation,
					    NABoolean rmTSpaces )
{ 

  assert (CollationInfo::isSystemCollation(collation));

  UInt8 * ptr;

  Int16 charNum=0;
  NABoolean hasDigraphs = FALSE;
  Int32 trailingSpaceLength =0;
  UInt8 digraph[2];
  digraph[0]=digraph[1]=0;

  ptr= encodeKey;

  /////////////////////////////////////////////
  for ( Int32 i = srcLength -1 ; rmTSpaces && i> 0 && src[i]== 0x20; i--)
  {
    trailingSpaceLength++;
  }

  for (Int32 srcIdx = 0; srcIdx <  srcLength- trailingSpaceLength; srcIdx++)                  
  { 
    digraph[0] = digraph[1];
    digraph[1] = src[srcIdx];
    NABoolean digraphFound = FALSE;
	for (Int32 j = 0 ; j < getNumberOfDigraphs(collation); j++)
    {
      if (digraph[0] == getDigraph(collation, j)[0] &&
              digraph[1] ==  getDigraph(collation, j)[1]) 
      {
        digraphFound = hasDigraphs = TRUE;
        charNum = getDigraphIndex(collation,j);
        ptr = ptr - nPasses;
	break;
      }
    }
    if (!digraphFound)
    {
      charNum = src[srcIdx];
    }
    
    //don't include ignorable characters
    short ignorable = 0;
    for (short np = 0; np < nPasses ; np++)
    {
      ptr[np]= getCollationWeight(collation, np, charNum);

      if (ptr[np] == '\0')
      {
	ignorable++;
      }
    }
    if (ignorable != nPasses) //
    {
      ptr = ptr + nPasses;
    }
     
    if (digraphFound && 
	ignorable != nPasses)
    {
      for (short np = CollationInfo::FirstPass; np < nPasses ; np++)
      {
	ptr[np]= '\0';
      }
      ptr = ptr + nPasses;
    }


  }

  effEncodedKeyLength = ptr - encodeKey ;

  str_pad( (char *) ptr,(encodeKey - ptr) + encodedKeyLength, '\0');

} // ex_function_encode::encodeCollationSearchKey

////////////////////////////////////////////////////////////////////////
// class ex_function_explode_varchar
////////////////////////////////////////////////////////////////////////
ex_expr::exp_return_type ex_function_explode_varchar::processNulls(
     char * op_data[],
     CollHeap *heap,
     ComDiagsArea **diagsArea)
{
  Attributes *tgt = getOperand(0);

  if (getOperand(1)->getNullFlag() && (!op_data[1])) // missing value (is a null value)
  {
    if (tgt->getNullFlag())    // if result is nullable
      {
        // move null value to result
        ExpTupleDesc::setNullValue( op_data[0],
                                    tgt->getNullBitIndex(),
                                    tgt->getTupleFormat() );
    
        if (forInsert_)
        {
          // move 0 to length bytes
          tgt->setVarLength(0, op_data[MAX_OPERANDS]);
        } // for Insert
        else
        {
          // move maxLength to result length bytes
          tgt->setVarLength(tgt->getLength(), op_data[MAX_OPERANDS]);
        }
        return ex_expr::EXPR_NULL;  // indicate that a null input was processed
      }
    else
      {
        // Attempt to put NULL into column with NOT NULL NONDROPPABLE constraint.
	ExRaiseFunctionSqlError(heap, diagsArea, EXE_ASSIGNING_NULL_TO_NOT_NULL,
				derivedFunction(),
				origFunctionOperType());

        return ex_expr::EXPR_ERROR;
      }
    } // source is a null value

  // first operand is not null -- set null indicator in result if needed
  if (tgt->getNullFlag())
    {
      ExpTupleDesc::clearNullValue( op_data[0],
                                    tgt->getNullBitIndex(),
                                    tgt->getTupleFormat() );
    }

  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ex_function_explode_varchar::eval(char *op_data[],
							   CollHeap*heap,
							   ComDiagsArea**diagsArea)
{
  if (forInsert_)
    {
      // move source to target. No blankpadding.
      return convDoIt(op_data[1],
		      getOperand(1)->getLength(op_data[-MAX_OPERANDS + 1]),
		      getOperand(1)->getDatatype(),
		      getOperand(1)->getPrecision(),
		      getOperand(1)->getScale(),
		      op_data[0],
		      getOperand(0)->getLength(),
		      getOperand(0)->getDatatype(),
		      getOperand(0)->getPrecision(),
		      getOperand(0)->getScale(),
		      op_data[-MAX_OPERANDS],
		      getOperand(0)->getVCIndicatorLength(),
		      heap,
		      diagsArea);
    }
  else
    {
      // move source to target. Blankpad target to maxLength.
      if (convDoIt(op_data[1],
		   getOperand(1)->getLength(op_data[-MAX_OPERANDS + 1]),
		   getOperand(0)->getDatatype(),
		   getOperand(1)->getPrecision(),
		   getOperand(1)->getScale(),
		   op_data[0],
		   getOperand(0)->getLength(),
		   REC_BYTE_F_ASCII,
		   getOperand(0)->getPrecision(),
		   getOperand(0)->getScale(),
		   NULL,
		   0,
		   heap,
		   diagsArea))
	return ex_expr::EXPR_ERROR;
      
      // Move max length to length bytes of target.
      getOperand(0)->setVarLength(getOperand(0)->getLength(),
				   op_data[-MAX_OPERANDS]);
    }

  return ex_expr::EXPR_OK;
}

////////////////////////////////////////////////////////////////////
// class ex_function_hash
////////////////////////////////////////////////////////////////////
ULng32 ex_function_hash::HashHash(ULng32 inValue) {

  // Hashhash - 
  // input :   inValue  -  double word to be hashed
  // output :  30-bit hash values uniformly distributed (mod s) for
  //           any s < 2**30

  // This algorithm creates near-uniform output for arbitrarily distributed
  // input by selecting for each fw of the key a quasi-random universal	
  // hash function from the class of linear functions ax + b (mod p)
  // over the field of integers modulo the prime 2**31-1. The output is at
  // least comparable in quality to cubics of the form
  // ax**3 + bx**2 + cx  + d (mod p), and is considerably closer to true
  // uniformity than a single linear function chosen once per execution.
  // The latter preserve the uniform 2nd central moment of bucket totals,
  // and the former the 4th central moment. For probabilistic counting
  // applications, the theoretical standard error cannot be achieved with
  // less than cubic polynomials, but the present algorithm is approx 3-5x
  // in speed. (Cf. histogram doc. for bibliography, but especially:
  //    Carter and Wegman, "Universal Clases of Hash Functions",
  //       Journ. Comp. Sys. Sci., 18: April 1979, pp. 145-154 
  //       22: 1981, pp. 265-279 
  //    Dietzfelbinger, et al., "Polynomial Hash Functions...", 
  //       ICALP '92, pp. 235-246. )

  // N.B. - For modular arithmetic the 64-bit product of two 32-bit
  // operands must be reduced (mod p). The high-order 32 bits are available
  // in hardware but not necessarily through C syntax.

  // Two additional optimizations should be noted:
  // 1. Instead of processing 3-byte operands, as would be required with
  //    universal hashing over the field 2**31-1, with alignment delays, we
  //    process fullwords, and choose distinct 'random' coefficients for
  //    2 keys congruent (mod p) using a 32-bit function, and then proceed
  //    with modular linear hashing over the smaller field.
  // 2. For p = 2**c -1 for any c, shifts, and's and or's can be substituted
  //    for division, as recommended by Carter and Wegman. In addition, the
  //    output distribution is unaffected (i.e. with probability
  //    < 1/(2**31-1) if we omit tests for 0 (mod p).
  //    To reduce a (mod p), create k1 and k2 (<= p) with a = (2**31)k1 + k2,
  //    and reduce again to (2**31)k3 + k4, where k4 < 2**31 and k3 = 0 or 1.
  	 
  // Multi-word keys:
  // If k = k1||...||kn we compute the quasi-random coefficients c & d using
  // ki, but take h(ki) = c*(ki xor h(ki-1)) + d, where  h(k0) = 0, and  use
  // H(k) = h(kn). This precludes the commutative anomaly
  // H(k || k') = H(k' || k)       

  register ULng32 u, v, c, d, k0;
  ULng32 a1, a2, b1, b2;
  
  ULng32 c1 = (ULng32)5233452345LL;   
  ULng32 c2 = (ULng32)8578458478LL;  
  ULng32 d1 = 1862598173LL;
  ULng32 d2 = 3542657857LL;
 
  ULng32 hashValue = 0;

  ULng32 k = inValue;		

  u = (c1 >> 16) * (k >> 16);
  v = c1 * k; 
  c = u ^ v ^ c2;
  u = (d1 >> 16) * (k >> 16);
  v = d1 * k;
  d = u ^ v ^ d2;

  c = ((c & 0x80000000) >> 31) + (c & 0x7fffffff);	
  d = ((d & 0x80000000) >> 31) + (d & 0x7fffffff);

  /* compute hash value 1  */
	
  k0 = hashValue ^ k; 
	
  /*hmul(c,k0);
    u=u0; v=v0;*/

  a1 = c >> 16;
  a2 = c & 0xffff;
  b1 = k0 >> 16;
  b2 = k0 & 0xffff;
  
  v = (((a1 * b2) & 0xffff) + ((b1 * a2) & 0xffff)); 
  u = a1 * b1 + (((a1 * b2) >> 16) + ((b1 * a2) >> 16))
    + ((v & 0x10000) >> 16); 
  
  v  = c * k0;
  if (v < (a2 * b2))
    u++;

  u = u << 1;
  u = ((v & 0x80000000) >> 31) | u;
  v = v & 0x7fffffff;
  v = u + v;
  v = ((v & 0x80000000) >> 31) + (v & 0x7fffffff);
  /*v = ((v & 0x80000000) >> 31) + (v & 0x7fffffff);
    if ( v == 0x7fffffff) v = 0;*/
    
  v = v + d;
  v = ((v & 0x80000000) >> 31) + (v & 0x7fffffff);
  /*v = ((v & 0x80000000) >> 31) + (v & 0x7fffffff);
    if ( v == 0x7fffffff) v = 0;*/ 
  
  return (v);
};

ex_expr::exp_return_type ex_function_hash::eval(char *op_data[],
						CollHeap*,
						ComDiagsArea**)
{
  Attributes *srcOp = getOperand(1);
  ULng32 hashValue = 0;
  
  if (srcOp->getNullFlag() && (! op_data[ -(2 * MAX_OPERANDS) + 1 ]))
  {
    // operand is a null value. All null values hash to 
    // the same hash value. Choose any arbitrary constant
    // number as the hash value.
    hashValue = ExHDPHash::nullHashValue;  //;666654765;
  }
  else
  {
    // get the actual length stored in the data, or fixed length
    Lng32 length = srcOp->getLength(op_data[-MAX_OPERANDS + 1]);
    
    // if VARCHAR, skip trailing blanks and adjust length.
    if (srcOp->getVCIndicatorLength() > 0) {
      switch ( srcOp->getDatatype() ) {
	
	// added to correctly handle VARNCHAR.
      case REC_NCHAR_V_UNICODE:
	{
          // skip trailing blanks
          NAWchar* wstr = (NAWchar*)(op_data[1]);
          Lng32 wstr_length = length / sizeof(NAWchar);
	  
          while ((wstr_length > 0) &&
	         ( wstr[wstr_length-1] == unicode_char_set::space_char())
		 )
	    wstr_length--;
	  
          length = sizeof(NAWchar)*wstr_length;
	}
      break;
      
      default:
        //case  REC_BYTE_V_ASCII:
	
	// skip trailing blanks
	while ((length > 0) &&
	       (op_data[1][length-1] == ' '))
	  length--;
	break;
      }
    }
    
    UInt32 flags = ExHDPHash::NO_FLAGS;

    switch(srcOp->getDatatype()) {
    case REC_NCHAR_V_UNICODE:
    case REC_NCHAR_V_ANSI_UNICODE:
      flags = ExHDPHash::SWAP_TWO;
      break; 
    }

    hashValue = ExHDPHash::hash(op_data[1], flags, length); 
  };
  
  *(ULng32 *)op_data[0] = hashValue;
   
  return ex_expr::EXPR_OK;
};

Lng32 ex_function_hivehash::hashForCharType(char* data, Lng32 length)
{
  // To compute: SUM (i from 0 to n-1) (s(i) * 31^(n-1-i)

  ULng32 resultCopy = 0;
  ULng32 result = (ULng32)data[0];
  for (Lng32 i=1; i<length; i++ ) {

     // perform result * 31, optimized as (result <<5 - result)
     resultCopy = result;
     result <<= 5;
     result -= resultCopy;

     result += (ULng32)(data[i]);
  }

  return result;
}

ex_expr::exp_return_type ex_function_hivehash::eval(char *op_data[],
					   	CollHeap*,
						ComDiagsArea**)
{
  Attributes *srcOp = getOperand(1);
  ULng32 hashValue = 0;
  Lng32 length;
  
  if (srcOp->getNullFlag() && (! op_data[ -(2 * MAX_OPERANDS) + 1 ]))
  {
    // operand is a null value. All null values hash to the same hash value. 
    hashValue = 0; // hive semantics: hash(NULL) = 0
  } else
  if ( (DFS2REC::isSQLVarChar(srcOp->getDatatype()) || 
        DFS2REC::isANSIVarChar(srcOp->getDatatype())) && 
       getOperand(1)->getVCIndicatorLength() > 0 ) 
  {
      length = srcOp->getLength(op_data[-MAX_OPERANDS + 1]);
      hashValue = ex_function_hivehash::hashForCharType(op_data[1],length);
  } else
  if ( DFS2REC::isSQLFixedChar(srcOp->getDatatype()) ) {
      length = srcOp->getLength();
      hashValue = ex_function_hivehash::hashForCharType(op_data[1],length);
  } else
  if ( DFS2REC::isBinary(srcOp->getDatatype()) ) {
      hashValue = *(ULng32*)(op_data[1]);
  } // TBD: other SQ types

  *(ULng32 *)op_data[0] = hashValue;
  return ex_expr::EXPR_OK;
}

////////////////////////////////////////////////////////////////////
// class ExHashComb
////////////////////////////////////////////////////////////////////
ex_expr::exp_return_type ExHashComb::eval(char *op_data[], 
                                          CollHeap* heap,
                                          ComDiagsArea** diagsArea)
{
  // always assume that both operands and result are of the same
  // (unsigned) type and length

  // with built-in long long type we could also support 8 byte integers
  ULng32 op1, op2;

  switch (getOperand(0)->getStorageLength())
    {
    case 4:
      op1 = *((ULng32 *) op_data[1]);
      op2 = *((ULng32 *) op_data[2]);
      *((ULng32 *) op_data[0]) = ((op1 << 1) | (op1 >> 31)) ^ op2;
      break;
    default:
      ExRaiseFunctionSqlError(heap, diagsArea, EXE_INTERNAL_ERROR,
                              derivedFunction(),
                              origFunctionOperType());

      return ex_expr::EXPR_ERROR;
    }

  return ex_expr::EXPR_OK;
}

////////////////////////////////////////////////////////////////////
// class ExHiveHashComb
////////////////////////////////////////////////////////////////////
ex_expr::exp_return_type ExHiveHashComb::eval(char *op_data[],
                                          CollHeap* heap,
                                          ComDiagsArea** diagsArea)
{
  // always assume that both operands and result are of the same
  // (unsigned) type and length

  // with built-in long long type we could also support 8 byte integers
  ULng32 op1, op2;

  switch (getOperand(0)->getStorageLength())
    {
    case 4:
      op1 = *((ULng32 *) op_data[1]);
      op2 = *((ULng32 *) op_data[2]);

      // compute op1 * 31 + op2, optimized as op1 << 5 - op1 + op2
      *((ULng32 *) op_data[0]) = op1 << 5 - op1 + op2;
      break;

    default:
      ExRaiseFunctionSqlError(heap, diagsArea, EXE_INTERNAL_ERROR,
                              derivedFunction(),
                              origFunctionOperType());

      return ex_expr::EXPR_ERROR;
    }

  return ex_expr::EXPR_OK;
}


// -------------------------------------------------------------
// Hash Functions used by Hash Partitioning. These functions cannot
// change once Hash Partitioning is released!  Defined for all data
// types, returns a 32 bit non-nullable hash value for the data item.
// The ::hash() function uses a loop over the key bytes; the other
// hash2()/hash4()/hash8() are more efficient but are only applicable
// to keys whose sizes are known at compile time: 2/4/8 bytes.
//--------------------------------------------------------------

ULng32 ExHDPHash::hash(const char *data, UInt32 flags, Int32 length)
{
  ULng32 hashValue = 0;
  unsigned char *valp = (unsigned char *)data;
  Int32 iter = 0; // iterator over the key bytes, if needed
  
  switch(flags) {
  case NO_FLAGS:
  case SWAP_EIGHT:
    {

      // Speedup for long keys - compute first 8 bytes fast (the rest with a loop)
      if ( length >= 8 ) {
        hashValue = hash8(data, flags);  // do the first 8 bytes fast
        // continue with the 9-th byte (only when length > 8 )
        valp = (unsigned char *)&data[8];
        iter = 8; 
      }

      for(; iter < length; iter++) {
        // Make sure the hashValue is sensitive to the byte position.
        // One bit circular shift.
        hashValue = 
          (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*valp++];
      }
      break;
    }
  case SWAP_TWO:
    {

      // Speedup for long keys - compute first 8 bytes fast (the rest with a loop)
      if ( length >= 8 ) {
        hashValue = hash8(data, flags);  // do the first 8 bytes fast
        // continue with the 9-th byte (only when length > 8 )
        valp = (unsigned char *)&data[8];
        iter = 8; 
      }

      // Loop over all the bytes of the value and compute the hash value.
      for(; iter < length; iter+=2) {
        // Make sure the hashValue is sensitive to the byte position.
        // One bit circular shift.
        hashValue = 
          (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*(valp+1)];
        hashValue = 
          (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*valp];
        valp += 2;
      }
      break;
    }
  case SWAP_FOUR:
    {
      hashValue = hash4(data, flags);
      break;
    }
  case (SWAP_FIRSTTWO | SWAP_LASTFOUR):
  case SWAP_FIRSTTWO:
  case SWAP_LASTFOUR:
    {
      if((flags & SWAP_FIRSTTWO) != 0) {

        hashValue = randomHashValues[*(valp+1)];
        hashValue = 
          (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*valp];
        valp += 2;
        iter += 2;
      }

      if((flags & SWAP_LASTFOUR) != 0) {
        length -= 4;
      }

      for(; iter < length; iter++) {
        // Make sure the hashValue is sensitive to the byte position.
        // One bit circular shift.
        hashValue = 
          (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*valp++];
      }

      if((flags & SWAP_LASTFOUR) != 0) {
        hashValue = 
          (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*(valp+3)];
        hashValue = 
          (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*(valp+2)];
        hashValue = 
          (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*(valp+1)];
        hashValue = 
          (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*(valp+0)];
      }
      break;
    }
  default:
    assert(FALSE);
  }

  return hashValue;
}

ex_expr::exp_return_type ExHDPHash::eval(char *op_data[],
                                         CollHeap*,
                                         ComDiagsArea**)
{
  Attributes *srcOp = getOperand(1);
  ULng32 hashValue;

  if (srcOp->getNullFlag() && (! op_data[ -(2 * MAX_OPERANDS) + 1 ]))
  {
    // operand is a null value. All null values hash to 
    // the same hash value. Choose any arbitrary constant
    // number as the hash value.
    //
    hashValue =  ExHDPHash::nullHashValue; //666654765;
  }
  else {
    Int32 length = (Int32)srcOp->getLength(op_data[-MAX_OPERANDS + 1]);

    // if VARCHAR, skip trailing blanks and adjust length.
    if (srcOp->getVCIndicatorLength() > 0) {
	  
      switch ( srcOp->getDatatype() ) {

        // added to correctly handle VARNCHAR.
      case REC_NCHAR_V_UNICODE:
        {
          // skip trailing blanks
          NAWchar* wstr = (NAWchar*)(op_data[1]);
          Int32 wstr_length = length / sizeof(NAWchar);

          while ((wstr_length > 0) &&
	         ( wstr[wstr_length-1] == unicode_char_set::space_char()))
	    wstr_length--;
          
          length = sizeof(NAWchar) * wstr_length;
        }
        break;
      default:

        // skip trailing blanks
        while ((length > 0) &&
               (op_data[1][length-1] == ' '))
          length--;
        break;
      }
    }

    UInt32 flags = NO_FLAGS;

    switch(srcOp->getDatatype()) {
    case REC_NUM_BIG_UNSIGNED:
    case REC_NUM_BIG_SIGNED:
    case REC_BIN16_SIGNED:
    case REC_BIN16_UNSIGNED:
    case REC_NCHAR_F_UNICODE:
    case REC_NCHAR_V_UNICODE:
    case REC_NCHAR_V_ANSI_UNICODE:
      flags = SWAP_TWO;
      break; 
    case REC_BIN32_SIGNED:
    case REC_BIN32_UNSIGNED:
    case REC_IEEE_FLOAT32:
      flags = SWAP_FOUR;
      break;
    case REC_BIN64_SIGNED:
    case REC_BIN64_UNSIGNED:
    case REC_IEEE_FLOAT64:
      flags = SWAP_EIGHT;
      break;
    case REC_DATETIME:
      {
        rec_datetime_field start;
        rec_datetime_field end;
        ExpDatetime *datetime = (ExpDatetime*) srcOp;
        datetime->getDatetimeFields(srcOp->getPrecision(), start, end);
        if(start == REC_DATE_YEAR) {
          flags = SWAP_FIRSTTWO;
        }
        if(end == REC_DATE_SECOND && srcOp->getScale() > 0) {
          flags |= SWAP_LASTFOUR;
        }
      
      }
      break; 
    default:
      if(srcOp->getDatatype() >= REC_MIN_INTERVAL &&
         srcOp->getDatatype() <= REC_MAX_INTERVAL) {

        if (srcOp->getLength() == 8)
          flags = SWAP_EIGHT;
        else if (srcOp->getLength() == 4)
          flags = SWAP_FOUR;
        else if (srcOp->getLength() == 2)
          flags = SWAP_TWO;
        else
          assert(FALSE);
      }
    }

    hashValue = hash(op_data[1], flags, length);
  }

  *(ULng32 *)op_data[0] = hashValue;
   
  return ex_expr::EXPR_OK;
} // ExHDPHash::eval()

// --------------------------------------------------------------
// This function is used to combine two hash values to produce a new
// hash value. Used by Hash Partitioning. This function cannot change
// once Hash Partitioning is released!  Defined for all data types,
// returns a 32 bit non-nullable hash value for the data item.
// --------------------------------------------------------------
ex_expr::exp_return_type ExHDPHashComb::eval(char *op_data[], 
                                             CollHeap* heap,
                                             ComDiagsArea** diagsArea)
{
  // always assume that both operands and result are of the same
  // (unsigned) type and length

  assert(getOperand(0)->getStorageLength() == 4 &&
         getOperand(1)->getStorageLength() == 4 &&
         getOperand(2)->getStorageLength() == 4);

  ULng32 op1, op2;

  op1 = *((ULng32 *) op_data[1]);
  op2 = *((ULng32 *) op_data[2]);

  // One bit, circular shift
  op1 = ((op1 << 1) | (op1 >> 31));

  op1 = op1 ^ op2;

  *((ULng32 *) op_data[0]) = op1;
  
  return ex_expr::EXPR_OK;
} // ExHDPHashComb::eval()

// ex_function_replace_null
//
ex_expr::exp_return_type 
ex_function_replace_null::processNulls(char *op_data[],
				       CollHeap *heap,
				       ComDiagsArea **diagsArea) 
{
  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ex_function_replace_null::eval(char *op_data[], 
							CollHeap*,
							ComDiagsArea **) {
  Attributes *tgt = getOperand(0);

  // Mark the result as non-null
  if(tgt->getNullFlag())
    ExpTupleDesc::clearNullValue(op_data[ -(2 * MAX_OPERANDS) ],
                                 tgt->getNullBitIndex(),
                                 tgt->getTupleFormat());

  // If the input is NULL, replace it with the value in op_data[3]
  if (! op_data[ - (2 * MAX_OPERANDS) + 1]) {
    for(Lng32 i=0; i < tgt->getStorageLength(); i++)
      op_data[0][i] = op_data[3][i];
  }
  else {
    for(Lng32 i=0; i < tgt->getStorageLength(); i++)
      op_data[0][i] = op_data[2][i];
  }

  return ex_expr::EXPR_OK;
}

////////////////////////////////////////////////////////////////////
// class ex_function_mod
////////////////////////////////////////////////////////////////////
ex_expr::exp_return_type ex_function_mod::eval(char *op_data[],
					       CollHeap *heap,
					       ComDiagsArea** diagsArea)
{
  Int32 lenr = (Int32) getOperand(0)->getLength();
  Int32 len1 = (Int32) getOperand(1)->getLength();
  Int32 len2 = (Int32) getOperand(2)->getLength();

  Int64 op1, op2, result;

  switch (len1)
    {
    case 1:
      op1 = *((Int8 *) op_data[1]);
      break;
    case 2:
      op1 = *((short *) op_data[1]);
      break;
    case 4:
      op1 = *((Lng32 *) op_data[1]);
      break;
    case 8:
      op1 = *((Int64 *) op_data[1]);
      break;
    default:
      ExRaiseFunctionSqlError(heap, diagsArea, EXE_INTERNAL_ERROR,
			      derivedFunction(),
			      origFunctionOperType());

      return ex_expr::EXPR_ERROR;
    }

  switch (len2)
    {
    case 1:
      op2 = *((Int8 *) op_data[2]);
      break;
    case 2:
      op2 = *((short *) op_data[2]);
      break;
    case 4:
      op2 = *((Lng32 *) op_data[2]);
      break;
    case 8:
      op2 = *((Int64 *) op_data[2]);
      break;
    default:
      ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR);
      return ex_expr::EXPR_ERROR;
    }

  if (op2 == 0)
    {
      ExRaiseFunctionSqlError(heap, diagsArea, EXE_DIVISION_BY_ZERO,
			      derivedFunction(),
			      origFunctionOperType());
      return ex_expr::EXPR_ERROR;
    }

  result = op1 % op2;

  switch (lenr)
    {
    case 1:
      *((Int8 *) op_data[0]) = (short) result;
      break;
    case 2:
      *((short *) op_data[0]) = (short) result;
      break;
    case 4:
      *((Lng32 *) op_data[0]) = (Lng32)result;
      break;
    case 8:
      *((Int64 *) op_data[0]) = result;
      break;
    default:
      ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR);
      return ex_expr::EXPR_ERROR;
    }

  return ex_expr::EXPR_OK;
}

////////////////////////////////////////////////////////////////////
// class ex_function_mask
////////////////////////////////////////////////////////////////////
ex_expr::exp_return_type ex_function_mask::eval(char *op_data[], 
                                                CollHeap* heap,
                                                ComDiagsArea** diagsArea)
{
  // always assume that both operands and result are of the same
  // (unsigned) type and length

  // with built-in long long type we could also support 8 byte integers
  ULng32 op1, op2, result;

  switch (getOperand(0)->getStorageLength())
    {
    case 1:
      op1 = *((UInt8 *) op_data[1]);
      op2 = *((UInt8 *) op_data[2]);
      if(getOperType() == ITM_MASK_SET) {
        result = op1 | op2;
      } else {
        result = op1 & ~op2;
      }
      *((unsigned short *) op_data[0]) = (unsigned short) result;
      break;
    case 2:
      op1 = *((unsigned short *) op_data[1]);
      op2 = *((unsigned short *) op_data[2]);
      if(getOperType() == ITM_MASK_SET) {
        result = op1 | op2;
      } else {
        result = op1 & ~op2;
      }
      *((unsigned short *) op_data[0]) = (unsigned short) result;
      break;
    case 4:
      op1 = *((ULng32 *) op_data[1]);
      op2 = *((ULng32 *) op_data[2]);
      if(getOperType() == ITM_MASK_SET) {
        result = op1 | op2;
      } else {
        result = op1 & ~op2;
      }
      *((ULng32 *) op_data[0]) = result;
      break;
    case 8:
      {
        Int64 lop1 = *((Int64 *) op_data[1]);
        Int64 lop2 = *((Int64 *) op_data[2]);
        Int64 lresult;
        if(getOperType() == ITM_MASK_SET) {
          lresult = lop1 | lop2;
        } else {
          lresult = lop1 & ~lop2;
        }
        *((Int64 *) op_data[0]) = lresult;
        break;
      }
    default:
      ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR);
      return ex_expr::EXPR_ERROR;
    }

  return ex_expr::EXPR_OK;
}

////////////////////////////////////////////////////////////////////
// class ExFunctionShift
////////////////////////////////////////////////////////////////////
ex_expr::exp_return_type ExFunctionShift::eval(char *op_data[], 
                                               CollHeap* heap,
                                               ComDiagsArea** diagsArea)
{

  if(getOperand(2)->getStorageLength() != 4) {
    ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR);
    return ex_expr::EXPR_ERROR;
  }

  ULng32 shift = *((ULng32 *)op_data[2]);
  ULng32 value, result;

  switch (getOperand(0)->getStorageLength()) {
  case 1:
    value = *((UInt8 *) op_data[1]);
    if(getOperType() == ITM_SHIFT_RIGHT) {
      result = value >> shift;
    } else {
      result = value << shift;
    }
    *((UInt8 *) op_data[0]) = (UInt8) result;
    break;
  case 2:
    value = *((unsigned short *) op_data[1]);
    if(getOperType() == ITM_SHIFT_RIGHT) {
      result = value >> shift;
    } else {
      result = value << shift;
    }
    *((unsigned short *) op_data[0]) = (unsigned short) result;
    break;
  case 4:
    value = *((ULng32 *) op_data[1]);
    if(getOperType() == ITM_SHIFT_RIGHT) {
      result = value >> shift;
    } else {
      result = value << shift;
    }
    *((ULng32 *) op_data[0]) = result;
    break;
  case 8:
    {
      Int64 value = *((Int64 *) op_data[1]);
      Int64 result;
      if(getOperType() == ITM_SHIFT_RIGHT) {
        result = value >> shift;
      } else {
        result = value << shift;
      }
      *((Int64 *) op_data[0]) = result;
      break;
    }
    default:
      ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR);
      return ex_expr::EXPR_ERROR;
    }

  return ex_expr::EXPR_OK;
}
static
ex_expr::exp_return_type getDoubleValue(double *dest,
                                        char *source,
                                        Attributes *operand,
                                        CollHeap *heap,
                                        ComDiagsArea** diagsArea)
{
  switch(operand->getDatatype()) {
  case REC_FLOAT64:
    *dest = *(double *)(source);
    return ex_expr::EXPR_OK;
  default:
    ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR);
    return ex_expr::EXPR_ERROR;
  }
    
}

static
ex_expr::exp_return_type setDoubleValue(char *dest,
                                        Attributes *operand,
                                        double *source,
                                        CollHeap *heap,
                                        ComDiagsArea** diagsArea)
{
  switch(operand->getDatatype()) {
  case REC_FLOAT64:
    *(double *)dest = *source;
    return ex_expr::EXPR_OK;
  default:
    ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR);
    return ex_expr::EXPR_ERROR;
  }
    
}

ex_expr::exp_return_type ExFunctionSVariance::eval(char *op_data[],
						   CollHeap *heap,
						   ComDiagsArea **diagsArea)
{
  
  double sumOfValSquared = 0;
  double sumOfVal = 0;
  double countOfVal = 1;
  double avgOfVal;
  double result = 0;

  if(getDoubleValue(&sumOfValSquared, op_data[1], getOperand(1),
                    heap, diagsArea)) {
    return ex_expr::EXPR_ERROR;
  }

  if(getDoubleValue(&sumOfVal, op_data[2], getOperand(2), heap, diagsArea)) {
    return ex_expr::EXPR_ERROR;
  }

  if(getDoubleValue(&countOfVal, op_data[3], getOperand(3), heap, diagsArea)) {
    return ex_expr::EXPR_ERROR;
  }

  avgOfVal = sumOfVal/countOfVal;

  if(countOfVal == 1) {
    result = 0.0;
  }
  else {
    result = (sumOfValSquared - (sumOfVal * avgOfVal)) / (countOfVal - 1);

    if(result < 0.0) {
      result = 0.0;
    }
  }

  if(setDoubleValue(op_data[0], getOperand(0), &result, heap, diagsArea)) {
    return ex_expr::EXPR_ERROR;
  }

  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ExFunctionSStddev::eval(char *op_data[],
						 CollHeap *heap,
						 ComDiagsArea **diagsArea)
{
  
  double sumOfValSquared = 0;
  double sumOfVal = 0;
  double countOfVal = 1;
  double avgOfVal;
  double result = 0;

  if(getDoubleValue(&sumOfValSquared, op_data[1], getOperand(1),
                    heap, diagsArea)) {
    return ex_expr::EXPR_ERROR;
  }

  if(getDoubleValue(&sumOfVal, op_data[2], getOperand(2), heap, diagsArea)) {
    return ex_expr::EXPR_ERROR;
  }

  if(getDoubleValue(&countOfVal, op_data[3], getOperand(3), heap, diagsArea)) {
    return ex_expr::EXPR_ERROR;
  }

  avgOfVal = sumOfVal/countOfVal;

  if(countOfVal == 1) {
    result = 0.0;
  }
  else {
    short err = 0;
    result = (sumOfValSquared - (sumOfVal * avgOfVal)) / (countOfVal - 1);

    if(result < 0.0) {
      result = 0.0;
    } else {
      result = MathSqrt(result, err);
    }

    if (err)
      {
	  ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
	  **diagsArea << DgString0("SQRT");

	  ExRaiseSqlError(heap, diagsArea, EXE_MAPPED_FUNCTION_ERROR);
	  **diagsArea << DgString0("STDDEV");

	return ex_expr::EXPR_ERROR;
      }
  }

  if(setDoubleValue(op_data[0], getOperand(0), &result, heap, diagsArea)) {
    return ex_expr::EXPR_ERROR;
  }

  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ExpRaiseErrorFunction::eval(char *op_data[],
					       CollHeap* heap,
					       ComDiagsArea** diagsArea)
{
  char catName[ComAnsiNamePart::MAX_IDENTIFIER_EXT_LEN+1];
  char schemaName[ComAnsiNamePart::MAX_IDENTIFIER_EXT_LEN+1];

  // Don't do anything with the op[] data
  // Create a DiagsArea to return the SQLCODE and the ConstraintName
  // and TableName.
  if (raiseError())
    ExRaiseSqlError(heap, diagsArea, (ExeErrorCode)getSQLCODE());
  else
    ExRaiseSqlWarning(heap, diagsArea, (ExeErrorCode)getSQLCODE());

  // SQLCODE correspoding to Triggered Action Exception
  if (getSQLCODE() == ComDiags_TrigActionExceptionSQLCODE) 
  {
     assert(constraintName_ && tableName_);

     extractCatSchemaNames(catName, schemaName, constraintName_);
                         
     *(*diagsArea) << DgTriggerCatalog(catName);
     *(*diagsArea) << DgTriggerSchema(schemaName);
     *(*diagsArea) << DgTriggerName(constraintName_);

     extractCatSchemaNames(catName, schemaName, tableName_);

     *(*diagsArea) << DgCatalogName(catName);
     *(*diagsArea) << DgSchemaName(schemaName);
     *(*diagsArea) << DgTableName(tableName_);
  }
  else if (getSQLCODE() == ComDiags_SignalSQLCODE)  // Signal Statement
  {    
	if (constraintName_)
		*(*diagsArea) << DgString0(constraintName_);  // The SQLSTATE
  
	if (getNumOperands()==2) 
        {
           Lng32 len1 = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);
           op_data[1][len1] = '\0';
           *(*diagsArea) << DgString1(op_data[1]);  // The string expression
	} 
        else
          if (tableName_)
            *(*diagsArea) << DgString1(tableName_);   // The message
  } 
  else 
  {
	if (constraintName_)
        {
            extractCatSchemaNames(catName, schemaName, constraintName_);

	    *(*diagsArea) << DgConstraintCatalog(catName);
	    *(*diagsArea) << DgConstraintSchema(schemaName);
	    *(*diagsArea) << DgConstraintName(constraintName_);
        }
	if (tableName_)
        {
            extractCatSchemaNames(catName, schemaName, tableName_);

	    *(*diagsArea) << DgCatalogName(catName);
	    *(*diagsArea) << DgSchemaName(schemaName);
	    *(*diagsArea) << DgTableName(tableName_);
        }
  }

  // If it's a warning, we should return a predictable boolean value.
  *((ULng32*)op_data[0]) = 0;

  if (raiseError())
    return ex_expr::EXPR_ERROR;
  else
    return ex_expr::EXPR_OK;
}

// -----------------------------------------------------------------------
// methods for ExFunctionPack
// -----------------------------------------------------------------------
// Constructor.
ExFunctionPack::ExFunctionPack(Attributes** attr,
                               Space* space,
                               Lng32 width,
                               Lng32 base,
                               NABoolean nullsPresent)
 : ex_function_clause(ITM_PACK_FUNC,3,attr,space),
   width_(width), base_(base)
{
   setNullsPresent(nullsPresent);
}

// Evaluator.
ex_expr::exp_return_type ExFunctionPack::eval(char* op_data[],
                                              CollHeap* heap,
                                              ComDiagsArea** diagsArea)
{
  char guard1 = op_data[0][-1];
  char guard2 = op_data[0][getOperand(0)->getLength()];

  // Extract no of rows already in the packed record.
  Lng32 noOfRows;
  str_cpy_all((char*)&noOfRows,op_data[0],sizeof(Lng32));

  // Extract the packing factor.
  Lng32 pf = *(Lng32 *)op_data[2];

  // The clause returns an error for no more slots in the packed record.
  if(noOfRows >= pf)
  {
    ExRaiseSqlError(heap,diagsArea,EXE_INTERNAL_ERROR);
    return ex_expr::EXPR_ERROR;
  }

  // Whether the source is null.
  char* nullFlag = op_data[-2*ex_clause::MAX_OPERANDS+1];

  // If null bit map is present in the packed record.
  if(nullsPresent())
  {
    // Offset of null bit from the beginning of the null bitmap.
    Lng32 nullBitOffsetInBytes = noOfRows >> 3;

    // Offset of null bit from the beginning of the byte it is in.
    Lng32 nullBitOffsetInBits = noOfRows & 0x7;

    // Extract the byte in which the null bit is in.
    char* nullByte = op_data[0] + nullBitOffsetInBytes + sizeof(Int32);

    // Used to set/unset the null bit.
    unsigned char nullByteMask = (1 << nullBitOffsetInBits);

    // Turn bit off/on depending on whether operand is null.
    if(nullFlag == 0)
      *nullByte |= nullByteMask;  // set null bit on.
    else
      *nullByte &= (~nullByteMask);  // set null bit off.
  }
  else if(nullFlag == 0) 
  {
    // Bit map is not present but input is null. We got a problem.
    ExRaiseSqlError(heap,diagsArea,EXE_INTERNAL_ERROR);
    return ex_expr::EXPR_ERROR;
  }

  // We have contents to copy only if source is not null.
  if(nullFlag != 0)
    {
    // Width of each packet in the packed record. -ve means in no of bits.
    if(width_ < 0)
    {
      Lng32 widthInBits = -width_;

      // Length of data region which has already been occupied in bits.
      Lng32 tgtBitsOccupied = (noOfRows * widthInBits);

      // Byte offset for data of this packet from beginning of data region.
      Lng32 tgtByteOffset = base_ + (tgtBitsOccupied >> 3);

      // Bit offset for data of this packet from beginning of its byte.
      Lng32 tgtBitOffset = (tgtBitsOccupied & 0x7);

      // Byte offset of data source left to be copied.
      Lng32 srcByteOffset = 0;

      // Bit offset of data source from beginning of its byte to be copied.
      Lng32 srcBitOffset = 0;

      // No of bits to copy in total.
      Lng32 bitsToCopy = widthInBits;

      // There are still bits remaining to be copied.
      while(bitsToCopy > 0)
      {
        // Pointer to the target byte.
        char* tgtBytePtr = (op_data[0] + tgtByteOffset);

        // No of bits left in the target byte.
        Lng32 bitsLeftInTgtByte = 8 - tgtBitOffset;

        // No of bits left in the source byte.
        Lng32 bitsLeftInSrcByte = 8 - srcBitOffset;

        Lng32 bitsToCopyThisRound = (bitsLeftInTgtByte > bitsLeftInSrcByte ?
                                    bitsLeftInSrcByte : bitsLeftInTgtByte);

        if(bitsToCopyThisRound > bitsToCopy) bitsToCopyThisRound = bitsToCopy;

        // Mask has ones in the those positions where bits will be copied to.
        unsigned char mask = ((0xFF >> tgtBitOffset) <<
                              (8 - bitsToCopyThisRound)) >>
                              (8 - tgtBitOffset - bitsToCopyThisRound);

        // Clear target bits. Keep other bits unchanged in the target byte.
        (*tgtBytePtr) &= (~mask);

        // Align source bits with its the destination. Mask off other bits.
        unsigned char srcByte = *(op_data[1] + srcByteOffset);
        srcByte = ((srcByte >> srcBitOffset) << tgtBitOffset) & mask;

        // Make the copy.
        (*tgtBytePtr) |= srcByte;

        // Move source byte and bit offsets.
        srcBitOffset += bitsToCopyThisRound;
        if(srcBitOffset >= 8)
        {
          srcByteOffset++;
          srcBitOffset -= 8;
        }

        // Move target byte and bit offsets.
        tgtBitOffset += bitsToCopyThisRound;
        if(tgtBitOffset >= 8)
        {
          tgtByteOffset++;
          tgtBitOffset -= 8;
        }

        bitsToCopy -= bitsToCopyThisRound;
      }
    }
    else // width_ > 0
    {
      // Width in bytes: we can copy full strings of bytes.
      Lng32 tgtByteOffset = base_ + (noOfRows * width_);
      str_cpy_all(op_data[0]+tgtByteOffset,op_data[1],width_);
    }
  }

  // Update the "noOfRows" in the packed record.
  noOfRows++;
  str_cpy_all(op_data[0],(char*)&noOfRows,sizeof(Lng32));

  // $$$ supported as a CHAR rather than a VARCHAR for now.
  // getOperand(0)->
  // setVarLength(offset+lengthToCopy,op_data[-ex_clause::MAX_OPERANDS]);

  if(guard1 != op_data[0][-1] ||
     guard2 != op_data[0][getOperand(0)->getLength()]) {
    ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR);
    return ex_expr::EXPR_ERROR;
  }

  // Signal a completely packed record to the caller.
  if(noOfRows == pf) return ex_expr::EXPR_TRUE;

  // Signal an incompletely packed record to the caller.
  return ex_expr::EXPR_FALSE;
}

// ExUnPackCol::eval() ------------------------------------------
// The ExUnPackCol clause extracts a set of bits from a CHAR value. 
// The set of  bits to extract is described by a base offset, a width, 
// and an index.  The offset and width are known at compile time, but
// the index is a run time variable.  ExUnPackCol clause also gets
// the null indicator of the result from a bitmap within the CHAR
// field.
// 
ex_expr::exp_return_type 
ExUnPackCol::eval(char *op_data[], CollHeap *heap, ComDiagsArea **diagsArea)
{

  // The width of the extract in BITS.
  //
  Lng32 width = width_;

  // The base offset of the data in BYTES.
  //
  Lng32 base = base_;

  // Boolean indicating if the NULL Bitmap is present.
  // If it is present, then it starts at a 4 (sizeof(int)) byte offset.
  //
  NABoolean np = nullsPresent();
  
  // Which piece of data are we extracting.
  //
  Lng32 index = *(Lng32 *)op_data[2];


  // NULL Processing...
  //
  if(np) {

    // The bit to be extracted.
    //
    Lng32 bitOffset = index;

    // The byte of the CHAR field containing the bit.
    //
    Lng32 byteOffset = sizeof(Int32) + (bitOffset >> 3);

    // The bit of the byte at byteOffset to be extracted.
    //
    bitOffset = bitOffset & 0x7;

    // A pointer to the null indicators of the operands.
    //
    char **null_data = &op_data[-2 * ex_clause::MAX_OPERANDS];
    

    // The mask used to test the NULL bit.
    //
    UInt32 mask = 1 << bitOffset;

    // The byte containing the NULL Flag.
    //
    UInt32 byte = op_data[1][byteOffset];
    
    // Is the NULL Bit set?
    //
    if(byte & mask) {

      // The value is NULL, so set the result to NULL, and
      // return since we do not need to extract the data.
      //
      *(short *)null_data[0] = (short)0xFFFF; 
      return ex_expr::EXPR_OK;
    } else {

      // The value is non-NULL, so set the indicator,
      // continue to extract the data value.
      //
      *(short *)null_data[0] = 0; 
    }
  }


  // Bytes masks used for widths (1-8) of bit extracts.
  //
  const UInt32 masks[] = {0,1,3,7,15,31,63,127,255};

  // Handle some special cases:
  // Otherwise do a generic bit extract.
  //
  if(width == 8 || width == 4 || width == 2 || width == 1) {

    // Items per byte for special case widths (1-8).
    //
    const UInt32 itemsPerBytes[] =     {0,8,4,2,2,1,1,1,1};

    // Amount to shift the index to get a byte index for the
    // special case widths.
    //
    const UInt32 itemsPerByteShift[] = {0,3,2,1,1,0,0,0,0};

    // Extracted value.
    //
    UInt32 value;

    // An even more special case.
    //
    if(width == 8) {

      // Must use unsigned assignment so that sign extension is not done.
      // Later when signed bit precision integers are support will have
      // to have a special case for those.
      //
      value = (unsigned char)op_data[1][base + index];
    } else {

      // The number of items in a byte.
      //
      UInt32 itemsPerByte = itemsPerBytes[width];

      // The amount to shift the index to get a byte offset.
      //
      UInt32 shift = itemsPerByteShift[width];

      // The offset of the byte containing the value.
      //
      Lng32 byteIndex = index >> shift;

      // The index into the byte of the value.
      //
      Lng32 itemIndex = index & ( itemsPerByte - 1);

      // A mask to extract an item of size width.
      //
      UInt32 mask = masks[width];

      // The byte containing the item.
      //
      value = op_data[1][base + byteIndex];

      // Shift the byte, so that the value to be
      // extracted is in the least significant bits.
      //
      value = value >> (width * itemIndex);

      // Clear all bits except those of the value.
      //
      value = value & mask;

    }

    // Copy value to result.
    //
    switch(getOperand(0)->getLength()) {
    case 1:
      *(unsigned char *)op_data[0] = value;
      return ex_expr::EXPR_OK;
    case 2:
      *(unsigned short *)op_data[0] = value;
      return ex_expr::EXPR_OK;
    case 4:
      *(ULng32 *)op_data[0] = value;
      return ex_expr::EXPR_OK;
    default:
      // ERROR - This should never happen.
      //
      ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR);
      return ex_expr::EXPR_ERROR;
    }

    return ex_expr::EXPR_OK;
  }


  // Handle special case of a Byte copy.
  //
  if((width % 8) == 0) {

    width = width/8;

    str_cpy_all(op_data[0], &op_data[1][base + (index * width)], width);
    return ex_expr::EXPR_OK;

  } 

  char guard1 = op_data[0][-1];
  char guard2 = op_data[0][getOperand(0)->getLength()];

  // The general case of arbitrary bit lengths that can span byte boundaries.
  //

  // The offset to the value in bits.
  //
  Lng32 bitOffset = index * width;

  // The offset to the last bit of the value in bits.
  //
  Lng32 bitOffsetEnd = bitOffset + width - 1;
  
  // The offset to the byte containing the first bit of the value.
  // in bytes.
  //
  Lng32 byteOffset = base + (bitOffset >> 3);

  // The offset to the byte containing the first bit beyond the value.
  // in bytes.
  //
  Lng32 byteOffsetEnd = base + (bitOffsetEnd >> 3);

  // The offset of the first bit in the byte.
  //
  bitOffset = bitOffset & 0x7;

  // The amount to shift the byte to the right to align
  // the lower portion.
  //
  Lng32 rshift = bitOffset;

  // The amount to shift the byte to the left to align
  // the upper portion.
  //
  Lng32 lshift = 8 - bitOffset;

  // An index into the destination.
  //
  Lng32 dindex = 0;

  // Copy all the bits to the destination.
  //
  Int32 i = byteOffset;
  for(; i <= byteOffsetEnd; i++) {
 
    // Get a byte containing bits of the value.
    //
    unsigned char byte = op_data[1][i];
      
    if(dindex > 0) {
      // After the first byte, must copy the upper
      // portion of the byte to the previous byte of
      // the result. This is the second time writing
      // to this byte.
      //
      op_data[0][dindex - 1] |= byte << lshift;
    }

    if(dindex < (Lng32) getOperand(0)->getLength()) {
      // Copy the lower portion of this byte of the result
      // to the destination.  This is the first time this
      // byte is written to.
      //
      op_data[0][dindex] = byte >> rshift;
    }

    dindex++;

  }

  // Clear all bits of the result that did not come
  // from the extracted value.
  //
  for(i = 0; i < (Lng32) getOperand(0)->getLength(); i++) {

    unsigned char mask = (width > 7) ? 0xFF : masks[width];
    
    op_data[0][i] &= mask;
    width -= 8;
    width = (width < 0) ? 0 : width;
  }

  if(guard1 != op_data[0][-1] ||
     guard2 != op_data[0][getOperand(0)->getLength()]) {
    ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR);
    return ex_expr::EXPR_ERROR;
  }

  return ex_expr::EXPR_OK;
}
ex_expr::exp_return_type ex_function_translate::eval(char *op_data[],
                                                     CollHeap* heap,
                                                     ComDiagsArea** diagsArea)
{
  Int32 copyLen = 0;
  Int32 convertedLen = 0;
  Int32 convType = get_conv_type();

  Attributes * op0 = getOperand(0);
  Attributes * op1 = getOperand(1);
  ULng32 convFlags = (flags_ & TRANSLATE_FLAG_ALLOW_INVALID_CODEPOINT ?
                      CONV_ALLOW_INVALID_CODE_VALUE : 0);

      return convDoIt(op_data[1],
        op1->getLength(op_data[-MAX_OPERANDS + 1]),
        op1->getDatatype(),
        op1->getPrecision(),
        (convType == CONV_UTF8_F_UCS2_V) ? (Int32)(CharInfo::UTF8) : op1->getScale(),
        op_data[0],
        op0->getLength(),
        op0->getDatatype(),
        op0->getPrecision(),
        (convType == CONV_UCS2_F_UTF8_V) ? (Int32)(CharInfo::UTF8) : op0->getScale(),
        op_data[-MAX_OPERANDS],
        op0->getVCIndicatorLength(),
        heap,
        diagsArea,
        (ConvInstruction)convType,
        NULL,
        convFlags);
}
  
void ExFunctionRandomNum::initSeed(char *op_data[])
{
  if (seed_==0)
    {
      if (simpleRandom())
	{
	  // start with 1 and go up to max
	  seed_ = 1;
	  return;
	}

      if (getNumOperands() == 2)
	{
	  // seed is specified as an argument. Use it.
	  seed_ = *(ULng32 *)op_data[1];
	  return;
	}

      // Pick an initial seed.  According to the reference given below
      // (in the eval function), all initial seeds between 1 and
      // 2147483646 are equally valid.  So, we just need to pick one
      // in this range.  Do this based on a timestamp.

      // Use ex_function_current to get timestamp.
      //
      char currBuff[32];
      char *opData[1];
      opData[0] = currBuff;
      ex_function_current currentFun;
      currentFun.eval(&opData[0], 0, 0);

      // Extract year, month, etc.
      //
      char *p = currBuff;
      short year = *((short*) p);
      p += sizeof(short);
      char month = *p++;
      char day = *p++;
      char hour = *p++;
      char minute = *p++;
      char second = *p++;
      Lng32 fraction = *((Lng32*) p);

      // Local variables year, ..., fraction are now initialized.
      // From the values of these variables, generate a seed in the
      // desired range.

      Lng32 x = year * month * day;
      if (hour) x *= hour;
      p = (char*) &x;

      assert(sizeof(Lng32)==4);

      p[0] |= (second<<1);
      p[1] |= (minute<<1);
      p[2] |= (minute<<2);
      p[3] |= second;

      seed_ = x + fraction;

      if (seed_<0)
        seed_ += 2147483647;
      if ( seed_ < 1 ) seed_ = 1;
    }
}


void ExFunctionRandomNum::genRand(char *op_data[])
{
  // Initialize seed if not already done
  initSeed(op_data);

  Lng32 t = 0;
  const Lng32 M = 2147483647;
  if (simpleRandom())
    {
      t = seed_ + 1;
    }
  else
    {
      // Algorithm is taken from "Random Number Generators: Good Ones
      // Are Hard To Find", by Stephen K. Park and Keith W. Miller, 
      // Communications of the ACM, Volume 31, Number 10, Oct 1988.

      const Lng32 A = 16807;
      const Lng32 Q = 127773;
      const Lng32 R = 2836;

      Lng32 h = seed_/Q;
      Lng32 l = seed_%Q;
      t = A*l-R*h;
  }

  if (t>0) 
     seed_ = t;
  else
     seed_ = t + M;
}


ex_expr::exp_return_type ExFunctionRandomNum::eval(char *op_data[],
                                                   CollHeap*,
                                                   ComDiagsArea**)
{
  genRand(op_data); // generates and sets the random number in seed_

  *((ULng32*)op_data[0]) = (ULng32) seed_;

  return ex_expr::EXPR_OK;
}


void ExFunctionRandomSelection::initDiff()
{
  if (difference_ == -1)
  {
    difference_ = 0;
    
    while (selProbability_ >= 1.0)
    {
      difference_++;
      selProbability_ -= 1.0;
    }
    
    // Normalize the selProbability to a 32 bit integer and store in 
    // normProbability
  
    normProbability_ = (Lng32) (selProbability_ * 0x7fffffff);
  
    // reset the selProbability_ to original value in case this function
    // gets called again
    
    selProbability_ += difference_;
  }
}


ex_expr::exp_return_type ExFunctionRandomSelection::eval(char *op_data[],
                                                         CollHeap*,
                                                         ComDiagsArea**)
{
  initDiff(); // gets executed only once

  genRand(NULL); // generates and sets the random number in seed_

  if (getRand() < normProbability_)
    *((ULng32*)op_data[0]) = (ULng32) (difference_ + 1);
  else
    *((ULng32*)op_data[0]) = (ULng32) (difference_);

  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ExHash2Distrib::eval(char *op_data[],
                                              CollHeap*,
                                              ComDiagsArea**)
{
  ULng32 keyValue = *(ULng32*)op_data[1];
  ULng32 numParts = *(ULng32*)op_data[2];
  ULng32 partNo =
     (ULng32)(((Int64)keyValue * (Int64)numParts) >> 32);

  *(ULng32*)op_data[0] = partNo;

  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ExProgDistrib::eval(char *op_data[],
                                             CollHeap*,
                                             ComDiagsArea**)
{
  ULng32 keyValue = *(Lng32*)op_data[1];
  ULng32 totNumValues = *(Lng32*) op_data[2];
  ULng32 resultValue = 1;
  ULng32 offset = keyValue;
  ULng32 i = 2;

  while(offset >= i && i <= totNumValues) {
    Lng32 n1 = offset % i;
    Lng32 n2 = offset / i;
    if (n1 == 0) {
      offset = (i-1) * (n2 - 1) + resultValue;
      resultValue = i;
      i++;
    } else {
      Lng32 n3 = n2 << 1;

      if(n1 > n3) {
        Lng32 n = n1/n3 + (n1%n3 != 0);
        offset -= n2 * n;
        i += n;
      } else {
        offset -= n2;
        i++;
      }
    }
  }

  *((ULng32 *)op_data[0]) = resultValue - 1;
  return ex_expr::EXPR_OK;
}
ex_expr::exp_return_type ExProgDistribKey::eval(char *op_data[],
                                                CollHeap*,
                                                ComDiagsArea**)
{
  ULng32 value = *(ULng32*)op_data[1];
  ULng32 offset = *(ULng32*)op_data[2];
  ULng32 totNumValues = *(ULng32*)op_data[3];
  ULng32 uniqueVal = offset >> 16;
  offset = offset & 0x0000FFFF;

  value++;

  ULng32 i = totNumValues;
  while(i >= 2) {

    if (value==i) {
      value = (ULng32) (offset-1)%(i-1) + 1;
      offset = ((offset-1)/(i-1) + 1) * i;
      i--;
    } else if(offset < i) {
      i = (offset>value?offset:value);
    } else {
      offset = offset + (offset-1)/(i-1);
      i--;
    }
  }
  
  Int64 result = offset;
  result = ((result << 16) | uniqueVal) << 16;

  *((Int64 *)op_data[0]) = result;

  return ex_expr::EXPR_OK;

}
ex_expr::exp_return_type ExPAGroup::eval(char *op_data[],
                                         CollHeap*,
                                         ComDiagsArea**)
{
  ULng32 partNum = *(ULng32*)op_data[1];
  ULng32 totNumGroups = *(ULng32*) op_data[2];
  ULng32 totNumParts = *(ULng32*) op_data[3];

  ULng32 scaleFactor = totNumParts / totNumGroups;
  ULng32 transPoint = (totNumParts % totNumGroups);

  ULng32 groupPart;

  if(partNum < (transPoint  * (scaleFactor + 1))) {
    groupPart = partNum / (scaleFactor + 1);
  } else {
    groupPart = (partNum - transPoint) / scaleFactor;
  }

  *((ULng32 *)op_data[0]) = groupPart;
  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ExFunctionRangeLookup::eval(char *op_data[],
						     CollHeap*,
						     ComDiagsArea**)
{
  // Two operands get passed to ExFunctionRangeLookup: a pointer to
  // the actual, encoded key, and a pointer into a constant array
  // that contains the encoded split ranges. The result is a 4 byte
  // integer, not NULL, that contains the partition number.
  char *encodedKey = op_data[1];
  char *sKeys = op_data[2];
  Lng32 *result = (Lng32 *) op_data[0];

  // Now perform a binary search in sKeys

  Lng32 lo = 0;
  Lng32 hi = numParts_; // note we have one more entry than parts
  Lng32 probe;
  Lng32 cresult;

  while (hi-lo > 1)
    {
      // try the element in the middle (may round down)
      probe = (lo+hi)/2;

      // compare our encoded key with that middle split range
      cresult = str_cmp(encodedKey,
			&sKeys[probe*partKeyLen_],
			partKeyLen_);
      if (cresult <= 0)
	hi = probe; // search first half, discard second half

      if (cresult >= 0)
	lo = probe; // search second half, discard first half
    }

  // Once we have narrowed it down to a difference between lo and hi
  // of 0 or 1, we know that lo points to the index of our partition
  // because the partition number must be greater or equal to lo and
  // less than hi. Remember that we set hi to one more than we had
  // partition numbers.
  *result = lo;

  return ex_expr::EXPR_OK;
}

ExRowsetArrayScan::ExRowsetArrayScan(){};
ExRowsetArrayRowid::ExRowsetArrayRowid(){};
ExRowsetArrayInto::ExRowsetArrayInto(){};

ExRowsetArrayScan::ExRowsetArrayScan(Attributes **attr,
                                       Space     *space,
                                       Lng32      maxNumElem,
                                       Lng32      elemSize,
                                       NABoolean elemNullInd)
  : maxNumElem_(maxNumElem),
    elemSize_(elemSize),
    elemNullInd_(elemNullInd),
    ex_function_clause(ITM_ROWSETARRAY_SCAN, 3, attr, space)
{
};

ExRowsetArrayRowid::ExRowsetArrayRowid(Attributes **attr,
                                       Space     *space,
                                       Lng32      maxNumElem)
  : maxNumElem_(maxNumElem),
    ex_function_clause(ITM_ROWSETARRAY_ROWID, 3, attr, space)
{
};

ExRowsetArrayInto::ExRowsetArrayInto(Attributes **attr,
                                     Space     *space,
                                     Lng32      maxNumElem,
                                     Lng32      elemSize,
                                     NABoolean elemNullInd)
  : maxNumElem_(maxNumElem),
    numElem_(0),
    elemSize_(elemSize),
    elemNullInd_(elemNullInd),
    ex_function_clause(ITM_ROWSETARRAY_INTO, 3, attr, space)

{
};


// ExRowsetArrayScan::eval() ------------------------------------------
// The ExRowsetArrayScan clause extracts an element of the Rowset array
// The size of the element is known at compile time, but the index is a
// run time variable.  
ex_expr::exp_return_type 
ExRowsetArrayScan::eval(char          *op_data[],
                        CollHeap      *heap, 
                        ComDiagsArea **diagsArea)
{
  // op_data[0] points to the result
  // op_data[1] points to the array
  // op_data[2] points to the index

  Lng32 index = *(Lng32 *)op_data[2];

  if (index < 0 || index >= maxNumElem_)
    {
      // The index cannot be greater than the dimension of the array
      // It is likely that there was an item expression evaluated at 
      // execution time to obtain the rowsetSize which is greater than
      // the maximum allowed.
      ExRaiseSqlError(heap, diagsArea, EXE_ROWSET_INDEX_OUTOF_RANGE);
      **diagsArea << DgSqlCode(-EXE_ROWSET_INDEX_OUTOF_RANGE);

      return ex_expr::EXPR_ERROR;
    }

  Attributes *ResultAttr = getOperand(0);
  Attributes *SourceAttr = getOperand(1);
  Lng32 size = ResultAttr->getStorageLength();
  char *SourceElemPtr    = &op_data[1][(index * size) + sizeof(Lng32)];

  // NULL Processing...
  if(elemNullInd_) {
    // A pointer to the null indicators of the operands.
    char **ResultNullData  = &op_data[-2 * ex_clause::MAX_OPERANDS];
    char *SourceElemIndPtr = SourceElemPtr;

    SourceElemPtr += SourceAttr->getNullIndicatorLength();

    // Set the indicator
    if (ResultAttr->getNullFlag()) {
      str_cpy_all(ResultNullData[0], SourceElemIndPtr, 
                  SourceAttr->getNullIndicatorLength());
    }
     
    if ( ExpTupleDesc::isNullValue( SourceElemIndPtr,
                                    SourceAttr->getNullBitIndex(),
                                    SourceAttr->getTupleFormat() ) )
    {
      // The value is NULL, return since we do not need to extract the data.
      return ex_expr::EXPR_NULL;
    }
  }
  
  // For SQLVarChars, we have to copy both length and value fields.
  // op_data[-ex_clause::MAX_OPERANDS] points to the length field of the
  // SQLVarChar;
  // The size of the field is sizeof(short) for rowset SQLVarChars. 
  if(SourceAttr->getVCIndicatorLength() > 0){
    str_cpy_all((char*)op_data[-ex_clause::MAX_OPERANDS], 
      (char*)(&op_data[-ex_clause::MAX_OPERANDS+1][index*size]), 
                SourceAttr->getVCIndicatorLength()); //sizeof(short));
    SourceElemPtr += SourceAttr->getVCIndicatorLength();
    str_cpy_all(op_data[0], SourceElemPtr, size - SourceAttr->getVCIndicatorLength());
  }
  else {
  // Note we do not have variable length for host variables. But we may not
  // need to copy the whole length for strings. 
    str_cpy_all(op_data[0], SourceElemPtr, size);
  }

  return ex_expr::EXPR_OK;
}

Long ExRowsetArrayScan::pack(void * space)
{
  return packClause(space, sizeof(ExRowsetArrayScan));
}

Long ExRowsetArrayRowid::pack(void * space)
{
  return packClause(space, sizeof(ExRowsetArrayRowid));
}

Long ExRowsetArrayInto::pack(void * space)
{
  return packClause(space, sizeof(ExRowsetArrayInto));
}

// ExRowsetArrayRowid::eval() ------------------------------------------
// The ExRowsetArrayRowid clause returns the value of the current index
ex_expr::exp_return_type 
ExRowsetArrayRowid::eval(char *op_data[], CollHeap *heap, 
                         ComDiagsArea **diagsArea)
{
  // op_data[0] points to the result
  // op_data[1] points to the array
  // op_data[2] points to the index

  // The width of each data item in bytes

  Lng32 index = *(Lng32 *)op_data[2];

  if (index < 0 || index >= maxNumElem_)
    {
      // The index cannot be greater than the dimension of the array
      // It is likely that there was an item expression evaluated at 
      // execution time to obtain the rowsetSize which is greater than
      // the maximum allowed.
      ExRaiseSqlError(heap, diagsArea, EXE_ROWSET_INDEX_OUTOF_RANGE);
      **diagsArea << DgSqlCode(-EXE_ROWSET_INDEX_OUTOF_RANGE);
      return ex_expr::EXPR_ERROR;
    }

  // Note we do not have variable length for host variables. But we may not
  // need to copy the whole length for strings.
  str_cpy_all(op_data[0], (char *)&index, sizeof(index));

  return ex_expr::EXPR_OK;
}

// ExRowsetArrayInto::eval() ------------------------------------------
// The ExRowsetArrayInto clause appends a value into the Rowset array
// The size of the element is known at compile time
ex_expr::exp_return_type 
ExRowsetArrayInto::eval(char *op_data[], CollHeap *heap, 
                        ComDiagsArea **diagsArea)
{
  // op_data[0] points to the array (Result)
  // op_data[1] points to the value to insert
  // op_data[2] points to the rowset size expression

  Lng32 runtimeMaxNumElem = *(Lng32 *)op_data[2];

  if (numElem_ >= runtimeMaxNumElem || numElem_ >= maxNumElem_) {
    // Overflow, we cannot add more elements to this rowset array
    ExRaiseSqlError(heap, diagsArea, EXE_ROWSET_OVERFLOW);
    **diagsArea << DgSqlCode(-EXE_ROWSET_OVERFLOW);
    return ex_expr::EXPR_ERROR;
  }

  // Get number of rows stored in the array
  Lng32 nrows;
  str_cpy_all((char*)&nrows,op_data[0],sizeof(Lng32));

  if (nrows >= runtimeMaxNumElem || nrows >= maxNumElem_) {
    // Overflow, we cannot add more elements to this rowset array
    ExRaiseSqlError(heap, diagsArea, EXE_ROWSET_OVERFLOW);
    **diagsArea << DgSqlCode(-EXE_ROWSET_OVERFLOW);
    return ex_expr::EXPR_ERROR;
  }

  Attributes *resultAttr   = getOperand(0);
  NABoolean   resultIsNull = FALSE;
  char *sourceNullData     = op_data[-2 * ex_clause::MAX_OPERANDS + 1];
  Attributes *sourceAttr   = getOperand(1);

  Lng32 elementSize = ((SimpleType *) resultAttr)->getStorageLength();

  char *resultElemPtr      = &op_data[0][(nrows * elementSize) + 
                                        sizeof (Lng32)];

  // NULL Processing...
  if (elemNullInd_) {
    char *resultElemIndPtr = resultElemPtr;

    // Set the indicator
    if (sourceAttr->getNullFlag() && sourceNullData == 0) {
      ExpTupleDesc::setNullValue(resultElemIndPtr,
                                 resultAttr->getNullBitIndex(),
                                 resultAttr->getTupleFormat());
      resultIsNull = TRUE;
    } else {
      ExpTupleDesc::clearNullValue(resultElemIndPtr,
                                   resultAttr->getNullBitIndex(),
                                   resultAttr->getTupleFormat());
    }
  } else if (sourceAttr->getNullFlag() && sourceNullData == 0) {
    // Source is null, but we do not have a way to express it
    ExRaiseSqlError(heap, diagsArea, EXE_MISSING_INDICATOR_VARIABLE);
    **diagsArea << DgSqlCode(-EXE_MISSING_INDICATOR_VARIABLE);
    return ex_expr::EXPR_ERROR;
  }
  
  // Copy the result if not null
  // For SQLVarChars, copy both val and len fields.
  if (resultIsNull == FALSE){  
    if (DFS2REC::isSQLVarChar(resultAttr->getDatatype())) { 
      unsigned short VCLen = 0;
      str_cpy_all((char *) &VCLen,
                  (char*)op_data[-ex_clause::MAX_OPERANDS + 1], 
                  resultAttr->getVCIndicatorLength());
    
      str_cpy_all( resultElemPtr+resultAttr->getNullIndicatorLength(),
                   (char *) &VCLen,
                   resultAttr->getVCIndicatorLength());

      str_cpy_all( 
                  resultElemPtr+resultAttr->getNullIndicatorLength()+
                  resultAttr->getVCIndicatorLength(),
                  op_data[1], VCLen); 
    }
    else {
      str_cpy_all(resultElemPtr + resultAttr->getNullIndicatorLength(), 
                                  op_data[1], resultAttr->getLength());
    } // if isSQLVarChar
  } // if resultIsNULL

  // Update the number of elements in the object associated with the array
  // and the array itself
  nrows++;
  str_cpy_all(op_data[0],(char*)&nrows,sizeof(Lng32));

  return ex_expr::EXPR_OK;
}
ex_expr::exp_return_type ex_function_nullifzero::eval(char *op_data[],
						      CollHeap *heap,
						      ComDiagsArea** diagsArea)
{
  Attributes *tgtOp = getOperand(0);
  char * tgt = op_data[0];
  char * tgtNull = op_data[-2 * MAX_OPERANDS];
  char * src = op_data[1];
  Lng32 srcLen = getOperand(1)->getLength();
  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,
                               tgtOp->getNullBitIndex(),
                               tgtOp->getTupleFormat());
  }
  else
  {
    ExpTupleDesc::clearNullValue(tgtNull,
                                 tgtOp->getNullBitIndex(),
                                 tgtOp->getTupleFormat());
  }
  
  return ex_expr::EXPR_OK;
}
//
// NVL(e1, e2) returns e2 if e1 is NULL otherwise e1. NVL(e1, e2) is
// equivalent to ANSI/ISO
//      COALESCE(e1, e2)
//        or,
//      CASE WHEN e1 IS NULL THEN e2 ELSE e1 END
// Both arguments can be nullable and actually null; they both can
// be constants as well.
// NVL() on CHAR type expressions is mapped to CASE. ISNULL(e1, e2) is
// mapped into NVL(e1, e2)
// Datatypes of e1 and e2 must be comparable/compatible.
//
ex_expr::exp_return_type ex_function_nvl::eval(char *op_data[],
					       CollHeap *heap,
					       ComDiagsArea** diagsArea)
{

  // Common index into op_data[] to access Null Indicators
  Int32 opNullIdx = -2 * MAX_OPERANDS;

  Attributes *tgtOp = getOperand(0);
  Attributes *arg1 = getOperand(1);
  Attributes *arg2 = getOperand(2);
  char * tgt = op_data[0];
  char * tgtNull = op_data[opNullIdx];
  char * src;
  UInt32 srcLen;
  NABoolean resultIsNull = TRUE;

  // As of today, NVL() on CHAR types becomes CASE. So make sure we are
  // not dealing with any CHAR types
  assert(!DFS2REC::isAnyCharacter(arg1->getDatatype()) &&
        !DFS2REC::isAnyCharacter(arg2->getDatatype()));
  
  // Locate the operand that is not null: if both are null
  // resultIsNull will still be TRUE and we will just set the
  // NULL flag of the result. If any operand is NOT NULL we copy
  // that value into result and clear NULL flag of the result.

  if (!arg1->getNullFlag() || op_data[opNullIdx + 1])
  {
    // First operand is either NOT NULLABLE or NON NULL Value.
    // This is the result.

    src = op_data[1];
    srcLen = arg1->getLength();
    resultIsNull = FALSE;
  }
  else
  {
    // Second operand could be the result, if it is not null.
    src = op_data[2];
    srcLen = arg2->getLength();

    // Second operand is either NOT NULLABLE or NON NULL Value.
    // This is the result.
     if (!arg2->getNullFlag() || op_data[opNullIdx + 2])
       resultIsNull = FALSE;
  }

  if (resultIsNull)
  {
  	// Result must be nullable
    assert(tgtOp->getNullFlag());
    ExpTupleDesc::setNullValue(tgtNull,
                               tgtOp->getNullBitIndex(),
                               tgtOp->getTupleFormat());
  }
  else
  {
    // clear nullflag of result if it is nullable
    if (tgtOp->getNullFlag())
      ExpTupleDesc::clearNullValue(tgtNull,
                               tgtOp->getNullBitIndex(),
                               tgtOp->getTupleFormat());
  }

  // Copy src to result: this could be NULL
  assert((UInt32)(tgtOp->getLength()) >= srcLen);
  str_cpy_all(tgt, src, srcLen);

  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ex_function_json_object_field_text::eval(char *op_data[],
					       CollHeap *heap,
					       ComDiagsArea** diagsArea)
{
    CharInfo::CharSet cs = ((SimpleType *)getOperand(1))->getCharSet();
    // search for operand 1
    Lng32 len1 = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);
    if ( cs == CharInfo::UTF8 )
    {
        Int32 prec1 = ((SimpleType *)getOperand(1))->getPrecision();
        len1 = Attributes::trimFillerSpaces( op_data[1], prec1, len1, cs );
    }

    // in operand 2
    Lng32 len2 = getOperand(2)->getLength(op_data[-MAX_OPERANDS+2]);
    if ( cs == CharInfo::UTF8 )
    {
        Int32 prec2 = ((SimpleType *)getOperand(2))->getPrecision();
        len2 = Attributes::trimFillerSpaces( op_data[2], prec2, len2, cs );
    }

    char *rltStr = NULL;
    char jsonStr[len1+1];
    char jsonAttr[len2+1];
    strncpy(jsonStr, op_data[1], len1);
    jsonStr[len1] = '\0';
    strncpy(jsonAttr, op_data[2], len2);
    jsonAttr[len2] = '\0';
    JsonReturnType ret = json_extract_path_text(&rltStr, jsonStr, 1, jsonAttr);
    if (ret != JSON_OK)
    {
        ExRaiseJSONError(heap, diagsArea, ret);
        return ex_expr::EXPR_ERROR;
    }
    if (rltStr != NULL)
    {
        Lng32 rltLen = str_len(rltStr)+1;
        str_cpy_all(op_data[0], rltStr, rltLen);
        free(rltStr);

        // If result is a varchar, store the length of substring 
        // in the varlen indicator.
        if (getOperand(0)->getVCIndicatorLength() > 0)
            getOperand(0)->setVarLength(rltLen, op_data[-MAX_OPERANDS]);
    }
    else
        getOperand(0)->setVarLength(0, op_data[-MAX_OPERANDS]);

    return ex_expr::EXPR_OK;
}

//
// Clause used to clear header bytes for both disk formats
// SQLMX_FORMAT and SQLMX_ALIGNED_FORMAT.  The number of bytes to clear
// is different for both formats.
// This clause is only generated for insert expressions and update expressions
// (updates that are non-optimized since olt optimized updates do a strcpy
// of the old image and then update the specific columns).
ex_expr::exp_return_type ExHeaderClause::eval(char           *op_data[],
                                              CollHeap       *heap,
                                              ComDiagsArea  **diagsArea)
{
  char *tgtData     = op_data[0];
  Attributes *tgtOp = getOperand(0);

  // Clear the entire header (not the VOA area)
  str_pad( tgtData, (Int32)adminSz_, '\0' );

  if ( bitmapOffset_ > 0 )
    ((ExpAlignedFormat *)tgtData)->setBitmapOffset( bitmapOffset_ );

  // Can not use the tgt attributes offset value here since for the aligned
  // format this may not be the first fixed field since the fixed fields
  // are re-ordered.
  if ( isSQLMXAlignedFormat() )
    ((ExpAlignedFormat *)tgtData)->setFirstFixedOffset( firstFixedOffset_ );
  else
    ExpTupleDesc::setFirstFixedOffset( tgtData,
                                       firstFixedOffset_,
                                       tgtOp->getTupleFormat() );

  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ex_function_queryid_extract::eval(char *op_data[],
							   CollHeap *heap,
							   ComDiagsArea** diagsArea)
{
  Lng32 retcode = 0;

  char * qidStr  = op_data[1];
  char * attrStr = op_data[2];
  Lng32 qidLen  = getOperand(1)->getLength();
  Lng32 attrLen = getOperand(2)->getLength();
  
  Lng32 attr = -999;
  NABoolean isNumeric = FALSE;

  // remove trailing blanks from attrStr
  while (attrLen && attrStr[attrLen-1] == ' ')
    attrLen--;

  if (strncmp(attrStr, "SEGMENTNUM", attrLen) == 0)
    {
      attr = ComSqlId::SQLQUERYID_SEGMENTNUM;
      isNumeric = TRUE;
    }
  else if (strncmp(attrStr, "CPU", attrLen) == 0)
    {
      attr = ComSqlId::SQLQUERYID_CPUNUM;
      isNumeric = TRUE;
    }
  else if (strncmp(attrStr, "CPUNUM", attrLen) == 0)
    {
      attr = ComSqlId::SQLQUERYID_CPUNUM;
      isNumeric = TRUE;
    }
  else if (strncmp(attrStr, "PIN", attrLen) == 0)
    {
      attr = ComSqlId::SQLQUERYID_PIN;
      isNumeric = TRUE;
    }
  else if (strncmp(attrStr, "EXESTARTTIME", attrLen) == 0)
    {
      attr = ComSqlId::SQLQUERYID_EXESTARTTIME;
      isNumeric = TRUE;
    }
  else if (strncmp(attrStr, "SESSIONID", attrLen) == 0)
    {
      attr = ComSqlId::SQLQUERYID_SESSIONID;
    }
  else if (strncmp(attrStr, "SESSIONNUM", attrLen) == 0)
    {
      attr = ComSqlId::SQLQUERYID_SESSIONNUM;
      isNumeric = TRUE;
    }
  else if (strncmp(attrStr, "USERNAME", attrLen) == 0)
    {
      attr = ComSqlId::SQLQUERYID_USERNAME;
    }
  else if (strncmp(attrStr, "SESSIONNAME", attrLen) == 0)
    {
      attr = ComSqlId::SQLQUERYID_SESSIONNAME;
    }
  else if (strncmp(attrStr, "QUERYNUM", attrLen) == 0)
    {
      attr = ComSqlId::SQLQUERYID_QUERYNUM;
      isNumeric = TRUE;
    }
  else if (strncmp(attrStr, "STMTNAME", attrLen) == 0)
    {
      attr = ComSqlId::SQLQUERYID_STMTNAME;
    }

  Int64 value;
  if (!isNumeric)
	  value = 99;         // set max valueStr length
  char valueStr[100];
  retcode = ComSqlId::getSqlQueryIdAttr(
       attr, qidStr,  qidLen, value, valueStr);
  if (retcode < 0)
    {
      ExRaiseFunctionSqlError(heap, diagsArea, (ExeErrorCode)(-retcode),
			      derivedFunction(),
			      origFunctionOperType());
      return ex_expr::EXPR_ERROR;
    }

  char * valPtr;
  short datatype;
  Lng32 length;
  if (isNumeric)
    {
      valPtr = (char*)&value;
      datatype = REC_BIN64_SIGNED;
      length = 8;
    }
  else
    {
      valPtr = valueStr;
      datatype = REC_BYTE_V_ANSI;
      length = (Lng32)value + 1;          // include null terminator
    }

  if (convDoIt(valPtr, length, datatype, 0, 0,
	       op_data[0], 
	       getOperand(0)->getLength(),
	       getOperand(0)->getDatatype(),
	       getOperand(0)->getPrecision(),
	       getOperand(0)->getScale(),
	       op_data[-MAX_OPERANDS],
	       getOperand(0)->getVCIndicatorLength(),
	       heap, diagsArea))
    return ex_expr::EXPR_ERROR;
  
  return ex_expr::EXPR_OK;
}


ex_expr::exp_return_type ExFunctionUniqueId::eval(char *op_data[],
						  CollHeap *heap,
						  ComDiagsArea** diagsArea)
{
  Lng32 retcode = 0;

  char * result = op_data[0];
  if(getOperType() == ITM_UNIQUE_ID)
  {
    //it is hard to find a common header file for these length
    //so hardcode 36 here
    //if change, please check the SynthType.cpp for ITM_UNIQUE_ID part as well
    //libuuid is global unique, even across computer node
    //NOTE: libuuid is avialble on normal CentOS, other system like Ubuntu may need to check 
    //Trafodion only support RHEL and CentOS as for now
    char str[36 + 1];
    uuid_t uu;
    uuid_generate( uu ); 
    uuid_unparse(uu, str);
    str_cpy_all(result, str, 36);
  }
  else //at present , it must be ITM_UUID_SHORT_ID
  { 
    Int64 uniqueUID;

    ComUID comUID;
    comUID.make_UID();

#if defined( NA_LITTLE_ENDIAN )
    uniqueUID = reversebytes(comUID.get_value());
#else
    uniqueUID = comUID.get_value();
#endif

    //it is safe, since the result is allocated 21 bytes in this case from synthtype,
    //max in64 is 19 digits and one for sign, 21 is enough
    sprintf(result,"%lu",uniqueUID); 
  }
 
  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ExFunctionRowNum::eval(char *op_data[],
						  CollHeap *heap,
						  ComDiagsArea** diagsArea)
{
  char * result = op_data[0];

  Int64 rowNum = getExeGlobals()->rowNum();

  str_cpy_all(result, (char*)&rowNum, sizeof(Int64));
  str_pad(&result[sizeof(Int64)], sizeof(Int64), '\0');
  
  return ex_expr::EXPR_OK;
}

short ExFunctionHbaseColumnLookup::extractColFamilyAndName(
     const char * input, 
     short len,
     NABoolean isVarchar,
     std::string &colFam, std::string &colName)
{
  if (! input)
    return -1;

  Lng32 i = 0;
  Lng32 startPos = 0;
  if (isVarchar)
    {
      len = *(short*)input;
      startPos = sizeof(len);
    }
  else if (len == -1)
    {
      len = strlen(input);
      startPos = 0;
    }
  else
    {
      startPos = 0;
    }

  Lng32 j = 0;
  i = startPos;
  NABoolean colonFound = FALSE;
  while ((j < len) && (not colonFound))
    {
      if (input[i] != ':')
	{
	  i++;
	}
      else
	{
	  colonFound = TRUE;
	}

      j++;
    }
  
  if (colonFound) // ":" found
    {
      colFam.assign(&input[startPos], i - startPos);
  
      i++;
      if (i  < (startPos + len))
	{
	  colName.assign(&input[i], (startPos + len) - i);
	}
    }
  else
    {
      colName.assign(&input[startPos], i - startPos);
    }

  return 0;
}

ex_expr::exp_return_type 
ExFunctionHbaseColumnLookup::eval(char *op_data[], CollHeap *heap, 
				  ComDiagsArea **diagsArea)
{
  // op_data[0] points to result. The result is a varchar.
  Attributes *resultAttr   = getOperand(0);
  Attributes *colDetailAttr   = getOperand(1);
  
  char * resultStart = op_data[0];
  char * resultNull = op_data[-2 * MAX_OPERANDS];

  char * result = resultStart;
  char * colDetail = op_data[1];

  Lng32 sourceLen = 0;
  if (colDetailAttr->getVCIndicatorLength() == sizeof(Lng32))
    str_cpy_all((char*)&sourceLen, op_data[-MAX_OPERANDS+1], sizeof(Lng32));
  else
    {
      short tempLen = 0;
      str_cpy_all((char*)&tempLen, op_data[-MAX_OPERANDS+1], sizeof(short));
      sourceLen = tempLen;
    }

  char * pos = colDetail;
  NABoolean done = FALSE;
  NABoolean colFound = FALSE;
  while (NOT done)
    {
      short colNameLen = 0;
      Lng32 colValueLen = 0;

      memcpy((char*)&colNameLen, pos, sizeof(short));
      pos += sizeof(short);

      if ((colNameLen == strlen(colName_)) &&
	   (str_cmp(colName_, pos, colNameLen) == 0))
	{
	  pos += colNameLen;
	  
	  memcpy((char*)&colValueLen, pos, sizeof(Lng32));
	  pos  += sizeof(Lng32);

	  NABoolean charType = DFS2REC::isAnyCharacter(resultAttr->getDatatype());
	  if (! charType)
	    {
	      // lengths must match for non-char types
	      if (colValueLen != resultAttr->getLength())
		continue;
	    }

	  UInt32 flags = 0;
	  
	  ex_expr::exp_return_type rc = 
	    convDoIt(pos,
		     colValueLen,
		     (charType ? REC_BYTE_F_ASCII : resultAttr->getDatatype()),
		     (charType ? 0 : resultAttr->getPrecision()),
		     (charType ? 0 : resultAttr->getScale()),
		     result,
		     resultAttr->getLength(),
		     resultAttr->getDatatype(),
		     resultAttr->getPrecision(),
		     resultAttr->getScale(),
		     NULL,
		     0,
		     heap,
		     diagsArea);
	  if ((rc != ex_expr::EXPR_OK) ||
	      ((diagsArea) && (*diagsArea) && ((*diagsArea)->getNumber(DgSqlCode::WARNING_)) > 0))
	    {

	      if (rc == ex_expr::EXPR_OK)
		{
		  (*diagsArea)->negateAllWarnings();
		}

	      return ex_expr::EXPR_ERROR;
	    }

	  getOperand(0)->setVarLength(colValueLen, op_data[-MAX_OPERANDS]);

	  colFound = TRUE;

	  done = TRUE;
	}
      else
	{
	  pos += colNameLen;

	  memcpy((char*)&colValueLen, pos, sizeof(Lng32));
	  pos  += sizeof(Lng32);
	  
	  pos += colValueLen;
	  
	  if (pos >= (colDetail + sourceLen))
	    {
	      done = TRUE;
	    }
	}
    } // while

  if (NOT colFound)
    {
      // move null value to result
      ExpTupleDesc::setNullValue(resultNull,
				  resultAttr->getNullBitIndex(),
				  resultAttr->getTupleFormat() );
    }
  else
    {
      ExpTupleDesc::clearNullValue(resultNull,
				  resultAttr->getNullBitIndex(),
				  resultAttr->getTupleFormat() );
    }

  return ex_expr::EXPR_OK;
}

NABoolean ExFunctionHbaseColumnsDisplay::toBeDisplayed(
						       char * colName, Lng32 colNameLen)
{
  if ((! colNames()) || (numCols_ == 0))
    return TRUE;

  char * currColName = colNames();
  for (Lng32 i = 0; i < numCols_; i++)
    {
      short currColNameLen = *(short*)currColName;
      currColName += sizeof(short);
      if ((colNameLen == currColNameLen) &&
	  (memcmp(colName, currColName, colNameLen) == 0))
	return TRUE;

      currColName  += currColNameLen;
    }

  return FALSE;
}

ex_expr::exp_return_type 
ExFunctionHbaseColumnsDisplay::eval(char *op_data[], CollHeap *heap, 
				    ComDiagsArea **diagsArea)
{
  // op_data[0] points to result. The result is a varchar.
  Attributes *resultAttr   = getOperand(0);
  Attributes *colDetailAttr   = getOperand(1);
  
  char * resultStart = op_data[0];
  char * result = resultStart;
  char * colDetail = op_data[1];

  Lng32 sourceLen = 0;
  if (colDetailAttr->getVCIndicatorLength() == sizeof(Lng32))
    str_cpy_all((char*)&sourceLen, op_data[-MAX_OPERANDS+1], sizeof(Lng32));
  else
    {
      short tempLen = 0;
      str_cpy_all((char*)&tempLen, op_data[-MAX_OPERANDS+1], sizeof(short));
      sourceLen = tempLen;
    }

  char * pos = colDetail;
  NABoolean done = FALSE;

  while (NOT done)
    {
      short colNameLen = 0;
      Lng32 colValueLen = 0;

      memcpy((char*)&colNameLen, pos, sizeof(short));
      pos += sizeof(short);
      memcpy(result, pos, colNameLen);
      pos += colNameLen;

      // if this col name need to be returned, then return it.
      if (NOT toBeDisplayed(result, colNameLen))
	{
	  goto label_continue;
	}

      result += colNameLen;

      memcpy(result, " => ", strlen(" => "));
      result += strlen(" => ");

      memcpy((char*)&colValueLen, pos, sizeof(Lng32));
      pos  += sizeof(Lng32);
      memcpy(result, pos, colValueLen);
      result += colValueLen;
      pos += colValueLen;

      if (pos < (colDetail + sourceLen))
	{
	  memcpy(result, ", ", strlen(", "));
	  result += strlen(", ");
	}

    label_continue:
      if (pos >= (colDetail + sourceLen))
	{
	  done = TRUE;
	}
    }

  // store the row length in the varlen indicator.
  getOperand(0)->setVarLength((result-resultStart), op_data[-MAX_OPERANDS]);

  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type 
ExFunctionHbaseColumnCreate::eval(char *op_data[], CollHeap *heap, 
				  ComDiagsArea **diagsArea)
{
  // op_data[0] points to result. The result is a varchar.
  // Values in result have already been populated by clauses evaluated
  // before this clause is reached.
  Attributes *resultAttr   = getOperand(0);
  char * resultStart = op_data[0];
  char * result = resultStart;
  
  str_cpy_all(result, (char*)&numEntries_, sizeof(numEntries_));
  result += sizeof(short);

  str_cpy_all(result, (char*)&colNameMaxLen_, sizeof(colNameMaxLen_));
  result += sizeof(short);

  str_cpy_all(result, (char*)&colValVCIndLen_, sizeof(colValVCIndLen_));
  result += sizeof(short);
  
  str_cpy_all(result, (char*)&colValMaxLen_, sizeof(colValMaxLen_));
  result += sizeof(Int32);

  for (Lng32 i = 0; i < numEntries_; i++)
    {
      // validate that column name is of right format:   colfam:colname
      std::string colFam;
      std::string colNam;
      ExFunctionHbaseColumnLookup::extractColFamilyAndName(
                                                           result, -1, TRUE/*isVarchar*/, colFam, colNam);
      if (colFam.empty())
        {
          short colNameLen;
          str_cpy_all((char*)&colNameLen, result, sizeof(short));
          result += sizeof(short);
          std::string colNamData(result, colNameLen);
          ExRaiseSqlError(heap, diagsArea, (ExeErrorCode)1426, NULL, NULL, NULL, NULL,
                          colNamData.data());
          return ex_expr::EXPR_ERROR;
        }

      result += sizeof(short);
      result += ROUND2(colNameMaxLen_);

      // skip the nullable bytes
      result += sizeof(short);

      if (colValVCIndLen_ == sizeof(short))
        result += sizeof(short);
      else
        {
          result = (char*)ROUND4((Int64)result);
          result += sizeof(Lng32);
        }
      result += ROUND2(colValMaxLen_);
    }  

  resultAttr->setVarLength(result - resultStart, op_data[-MAX_OPERANDS]);

  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type 
ExFunctionCastType::eval(char *op_data[], CollHeap *heap, 
			 ComDiagsArea **diagsArea)
{
  // op_data[0] points to result. 
  Attributes *resultAttr   = getOperand(0);
  Attributes *srcAttr   = getOperand(1);
  
  char * resultData = op_data[0];
  char * srcData = op_data[1];

  Lng32 sourceLen = srcAttr->getLength(op_data[-MAX_OPERANDS+1]);
  Lng32 resultLen = resultAttr->getLength();

  if (sourceLen < resultLen)
    {
      ExRaiseFunctionSqlError(heap, diagsArea, EXE_STRING_OVERFLOW,
			      derivedFunction(),
			      origFunctionOperType());
      return ex_expr::EXPR_ERROR;
    }

  str_cpy_all(resultData, srcData, resultLen);
  getOperand(0)->setVarLength(resultLen, op_data[-MAX_OPERANDS]);

  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type 
ExFunctionSequenceValue::eval(char *op_data[], CollHeap *heap, 
			      ComDiagsArea **diagsArea)
{
  short rc = 0;

  // op_data[0] points to result. The result is a varchar.
  Attributes *resultAttr   = getOperand(0);
  char * result =  op_data[0];

  SequenceValueGenerator * seqValGen = getExeGlobals()->seqGen();
  Int64 seqVal = 0;
  if (isCurr())
    rc = seqValGen->getCurrSeqVal(sga_, seqVal);
  else
    rc = seqValGen->getNextSeqVal(sga_, seqVal);
  if (rc)
    {
      ExRaiseSqlError(heap, diagsArea, (ExeErrorCode)ABS(rc));
      return ex_expr::EXPR_ERROR;
    }

  *(Int64*)result = seqVal;

  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type 
ExFunctionHbaseTimestamp::eval(char *op_data[], CollHeap *heap, 
                               ComDiagsArea **diagsArea)
{
  short rc = 0;

  // op_data[0] points to result. 
  Attributes *resultAttr   = getOperand(0);
  char * result =  op_data[0];

  Int64 * hbaseTS = (Int64*)op_data[1];

  *(Int64*)result = hbaseTS[colIndex_];

  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type 
ExFunctionHbaseVersion::eval(char *op_data[], CollHeap *heap, 
                               ComDiagsArea **diagsArea)
{
  short rc = 0;

  // op_data[0] points to result. 
  Attributes *resultAttr   = getOperand(0);
  char * result =  op_data[0];

  Int64 * hbaseVersion = (Int64*)op_data[1];

  *(Int64*)result = hbaseVersion[colIndex_];

  return ex_expr::EXPR_OK;
}

////////////////////////////////////////////////////////////////////
//
// decodeKeyValue
//
// This routine decodes an encoded key value.
//
// Note: The target MAY point to the source to change the original
//       value.  
//
////////////////////////////////////////////////////////////////////
short ex_function_encode::decodeKeyValue(Attributes * attr,
					 NABoolean isDesc,
					 char *inSource,
					 char *varlen_ptr,
					 char *target,
                                         char *target_varlen_ptr,
					 NABoolean handleNullability
					 )
{
  Lng32 fsDatatype = attr->getDatatype();
  Lng32 length = attr->getLength();
  Lng32 precision = attr->getPrecision();

  Lng32 encodedKeyLen = length;
  if ((handleNullability) &&
      (attr->getNullFlag()))
    encodedKeyLen += attr->getNullIndicatorLength();

  char * source = inSource;
  if (isDesc)
    {
      // compliment all bytes
      for (Lng32 k = 0; k < encodedKeyLen; k++)
	target[k] = ~(source[k]);
      
      source = target;
    }
  
  if ((handleNullability) &&
      (attr->getNullFlag()))
    {
      if (target != source)
        str_cpy_all(target, source, attr->getNullIndicatorLength());

      source += attr->getNullIndicatorLength();
      target += attr->getNullIndicatorLength();
    }

  switch (fsDatatype) {
#if defined( NA_LITTLE_ENDIAN )
  case REC_BIN8_SIGNED:
    //
    // Flip the sign bit.
    //
    *(UInt8*)target = *(UInt8*)source;
    target[0] ^= 0200;
    break;

  case REC_BIN8_UNSIGNED:
  case REC_BOOLEAN:
    *(UInt8*)target = *(UInt8*)source;
    break;

  case REC_BIN16_SIGNED:
    //
    // Flip the sign bit.
    //
    *((unsigned short *) target) = reversebytes( *((unsigned short *) source) );
    target[sizeof(short)-1] ^= 0200;
    break;

  case REC_BPINT_UNSIGNED:
  case REC_BIN16_UNSIGNED:
    *((unsigned short *) target) = reversebytes( *((unsigned short *) source) );
    break;

  case REC_BIN32_SIGNED:
    //
    // Flip the sign bit.
    //
    *((ULng32 *) target) = reversebytes( *((ULng32 *) source) );
    target[sizeof(Lng32)-1] ^= 0200;
    break;

  case REC_BIN32_UNSIGNED:
    *((ULng32 *) target) = reversebytes( *((ULng32 *) source) );
    break;

  case REC_BIN64_SIGNED:
    //
    // Flip the sign bit.
    //
    *((_int64 *) target) = reversebytes( *((_int64 *) source) );
    target[sizeof(_int64)-1] ^= 0200;
    break;

  case REC_BIN64_UNSIGNED:
    *((UInt64 *) target) = reversebytes( *((UInt64 *) source) );
    break;

  case REC_INT_YEAR:
  case REC_INT_MONTH:
  case REC_INT_YEAR_MONTH:
  case REC_INT_DAY:
  case REC_INT_HOUR:
  case REC_INT_DAY_HOUR:
  case REC_INT_MINUTE:
  case REC_INT_HOUR_MINUTE:
  case REC_INT_DAY_MINUTE:
  case REC_INT_SECOND:
  case REC_INT_MINUTE_SECOND:
  case REC_INT_HOUR_SECOND:
  case REC_INT_DAY_SECOND:
    switch(length)
      {
      case 2:	 // Signed 16 bit
	*((unsigned short *) target) = reversebytes( *((unsigned short *) source) );
	target[SQL_SMALL_SIZE-1] ^= 0200;
	break;
      case 4:  // Signed 32 bit
	*((ULng32 *) target) = reversebytes( *((ULng32 *) source) );
	target[SQL_INT_SIZE-1] ^= 0200;
	break;
      case 8:  // Signed 64 bit
	*((_int64 *) target) = reversebytes( *((_int64 *) source) );
	target[SQL_LARGE_SIZE-1] ^= 0200;
	break;
      default:
	assert(FALSE);
	break;
      };  // switch(length)
    break;
  case REC_DATETIME: {
    // This method has been modified as part of the MP Datetime
    // Compatibility project.  It has been made more generic so that
    // it depends only on the start and end fields of the datetime type.
    //
    rec_datetime_field startField;
    rec_datetime_field endField;

    ExpDatetime *dtAttr = (ExpDatetime *)attr;

    // Get the start and end fields for this Datetime type.
    //
    dtAttr->getDatetimeFields(dtAttr->getPrecision(),
                              startField,
                              endField);

    // Copy all of the source to the destination, then reverse only
    // those fields of the target that are longer than 1 byte
    //
    if (target != source)
      str_cpy_all(target, source, length);
    
    // Reverse the YEAR and Fractional precision fields if present.
    //
    char *ptr = target;
    for(Int32 field = startField; field <= endField; field++) {
      switch (field) {
      case REC_DATE_YEAR:
        // convert YYYY from little endian to big endian
        //
        *((unsigned short *) ptr) = reversebytes( *((unsigned short *) ptr) );
        ptr += sizeof(short);
        break;
      case REC_DATE_MONTH:
      case REC_DATE_DAY:
      case REC_DATE_HOUR:
      case REC_DATE_MINUTE:
        // One byte fields are copied as is...
        ptr++;
        break;
      case REC_DATE_SECOND:
        ptr++;

        // if there is a fraction, make it big endian 
        // (it is an unsigned long, beginning after the SECOND field)
        //
        if (dtAttr->getScale() > 0)
          *((ULng32 *) ptr) = reversebytes( *((ULng32 *) ptr) );
        break;

      }
    }
    break;
  }
#else
  case REC_BIN8_SIGNED:
  case REC_BIN16_SIGNED:
  case REC_BIN32_SIGNED:
  case REC_BIN64_SIGNED:
  case REC_INT_YEAR:
  case REC_INT_MONTH:
  case REC_INT_YEAR_MONTH:
  case REC_INT_DAY:
  case REC_INT_HOUR:
  case REC_INT_DAY_HOUR:
  case REC_INT_MINUTE:
  case REC_INT_HOUR_MINUTE:
  case REC_INT_DAY_MINUTE:
  case REC_INT_SECOND:
  case REC_INT_MINUTE_SECOND:
  case REC_INT_HOUR_SECOND:
  case REC_INT_DAY_SECOND:
    //
    // Flip the sign bit.
    //
    if (target != source)
      str_cpy_all(target, source, length);
    target[0] ^= 0200;
    break;
#endif
  case REC_DECIMAL_LSE:
    //
    // If the number was negative, complement all the bytes.  Otherwise, set
    // the sign bit.
    //
    if (NOT(source[0] & 0200)) {
      for (Lng32 i = 0; i < length; i++)
        target[i] = ~source[i];
    } else {
      if (target != source)
        str_cpy_all(target, source, length);
      target[0] &= ~0200;
    }
    break;
  case REC_NUM_BIG_SIGNED:
  case REC_NUM_BIG_UNSIGNED: {
    BigNum type(length, precision, 0, 0);
    type.decode(source, target);
    break;
  }
  case REC_IEEE_FLOAT32: {
    //
    // Encoded float (IEEE 754 - 1985 standard):
    //
    // +-+--------+-----------------------+
    // | |Exponent| Mantissa              |
    // | |(8 bits)| (23 bits)             |
    // +-+--------+-----------------------+
    //  ||                                |
    //  |+- Complemented if sign was neg.-+
    //  |
    //  +- Sign bit complement
    //
    // unencoded float (IEEE 754 - 1985 standard):
    //
    // +-+----------+---------------------+
    // | | exponent |  mantissa           |
    // | | (8 bits) |  (23 bits)          |
    // +-+----------+---------------------+
    //  |
    //  +- Sign bit
    //

    // the following code is independent of the "endianess" of the
    // archtiecture. Instead, it assumes IEEE 754 - 1985 standard
    // for representation of floats
    if (source[0] & 0200)
      {
	// sign bit is on. Indicates this was a positive number.
	// Copy to target and clear the sign bit.
	if (target != source)
	  str_cpy_all(target, source, length);
	target[0] &= 0177;
      }
    else
      {
	// this was a negative number.
	// flip all bits.
	for (Lng32 i = 0; i < length; i++)
	  target[i] = ~source[i];
      }

    // here comes the dependent part
#ifdef NA_LITTLE_ENDIAN
    *(ULng32 *) target = reversebytes(*(ULng32 *)target);
#endif
    break;
  }
  case REC_IEEE_FLOAT64: {
    //
    // Encoded double (IEEE 754 - 1985 standard):
    //
    // +-+-----------+--------------------+
    // | | Exponent  | Mantissa           |
    // | | (11 bits) | (52 bits)          |
    // +-+-----------+--------------------+
    //  ||                                |
    //  |+- Complemented if sign was neg.-+
    //  |
    //  +- Sign bit complement
    //
    // unencoded double (IEEE 754 - 1985 standard):
    //
    // +-+--------- -+--------------------+
    // | | exponent  |  mantissa          |
    // | | (11 bits) |  (52 bits)         |
    // +-+--------- -+--------------------+
    //  |
    //  +- Sign bit
    //

    // the following code is independent of the "endianess" of the
    // archtiecture. Instead, it assumes IEEE 754 - 1985 standard
    // for representation of floats
    if (source[0] & 0200)
      {
	// sign bit is on. Indicates this was a positive number.
	// Copy to target and clear the sign bit.
	if (target != source)
	  str_cpy_all(target, source, length);
	target[0] &= 0177;
      }
    else
      {
	// this was a negative number.
	// flip all bits.
	for (Lng32 i = 0; i < length; i++)
	  target[i] = ~source[i];
      }

    // here comes the dependent part
#ifdef NA_LITTLE_ENDIAN
    *(Int64 *) target = reversebytes(*(Int64 *)target);
#endif

    break;
  }
  case REC_BYTE_V_ASCII: 
  case REC_BYTE_V_ASCII_LONG: {
    //
    // Copy the source to the target.
    //
    short vc_len;
    // See bug LP 1444134, make this compatible with encoding for
    // varchars and remove the VC indicator
    assert(attr->getVCIndicatorLength() == sizeof(vc_len));
    str_cpy_all((char *) &vc_len, varlen_ptr, attr->getVCIndicatorLength());
    
    if (target != source)
      str_cpy_all(target, source, vc_len);
    //
    // Blankpad the target (if needed).
    //
    if (vc_len < length)
      str_pad(&target[vc_len], (Int32) (length - vc_len), ' ');
    //
    // Make the length bytes to be the maximum length for this field.  This
    // will make all encoded varchar keys to have the same length and so the
    // comparison will depend on the fixed part of the varchar buffer.
    //
    vc_len = (short) length;
    if (target_varlen_ptr)
      str_cpy_all(target_varlen_ptr, (char *) &vc_len, attr->getVCIndicatorLength());
    break;
  }

  case REC_NCHAR_V_UNICODE: 
  {
    //
    // Copy the source to the target.
    //
    // See bug LP 1444134, make this compatible with encoding for
    // varchars and remove the VC indicator
    short vc_len;
    assert(attr->getVCIndicatorLength() == sizeof(vc_len));
    str_cpy_all((char *) &vc_len, varlen_ptr, attr->getVCIndicatorLength());
    
    if (target != source)
      str_cpy_all(target, source, vc_len);
    //
    // Blankpad the target (if needed).
    //
    if (vc_len < length)
      wc_str_pad((NAWchar*)&target[attr->getVCIndicatorLength() + vc_len],
	      (Int32) (length - vc_len)/sizeof(NAWchar), unicode_char_set::space_char());

#if defined( NA_LITTLE_ENDIAN )
      wc_swap_bytes((NAWchar*)&target[attr->getVCIndicatorLength()], length/sizeof(NAWchar));
#endif
    //
    // Make the length bytes to be the maximum length for this field.  This
    // will make all encoded varchar keys to have the same length and so the
    // comparison will depend on the fixed part of the varchar buffer.
    //
    vc_len = (short) length;
    if (target_varlen_ptr)
      str_cpy_all(target_varlen_ptr, (char *) &vc_len, attr->getVCIndicatorLength());
    break;
  }

  case REC_NCHAR_F_UNICODE: 
  {

    if (target != source)
      str_cpy_all(target, source, length);

#if defined( NA_LITTLE_ENDIAN )
      wc_swap_bytes((NAWchar*)target, length/sizeof(NAWchar));
#endif

    break;
  }
  default:
    //
    // Decoding is not needed.  Just copy the source to the target.
    //
    if (target != source)
      str_cpy_all(target, source, length);
    break;
  }

  return 0;
}

static Lng32 convAsciiLength(Attributes * attr)
{
  Lng32 d_len = 0;
  Int32 scale_len = 0;

  Lng32 datatype = attr->getDatatype();
  Lng32 length = attr->getLength();
  Lng32 precision = attr->getPrecision();
  Lng32 scale = attr->getScale();

  if (scale > 0)
    scale_len = 1;
  
  switch (datatype)
    {
    case REC_BPINT_UNSIGNED: 
      // Can set the display size based on precision. For now treat it as
      // unsigned smallint
      d_len = SQL_USMALL_DISPLAY_SIZE;
      break;

    case REC_BIN16_SIGNED:
      d_len = SQL_SMALL_DISPLAY_SIZE + scale_len;
      break;

    case REC_BIN16_UNSIGNED:
      d_len = SQL_USMALL_DISPLAY_SIZE + scale_len;
      break;

    case REC_BIN32_SIGNED:
      d_len = SQL_INT_DISPLAY_SIZE + scale_len;
      break;

    case REC_BIN32_UNSIGNED:
      d_len = SQL_UINT_DISPLAY_SIZE + scale_len;
      break;

    case REC_BIN64_SIGNED:
      d_len = SQL_LARGE_DISPLAY_SIZE + scale_len;
      break;

    case REC_BIN64_UNSIGNED:
      d_len = SQL_ULARGE_DISPLAY_SIZE + scale_len;
      break;

   case REC_NUM_BIG_UNSIGNED:
   case REC_NUM_BIG_SIGNED:
      d_len = precision + 1 + scale_len; // Precision + sign + decimal point
      break;
       
    case REC_BYTE_F_ASCII:
      d_len = length;
      break;

   case REC_NCHAR_F_UNICODE:
   case REC_NCHAR_V_UNICODE:
   case REC_BYTE_V_ASCII:
   case REC_BYTE_V_ASCII_LONG:
      d_len = length;
      break;

    case REC_DECIMAL_UNSIGNED:
      d_len = length + scale_len;
      break;
      
    case REC_DECIMAL_LSE:
      d_len = length + 1 + scale_len;
      break;
      
    case REC_FLOAT32:
      d_len = SQL_REAL_DISPLAY_SIZE;
      break;
      
    case REC_FLOAT64:
      d_len = SQL_DOUBLE_PRECISION_DISPLAY_SIZE;
      break;
      
    case REC_DATETIME:
      switch (precision) {
	// add different literals for sqldtcode_date...etc. These literals
	// are from sqlcli.h and cannot be included here in this file.
      case 1 /*SQLDTCODE_DATE*/:
	{
	  d_len = DATE_DISPLAY_SIZE;
	}
        break;
      case 2 /*SQLDTCODE_TIME*/:
	{
	  d_len = TIME_DISPLAY_SIZE + 
	    (scale > 0 ? (1 + scale) : 0);
	}
        break;
      case 3 /*SQLDTCODE_TIMESTAMP*/:
	{
	  d_len = TIMESTAMP_DISPLAY_SIZE +
	    (scale > 0 ? (1 + scale) : 0);
	}
        break;
      default:
        d_len = length;
        break;
      }
      break;

    case REC_INT_YEAR:
    case REC_INT_MONTH:
    case REC_INT_YEAR_MONTH:
    case REC_INT_DAY:
    case REC_INT_HOUR:
    case REC_INT_DAY_HOUR:
    case REC_INT_MINUTE:
    case REC_INT_HOUR_MINUTE:
    case REC_INT_DAY_MINUTE:
    case REC_INT_SECOND:
    case REC_INT_MINUTE_SECOND:
    case REC_INT_HOUR_SECOND:
    case REC_INT_DAY_SECOND: {
        rec_datetime_field startField;
        rec_datetime_field endField;
        ExpInterval::getIntervalStartField(datatype, startField);
        ExpInterval::getIntervalEndField(datatype, endField);

	// this code is copied from IntervalType::getStringSize in
	// w:/common/IntervalType.cpp
	d_len = 1 + 1 +
	  precision +
	  3/*IntervalFieldStringSize*/ * (endField - startField);
	if (scale)
	  d_len += scale + 1; // 1 for "."
      }
      break;

    default:
      d_len = length;
      break;
    }
  
  return d_len;
}

//helper function, convert a string into IPV4 , if valid, it can support leading and padding space
static Lng32 string2ipv4(char *srcData, Lng32 slen, unsigned int *inet_addr)
{
   Int16 i = 0, j = 0 , p=0, leadingspace=0;
   char buf[16]; 
   Int16 dot=0;

   if(slen < MIN_IPV4_STRING_LEN ) 
     return 0;

   unsigned char *ipv4_bytes= (unsigned char *)inet_addr;

   if(srcData[0] == ' ')
   { 
     char * next = srcData;
     while (*next == ' ')
     {
       leadingspace++;
       next++;
     }
   }
   
      
   for(i=leadingspace , j = 0; i < slen ; i++)
   {
      if(srcData[i] == '.')
      {
         buf[j]=0;
         p = str_atoi(buf, j);
         if( p < 0 || p > 255 || j == 0) 
         {
           return 0;
         }
         else
         {
           if(ipv4_bytes)
             ipv4_bytes[dot] = (unsigned char)p;
         }
         j = 0;
         dot++;
         if(dot > 3) return 0;
      }
      else if(srcData[i] == ' ')
      {
        break; //space is terminator
      }
      else
      {
        if(isdigit(srcData[i]) == 0) 
         {
           return 0;
         }
        else
         buf[j] = srcData[i];
        j++;
      }
   } 
   Int16 stoppos=i;

   // the last part
   buf[j]=0;  //null terminator

   for(i = 0; i < j; i ++) //check for invalid character
   {
     if(isdigit(buf[i]) == 0)
     {
       return 0;
     }
   }
   p = str_atoi(buf, j);
   if( p < 0 || p > 255 || j == 0) // check for invalid number
   {
     return 0;
   }
   else
   {
     if(ipv4_bytes)
       ipv4_bytes[dot] = (unsigned char)p;
   }

   //if terminated by space
   if( stoppos < slen -1)
   {
     for(j = stoppos ; j < slen; j++)
     {
       if(srcData[j] != ' ') return 0;
     }
   }

   if(dot != 3) 
     return 0;
   else
     return 1;
  
}

ex_expr::exp_return_type ExFunctionInetAton::eval(char * op_data[],
                                                        CollHeap *heap,
                                                        ComDiagsArea **diags)
{
   char * srcData = op_data[1];
   char * resultData = op_data[0];

  Attributes *resultAttr   = getOperand(0);
  Attributes *srcAttr   = getOperand(1);

  Lng32 slen = srcAttr->getLength(op_data[-MAX_OPERANDS+1]);
  Lng32 rlen = resultAttr->getLength();

  unsigned int addr;
  int ret=string2ipv4(srcData, slen, &addr);
  if(ret)
  {
       *(unsigned int *)op_data[0]=addr;
       return ex_expr::EXPR_OK;
  } 
  else
  {
      ExRaiseSqlError(heap, diags, EXE_INVALID_CHARACTER);
      *(*diags) << DgString0("IP format") << DgString1("INET_ATON FUNCTION"); 
      return ex_expr::EXPR_ERROR;
  }
}


ex_expr::exp_return_type ExFunctionInetNtoa::eval(char * op_data[],
                                                        CollHeap *heap,
                                                        ComDiagsArea **diags)
{
   char buf[16]; //big enough
   unsigned long addr =  *(unsigned long*)op_data[1];
   char * resultData = op_data[0];
   Attributes *resultAttr = getOperand(0);
   const unsigned char *ipv4_bytes= (const unsigned char *) &addr;

   if( addr > 4294967295 ) 
   {
      ExRaiseSqlError(heap, diags, EXE_BAD_ARG_TO_MATH_FUNC);
      *(*diags) << DgString0("INET_NTOA"); 
      return ex_expr::EXPR_ERROR;
   }

   str_sprintf(buf, "%d.%d.%d.%d",
          ipv4_bytes[0], ipv4_bytes[1], ipv4_bytes[2], ipv4_bytes[3]);
   int slen = str_len(buf);
   str_cpy_all(resultData, buf, slen);
   getOperand(0)->setVarLength(slen, op_data[-MAX_OPERANDS]);

   return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ExFunctionCrc32::eval(char * op_data[],
                                                        CollHeap *heap,
                                                        ComDiagsArea **diags)
{
  Attributes *resultAttr   = getOperand(0);
  Attributes *srcAttr   = getOperand(1);

  Lng32 slen = srcAttr->getLength(op_data[-MAX_OPERANDS+1]);
  Lng32 rlen = resultAttr->getLength();

  *(ULng32*)op_data[0] = 0; 
  ULng32 crc = crc32(0L, Z_NULL, 0);
  crc = crc32 (crc, (const Bytef*)op_data[1], slen);
  *(ULng32*)op_data[0] = crc; 
  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ExFunctionSha2::eval(char * op_data[],
                                                        CollHeap *heap,
                                                        ComDiagsArea **diags)
{

  unsigned char sha[SHA512_DIGEST_LENGTH + 1] = {0};

  Attributes *resultAttr   = getOperand(0);
  Attributes *srcAttr   = getOperand(1);

  Lng32 slen = srcAttr->getLength(op_data[-MAX_OPERANDS+1]);

  // the length of result
  Lng32 rlen = SHA512_DIGEST_LENGTH;

  switch (mode) {
    case 0:
    case 256:
      SHA256_CTX sha_ctx_256;
      if (!SHA256_Init(&sha_ctx_256))
        goto sha2_error;
      if (!SHA256_Update(&sha_ctx_256, op_data[1], slen))
        goto sha2_error;
      if (!SHA256_Final((unsigned char *)sha, &sha_ctx_256))
        goto sha2_error;

      rlen = SHA256_DIGEST_LENGTH;
      break;

    case 224:
      SHA256_CTX sha_ctx_224;

      if (!SHA224_Init(&sha_ctx_224))
        goto sha2_error;
      if (!SHA224_Update(&sha_ctx_224, op_data[1], slen))
        goto sha2_error;
      if (!SHA224_Final((unsigned char *)sha, &sha_ctx_224))
        goto sha2_error;

      rlen = SHA224_DIGEST_LENGTH;
      break;

    case 384:
      SHA512_CTX sha_ctx_384;
      if (!SHA384_Init(&sha_ctx_384))
        goto sha2_error;
      if (!SHA384_Update(&sha_ctx_384, op_data[1], slen))
        goto sha2_error;
      if (!SHA384_Final((unsigned char *)sha, &sha_ctx_384))
        goto sha2_error;

      rlen = SHA384_DIGEST_LENGTH;
      break;

    case 512:
      SHA512_CTX sha_ctx_512;
      if (!SHA512_Init(&sha_ctx_512))
        goto sha2_error;
      if (!SHA512_Update(&sha_ctx_512, op_data[1], slen))
        goto sha2_error;
      if (!SHA512_Final((unsigned char *)sha, &sha_ctx_512))
        goto sha2_error;

      rlen = SHA512_DIGEST_LENGTH;
      break;

    default:
      ExRaiseSqlError(heap, diags, EXE_BAD_ARG_TO_MATH_FUNC);
      *(*diags) << DgString0("SHA2");
      return ex_expr::EXPR_ERROR;
  }
  str_pad(op_data[0], rlen, ' ');

  char tmp[3];
  for(int i=0; i < rlen; i++ )
  {
    tmp[0]=tmp[1]=tmp[2]='0';
    sprintf(tmp, "%.2x", (int)sha[i]);
    str_cpy_all(op_data[0]+i*2, tmp, 2);
  }

  return ex_expr::EXPR_OK;
sha2_error:
  ExRaiseFunctionSqlError(heap, diags, EXE_INTERNAL_ERROR,
                          derivedFunction(),
                          origFunctionOperType());
  return ex_expr::EXPR_ERROR;
}

ex_expr::exp_return_type ExFunctionSha::eval(char * op_data[],
                                                        CollHeap *heap,
                                                        ComDiagsArea **diags)
{

  unsigned char sha[SHA_DIGEST_LENGTH + 1]={0};  

  Attributes *resultAttr   = getOperand(0);
  Attributes *srcAttr   = getOperand(1);
  Lng32 slen = srcAttr->getLength(op_data[-MAX_OPERANDS+1]);
  Lng32 rlen = resultAttr->getLength();
  str_pad(op_data[0], rlen , ' ');

  SHA_CTX  sha_ctx;

  SHA1_Init(&sha_ctx);  
  SHA1_Update(&sha_ctx, op_data[1], slen);
  SHA1_Final((unsigned char*) sha,&sha_ctx); 
  char tmp[3];
  for(int i=0; i < SHA_DIGEST_LENGTH ; i++ )
  {
    tmp[0]=tmp[1]=tmp[2]='0';
    sprintf(tmp, "%.2x", (int)sha[i]);
    str_cpy_all(op_data[0]+i*2, tmp, 2);
  }
   
  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ExFunctionMd5::eval(char * op_data[],
                                                        CollHeap *heap,
                                                        ComDiagsArea **diags)
{
  unsigned char md5[17]={0};  

  Attributes *resultAttr   = getOperand(0);
  Attributes *srcAttr   = getOperand(1);

  Lng32 slen = srcAttr->getLength(op_data[-MAX_OPERANDS+1]);
  Lng32 rlen = resultAttr->getLength();

  str_pad(op_data[0], rlen, ' ');
  MD5_CTX  md5_ctx;

  MD5_Init(&md5_ctx);  
  MD5_Update(&md5_ctx, op_data[1], slen);
  MD5_Final((unsigned char*) md5,&md5_ctx); 

  char tmp[3];
  for(int i=0; i < 16; i++ )
  {
    tmp[0]=tmp[1]=tmp[2]='0';
    sprintf(tmp, "%.2x", (int)md5[i]);
    str_cpy_all(op_data[0]+i*2, tmp, 2);
  }
   
  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ExFunctionIsIP::eval(char * op_data[],
                                                        CollHeap *heap,
                                                        ComDiagsArea **diags)
{
  
  char * resultData = op_data[0];
  char * srcData = op_data[1];
  Int16 i = 0, j = 0 , p=0;
  Attributes *resultAttr   = getOperand(0);
  Attributes *srcAttr   = getOperand(1);

  Lng32 slen = srcAttr->getLength(op_data[-MAX_OPERANDS+1]);
  Lng32 rlen = resultAttr->getLength();
  
  if(getOperType() == ITM_ISIPV4)
  { 
   if(string2ipv4(srcData, slen, NULL) == 0)
   {
       *(Int16 *)op_data[0] = 0; 
       return ex_expr::EXPR_OK;
   }
   else
   {
       *(Int16 *)op_data[0] = 1; 
       return ex_expr::EXPR_OK;
   }
 
  }
  else
  {
    Int16 gapcounter = 0 , portidx = 0;;
    char portion[IPV6_PARTS_NUM][MAX_IPV6_STRING_LEN + 1];
    char trimdata[MAX_IPV6_STRING_LEN + 1];
    str_pad(trimdata,MAX_IPV6_STRING_LEN + 1, 0);
    
    if(slen < MIN_IPV6_STRING_LEN ) 
    {
      *(Int16 *)op_data[0] = 0;
      return ex_expr::EXPR_OK;
    }

    char *ptr= srcData;

    //cannot start with single :
    if (*ptr == ':')
    {
      if (*(ptr+1) != ':')
      {
        *(Int16 *)op_data[0] = 0;
        return ex_expr::EXPR_OK;
      }
    }
    else if (*ptr == ' ')
    {
      while(*ptr==' ') ptr++;
    }     
    
    char * start=ptr;
    if(slen - (srcData - ptr) > MAX_IPV6_STRING_LEN ) // must be padding space
    {
       if( start[MAX_IPV6_STRING_LEN] != ' ')
       {
        *(Int16 *)op_data[0] = 0;
        return ex_expr::EXPR_OK;
       }
       else { 
         for(j = MAX_IPV6_STRING_LEN; j >=0; j--)
         {
           if(ptr[j] != ' ') //stop, j is the last non-space char
             break;
         }
         str_cpy_all(trimdata,start, j);
         start = trimdata;
       }
    } 

    char ipv4[MAX_IPV6_STRING_LEN + 1]; 
    j = 0;
    int ipv4idx = 0;
    // try to split the string into portions delieted by ':'
    // also check '::', call it gap, there is only up to 1 gap
    // if there is a gap, portion number can be smaller than 8
    // without gap, portion number should be 8
    // each portion must be 16 bit integer in HEX format
    // leading 0 can be omit
    for(i = 0; i< slen; i++)
    {
      if(start[i] == ':')
      {
        portion[portidx][j] = 0; //set the terminator

        if(start[i+1] == ':')
        {
          if(j != 0)  //some characters are already saved into current portion
            portidx++;
          gapcounter++;
          j = 0; //reset temp buffer pointer
          i++; 
          continue;
        }
        else
        {
          //new portion start
          if( j == 0 )
          {
            *(Int16 *)op_data[0] = 0;
            return ex_expr::EXPR_OK;
          }
          portidx++;
          j=0;
          continue;     
        }
      }     
      else if( start[i] == '.') //ipv4 mixed format
      {
        if( ipv4idx > 0 ) 
        {
          *(Int16 *)op_data[0] = 0; 
          return ex_expr::EXPR_OK;
        }
   
        str_cpy_all(ipv4, portion[portidx],str_len(portion[portidx]));
        if(strlen(start+i) < MAX_IPV4_STRING_LEN)  //15 is the maximum IPV4 string length
          str_cat((const char*)ipv4, start+i, ipv4);
        else
        {
          *(Int16 *)op_data[0] = 0; 
          return ex_expr::EXPR_OK;
        }
         
        if(string2ipv4(ipv4, strlen(ipv4), NULL) == 0)
        {
          *(Int16 *)op_data[0] = 0; 
          return ex_expr::EXPR_OK;
        }
        else
        {
          ipv4idx = 2;  //ipv4 use 2 portions, 32 bits
          break; // ipv4 string must be the last portion
        }
      }

      portion[portidx][j] = start[i]; 
      j++;
      
    }

    if(gapcounter > 1 || portidx > IPV6_PARTS_NUM - 1)
    { 
      *(Int16 *)op_data[0] = 0; 
      return ex_expr::EXPR_OK;
    }
    else if(gapcounter ==0 && portidx+ipv4idx < IPV6_PARTS_NUM - 1)
    { 
      *(Int16 *)op_data[0] = 0; 
      return ex_expr::EXPR_OK;
    }

    //check each IPV6 portion 
    for(i =0; i < portidx ; i++)
    {
      int len = strlen(portion[i]);
      if( len > 4)  //IPV4 portion can be longer than 4 chars
      {
        if(ipv4idx == 0 || ((ipv4idx == 2) && ( i != portidx -1)  ) )  // no IPV4 portion, or this is not the IPV4 portion
        {
          *(Int16 *)op_data[0] = 0;
          return ex_expr::EXPR_OK;
        }
      }
      for(j = 0; j < len; j++)
      {
        if( (portion[i][j] >= 'A' && portion[i][j] <= 'F') || 
            (portion[i][j] >= 'a' && portion[i][j] <= 'f') ||
            (portion[i][j] >= '0' && portion[i][j] <= '9')  
          ) //good
            continue;
        else
        {
          *(Int16 *)op_data[0] = 0; 
          return ex_expr::EXPR_OK;
        } 
      }
    }
    //everything is good, this is IPV6
    *(Int16 *)op_data[0] = 1; 
    return ex_expr::EXPR_OK;
  }
}

// Parse json errors
static void ExRaiseJSONError(CollHeap* heap, ComDiagsArea** diagsArea, JsonReturnType type)
{
    switch(type)
    {
    case JSON_INVALID_TOKEN:
        ExRaiseSqlError(heap, diagsArea, EXE_JSON_INVALID_TOKEN);
        break;
    case JSON_INVALID_VALUE:
        ExRaiseSqlError(heap, diagsArea, EXE_JSON_INVALID_VALUE);
        break;
    case JSON_INVALID_STRING:
        ExRaiseSqlError(heap, diagsArea, EXE_JSON_INVALID_STRING);
        break;
    case JSON_INVALID_ARRAY_START:
        ExRaiseSqlError(heap, diagsArea, EXE_JSON_INVALID_ARRAY_START);
        break;
    case JSON_INVALID_ARRAY_NEXT:
        ExRaiseSqlError(heap, diagsArea, EXE_JSON_INVALID_ARRAY_NEXT);
        break;
    case JSON_INVALID_OBJECT_START:
        ExRaiseSqlError(heap, diagsArea, EXE_JSON_INVALID_OBJECT_START);
        break;
    case JSON_INVALID_OBJECT_LABEL:
        ExRaiseSqlError(heap, diagsArea, EXE_JSON_INVALID_OBJECT_LABEL);
        break;
    case JSON_INVALID_OBJECT_NEXT:
        ExRaiseSqlError(heap, diagsArea, EXE_JSON_INVALID_OBJECT_NEXT);
        break;
    case JSON_INVALID_OBJECT_COMMA:
        ExRaiseSqlError(heap, diagsArea, EXE_JSON_INVALID_OBJECT_COMMA);
        break;
    case JSON_INVALID_END:
        ExRaiseSqlError(heap, diagsArea, EXE_JSON_INVALID_END);
        break;
    case JSON_END_PREMATURELY:
        ExRaiseSqlError(heap, diagsArea, EXE_JSON_END_PREMATURELY);
        break;
    default:
        ExRaiseSqlError(heap, diagsArea, EXE_JSON_UNEXPECTED_ERROR);
        break;
    }
}
/*
 * SOUNDEX(str) returns a character string containing the phonetic
 * representation of the input string. It lets you compare words that
 * are spelled differently, but sound alike in English.
 * The phonetic representation is defined in "The Art of Computer Programming",
 * Volume 3: Sorting and Searching, by Donald E. Knuth, as follows:
 *
 *  1. Retain the first letter of the string and remove all other occurrences
 *  of the following letters: a, e, h, i, o, u, w, y.
 *
 *  2. Assign numbers to the remaining letters (after the first) as follows:
 *        b, f, p, v = 1
 *        c, g, j, k, q, s, x, z = 2
 *        d, t = 3
 *        l = 4
 *        m, n = 5
 *        r = 6
 *
 *  3. If two or more letters with the same number were adjacent in the original
 *  name (before step 1), or adjacent except for any intervening h and w, then
 *  omit all but the first.
 *
 *  4. Return the first four bytes padded with 0.
 * */
ex_expr::exp_return_type ExFunctionSoundex::eval(char *op_data[],
						     CollHeap *heap,
						     ComDiagsArea** diagsArea)
{
    ULng32 previous = 0;
    ULng32 current = 0;

    char *srcStr = op_data[1];
    char *tgtStr = op_data[0];
    Lng32 srcLen = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);
    Lng32 tgtLen = getOperand(0)->getLength();
    
    CharInfo::CharSet cs = ((SimpleType *)getOperand(1))->getCharSet();

    str_pad(tgtStr, tgtLen, '\0');

    tgtStr[0] = toupper(srcStr[0]);    // Retain the first letter, convert to capital anyway
    Int16 setLen = 1;                  // The first character is set already

    for(int i=1; i < srcLen; ++i)
    {
        char chr = toupper(srcStr[i]);
        switch(chr)
        {
            case 'A':
            case 'E':
            case 'H':
            case 'I':
            case 'O':
            case 'U':
            case 'W':
            case 'Y':
                current = 0;
                break;
            case 'B':
            case 'F':
            case 'P':
            case 'V':
                current = 1;
                break;
            case 'C':
            case 'G':
            case 'J':
            case 'K':
            case 'Q':
            case 'S':
            case 'X':
            case 'Z':
                current = 2;
                break;
            case 'D':
            case 'T':
                current = 3;
                break;
            case 'L':
                current = 4;
                break;
            case 'M':
            case 'N':
                current = 5;
                break;
            case 'R':
                current = 6;
                break;
            default:
                break;
        }

        if(current)    // Only non-zero valued letter shall ve retained, 0 will be discarded
        {
            if(previous != current)
            {
                str_itoa(current, &tgtStr[setLen]);
                setLen++;    // A new character is set in target
            }
        }

        previous = current;

        if(setLen == tgtLen)    // Don't overhit the target string
            break;
    } // end of for loop

    if(setLen < tgtLen)
        str_pad(tgtStr+setLen, (tgtLen - setLen), '0');
    
    return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ExFunctionAESEncrypt::eval(char * op_data[],
                                                              CollHeap *heap,
                                                              ComDiagsArea **diagsArea)
{
  CharInfo::CharSet cs = ((SimpleType *)getOperand(0))->getCharSet();
  Attributes *tgt = getOperand(0);

  Lng32 source_len = getOperand(1)->getLength(op_data[-MAX_OPERANDS + 1]);
  char * source = op_data[1];

  Lng32 key_len = getOperand(2)->getLength(op_data[-MAX_OPERANDS + 2]);
  unsigned char * key = (unsigned char *)op_data[2];

  unsigned char * result = (unsigned char *)op_data[0];

  unsigned char rkey[EVP_MAX_KEY_LENGTH];
  int u_len, f_len;
  EVP_CIPHER_CTX ctx;
  const EVP_CIPHER * cipher = aes_algorithm_type[aes_mode];

  int iv_len_need = EVP_CIPHER_iv_length(cipher);

  unsigned char * iv = NULL;
  if (iv_len_need) {
    if (args_num == 3) {
      Lng32 iv_len_input = getOperand(3)->getLength(op_data[-MAX_OPERANDS + 3]);
      if (iv_len_input == 0 || iv_len_input < iv_len_need) {
        // the length of iv is too short
        ExRaiseSqlError(heap, diagsArea, EXE_AES_INVALID_IV);
        *(*diagsArea) << DgInt0(iv_len_input) << DgInt1(iv_len_need);
        return ex_expr::EXPR_ERROR;
      }
      iv = (unsigned char *)op_data[3];
    }
    else {
      // it does not have iv argument, but the algorithm need iv
      ExRaiseSqlError(heap, diagsArea,EXE_ERR_PARAMCOUNT_FOR_FUNC);
      *(*diagsArea) << DgString0("AES_ENCRYPT");
      return ex_expr::EXPR_ERROR;
    }
  }
  else {
    if (args_num == 3) {
      // the algorithm doesn't need iv, give a warning
      ExRaiseSqlWarning(heap, diagsArea, EXE_OPTION_IGNORED);
      *(*diagsArea) << DgString0("IV");
    }
  }

  aes_create_key(key, key_len, rkey, aes_mode);

  if (!EVP_EncryptInit(&ctx, cipher, (const unsigned char*)rkey, iv))
      goto aes_encrypt_error;

  if (!EVP_CIPHER_CTX_set_padding(&ctx, true))
      goto aes_encrypt_error;

  if (!EVP_EncryptUpdate(&ctx, result, &u_len, (const unsigned char *)source, source_len))
      goto aes_encrypt_error;

  if (!EVP_EncryptFinal(&ctx, result + u_len, &f_len))
      goto aes_encrypt_error;

  EVP_CIPHER_CTX_cleanup(&ctx);

  tgt->setVarLength(u_len + f_len, op_data[-MAX_OPERANDS]);

  return ex_expr::EXPR_OK;

aes_encrypt_error:
  ERR_clear_error();
  EVP_CIPHER_CTX_cleanup(&ctx);

  ExRaiseSqlError(heap, diagsArea, EXE_OPENSSL_ERROR);
  *(*diagsArea) << DgString0("AES_ENCRYPT FUNCTION");

  return ex_expr::EXPR_ERROR;
}

ex_expr::exp_return_type ExFunctionAESDecrypt::eval(char * op_data[],
                                                              CollHeap *heap,
                                                              ComDiagsArea **diagsArea)
{
  Attributes * tgt = getOperand(0);

  Lng32 source_len = getOperand(1)->getLength(op_data[-MAX_OPERANDS + 1]);
  const unsigned char * source = (unsigned char *)op_data[1];

  Lng32 key_len = getOperand(2)->getLength(op_data[-MAX_OPERANDS + 2]);
  const unsigned char * key = (unsigned char *)op_data[2];

  Lng32 maxLength = getOperand(0)->getLength();
  unsigned char * result = (unsigned char *) op_data[0];

  unsigned char rkey[EVP_MAX_KEY_LENGTH] = {0};
  int u_len, f_len;

  EVP_CIPHER_CTX ctx;

  const EVP_CIPHER * cipher = aes_algorithm_type[aes_mode];

  int iv_len_need = EVP_CIPHER_iv_length(cipher);

  unsigned char * iv = NULL;
  if (iv_len_need) {
    if (args_num == 3) {
      Lng32 iv_len_input = getOperand(3)->getLength(op_data[-MAX_OPERANDS + 3]);
      if (iv_len_input == 0 || iv_len_input < iv_len_need) {
        // the length of iv is too short
        ExRaiseSqlError(heap, diagsArea, EXE_AES_INVALID_IV);
        *(*diagsArea) << DgInt0(iv_len_input) << DgInt1(iv_len_need);
        return ex_expr::EXPR_ERROR;
      }
      iv = (unsigned char *)op_data[3];
    }
    else {
      // it does not have iv argument, but the algorithm need iv
      ExRaiseSqlError(heap, diagsArea, EXE_ERR_PARAMCOUNT_FOR_FUNC);
      *(*diagsArea) << DgString0("AES_DECRYPT");
      return ex_expr::EXPR_ERROR;
    }
  }
  else {
    if (args_num == 3) {
      // the algorithm doesn't need iv, give a warning
      ExRaiseSqlWarning(heap, diagsArea, EXE_OPTION_IGNORED);
      *(*diagsArea) << DgString0("IV");
    }
  }

  aes_create_key(key, key_len, rkey, aes_mode);

  if (!EVP_DecryptInit(&ctx, cipher, rkey, iv))
      goto aes_decrypt_error;

  if (!EVP_CIPHER_CTX_set_padding(&ctx, true))
      goto aes_decrypt_error;

  if (!EVP_DecryptUpdate(&ctx, result, &u_len, source, source_len))
      goto aes_decrypt_error;

  if (!EVP_DecryptFinal_ex(&ctx, result + u_len, &f_len))
      goto aes_decrypt_error;

  EVP_CIPHER_CTX_cleanup(&ctx);

  tgt->setVarLength(u_len + f_len, op_data[-MAX_OPERANDS]);

  return ex_expr::EXPR_OK;

aes_decrypt_error:
  ERR_clear_error();
  EVP_CIPHER_CTX_cleanup(&ctx);

  ExRaiseSqlError(heap, diagsArea, EXE_OPENSSL_ERROR);
  *(*diagsArea) << DgString0("AES_DECRYPT FUNCTION");

  return ex_expr::EXPR_ERROR;
}
