/*********************************************************************
// @@@ 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 <time.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 "ComCextdecs.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_split_part::ex_function_split_part(){};

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 in_args_num, 
                                           Int32 aes_mode )
     : ex_function_clause(oper_type, in_args_num + 1, attr, space), 
       args_num(in_args_num), aes_mode(aes_mode)
{
};

ExFunctionAESDecrypt::ExFunctionAESDecrypt(OperatorTypeEnum oper_type,
                                           Attributes ** attr, Space * space, 
                                           int in_args_num, Int32 aes_mode)
     : ex_function_clause(oper_type, in_args_num + 1, attr, space), 
       args_num(in_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,
                                           int in_args_num)
     : ex_function_clause(oper_type, in_args_num, attr, space),
       args_num(in_args_num)
{
  
};

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

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

};

ex_function_split_part::ex_function_split_part(OperatorTypeEnum oper_type
            , Attributes **attr
                    , Space *space)
      : ex_function_clause(oper_type, 4, 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;
      ++total_bytes_out;
    }
  }
  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;
};

Lng32 ex_function_position::errorChecks(Lng32 startPos, Lng32 occurrence,
                                        CollHeap* heap, ComDiagsArea** diagsArea)
{
  // startPos is 1 based. Cannot be <= 0
  if (startPos < 0)
    {
      ExRaiseSqlError(heap, diagsArea, -1572);
      *(*diagsArea) << DgString0("START POSITION") << DgString1("INSTR function"); 
      return -1;
    }
  
  if (startPos == 0)
    {
      ExRaiseSqlError(heap, diagsArea, -1571);
      *(*diagsArea) << DgString0("START POSITION") << DgString1("INSTR function"); 
      return -1;
    }
  
  if (occurrence < 0)
    {
      ExRaiseSqlError(heap, diagsArea, -1572);
      *(*diagsArea) << DgString0("OCCURRENCE") << DgString1("INSTR function"); 

      return -1;
    }
  
  if (occurrence == 0)
    {
      ExRaiseSqlError(heap, diagsArea, -1571);
      *(*diagsArea) << DgString0("OCCURRENCE") << DgString1("INSTR function"); 

      return -1;
    }
  
  return 0;
}


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

  // return value is 1 based. First character position is 1.

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

  Int32 startPos = 1;
  Int32 occurrence = 1;
  if (getNumOperands() >= 4) // start position and optional occurrence specified
    {
      startPos = *(Int32*)op_data[3];
      if (getNumOperands() == 5)
        occurrence = *(Int32*)op_data[4];

      if (errorChecks(startPos, occurrence, heap, diagsArea))
        return ex_expr::EXPR_ERROR;
    }

  // operand2/srcStr is the string to be searched in.
  char * srcStr = &op_data[2][startPos-1];
  len2 -= (startPos-1);

  char * pat = op_data[1];

  Lng32 position = 0;
  if (len1 > 0)
    {
      short nPasses = CollationInfo::getCollationNPasses(getCollation());
      for (Int32 occ = 1; occ <= occurrence; occ++)
        {
          position = findPosition(srcStr,
                                  len2, 
                                  pat,
                                  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;
            }

          if ((occ < occurrence) &&
              (position > 0)) // found a matching string
            {
              // skip the current matched string and continue
              srcStr += (position + len1 - 1);
              len2 -= (position + len1 - 1);
              startPos += (position + len1 -1);
            }
        } // for occ

      if (position > 0) // found matching string
        position += (startPos - 1);
    }
  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*heap,
                                                               ComDiagsArea**diagsArea)
{
  // len1 and len2 are character lengths.

  // len1 is the pattern length to be searched.
  Lng32 len1 = ( getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]) ) / sizeof(NAWchar);

  // len2 is the length of string to be seached in.
  Lng32 len2 = ( getOperand(2)->getLength(op_data[-MAX_OPERANDS+2]) ) / sizeof(NAWchar);
  
  // startPos is character pos and not byte pos
  Int32 startPos = 1;

  Int32 occurrence = 1;
  if (getNumOperands() >= 4)
    {
      startPos = *(Int32*)op_data[3];
      if (getNumOperands() == 5)
        occurrence = *(Int32*)op_data[4];

      if (ex_function_position::errorChecks(startPos, occurrence, 
                                            heap, diagsArea))
        return ex_expr::EXPR_ERROR;
    }

  // operand2/srcStr is the string to be searched in.
  NAWchar * srcStr = 
    (NAWchar*)&op_data[2][startPos*sizeof(NAWchar) - sizeof(NAWchar)];

  NAWchar* pat = (NAWchar*)op_data[1];

  // start at specified startPos
  Lng32 position = startPos;

  // If patter length(len1) > srcStr len(len2), return position of 0
  if (len1 > len2)
    position = 0;
  else if (len1 > 0)
    {
      // if pat is not present in srcStr, return  position of 0; 
      // otherwise return the position of pat in  srcStr for the 
      // specified occurrence.
      short found = 0;
      for (Int32 occ = 1; occ <= occurrence; occ++)
        {
          found = 0;
          while (position+len1-1 <= len2 && !found)
           {
              if (wc_str_cmp(pat, srcStr, (Int32)len1))
                {
                  position++;
                  srcStr += 1;
                }
              else
                found = 1;
            }

          if ((occ < occurrence) &&
              (found)) // found a matching string
            {
              srcStr += len1;
              position += len1;
            }
        } // for occ

     if (! found) // not found matching string, return 0;
       position = 0;
    } 
  else
    {
      // if len1 <= 0, return position of 1.
      position = 1;
    }

  // 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;
    if (opData == NULL )
    {
       ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
       *(*diagsArea) << DgString0("UNIX_TIMESTAMP");
       return ex_expr::EXPR_ERROR;
    }
    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_split_part::eval(char *op_data[]
                               , CollHeap* heap
                               , ComDiagsArea** diagsArea)
{
  size_t sourceLen = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);
  size_t patternLen = getOperand(2)->getLength(op_data[-MAX_OPERANDS+2]);
  Lng32 indexOfTarget = *(Lng32 *)op_data[3];

  if (indexOfTarget <= 0)
    {
       ExRaiseSqlError(heap, diagsArea, EXE_INVALID_FIELD_POSITION);
       *(*diagsArea) << DgInt0(indexOfTarget);
       return ex_expr::EXPR_ERROR;
    }

  NAString source(op_data[1], sourceLen);
  NAString pattern(op_data[2], patternLen);

  Lng32 patternCnt = 0;
  StringPos currentTargetPos = 0;
  StringPos pos = 0;

  while (patternCnt != indexOfTarget)
    {
       currentTargetPos = pos;
       pos = source.index(pattern, pos);
       if (pos == NA_NPOS)
        break;
       pos = pos + patternLen;
       patternCnt++;
    }

  size_t targetLen = 0;
  if ((patternCnt == 0)
        ||((patternCnt != indexOfTarget)
             && (patternCnt != indexOfTarget - 1)))
    op_data[0][0] = '\0';
  else
    {
       if (patternCnt == indexOfTarget)
         targetLen = pos - currentTargetPos - patternLen;
       else  //if (patternLen == indexOfTarget-1)
         targetLen = sourceLen - currentTargetPos;

       str_cpy_all(op_data[0], op_data[1] + currentTargetPos, targetLen);
    }
  getOperand(0)->setVarLength(targetLen, op_data[-MAX_OPERANDS]);
  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;
}

static Int64 lcl_dayofweek(Int64 totaldays)
{
  return (unsigned short)((totaldays + 1) % 7) + 1;
}

static Int64 lcl_dayofyear(char year, char month, char day)
{
  return (Date2Julian(year,month,day)-Date2Julian(year,1,1)+1);
}

#define DAYS_PER_YEAR 365.25 /*consider leap year every four years*/
#define MONTHS_PER_YEAR 12
#define DAYS_PER_MONTH 30
#define HOURS_PER_DAY 24
#define SECONDS_PER_MINUTE 60
#define SECONDS_PER_HOUR 3600
#define SECONDS_PER_DAY 86400

static Int64 lcl_interval(rec_datetime_field eField, Lng32 eCode, char *opdata, UInt32 nLength)
{
  if (!opdata)
    return 0;
  if ( REC_DATE_DECADE == eField && REC_INT_YEAR == eCode )
    {
      short nValue;
      str_cpy_all((char *) &nValue, opdata, sizeof(nValue));
      return nValue / 10;
    }
  if ( REC_DATE_QUARTER == eField && REC_INT_MONTH == eCode )
    {
      short nValue;
      str_cpy_all((char *) &nValue, opdata, sizeof(nValue));
      return (nValue-1)/3+1;
    }
  if ( REC_DATE_EPOCH == eField )
    {
      Int64 nVal = 0;
      if ( SQL_SMALL_SIZE==nLength )
        {
          short value;
          str_cpy_all((char *) &value, opdata, sizeof(value));
          nVal = value;
        }
      else if ( SQL_INT_SIZE==nLength )
        {
          Lng32 value;
          str_cpy_all((char *) &value, opdata, sizeof(value));
          nVal = value;
        }
      else if ( SQL_LARGE_SIZE==nLength )
        {
          str_cpy_all((char *) &nVal, opdata, sizeof(nVal));
        }

      if ( REC_INT_YEAR==eCode )
        return nVal*DAYS_PER_YEAR*SECONDS_PER_DAY;
      else if ( REC_INT_MONTH==eCode
               || REC_INT_YEAR_MONTH==eCode)
        {
          double result = (double)(nVal/MONTHS_PER_YEAR) * DAYS_PER_YEAR * SECONDS_PER_DAY;
          result += (double)(nVal%MONTHS_PER_YEAR) * DAYS_PER_MONTH * SECONDS_PER_DAY;
          return Int64(result);
        }
      else if ( REC_INT_DAY==eCode )
        return nVal*SECONDS_PER_DAY;
      else if ( REC_INT_HOUR==eCode
               || REC_INT_DAY_HOUR==eCode )
        return nVal*SECONDS_PER_HOUR;
      else if ( REC_INT_MINUTE==eCode
               || REC_INT_HOUR_MINUTE==eCode
               || REC_INT_DAY_MINUTE==eCode)
        return nVal*SECONDS_PER_MINUTE;
      else if ( REC_INT_SECOND==eCode
               || REC_INT_MINUTE_SECOND==eCode
               || REC_INT_HOUR_SECOND==eCode
               || REC_INT_DAY_SECOND==eCode )
         return nVal;
    }
  return 0;
}

Int64 ex_function_extract::getExtraTimeValue(rec_datetime_field eField, Lng32 eCode, char *dateTime)
{
  short year;
  char month;
  char day;
  char hour = 0;
  char minute = 0;
  char second = 0;
  char millisencond = 0;
  if (eField < REC_DATE_CENTURY || eField > REC_DATE_WOM)
    return 0;
  if (eCode != REC_DTCODE_DATE && eCode != REC_DTCODE_TIMESTAMP)
    return 0;

  ExpDatetime *datetimeOpType = (ExpDatetime *) getOperand(1);
  if (!datetimeOpType)
    return 0;

  rec_datetime_field eEndFiled = REC_DATE_DAY;
  if ( REC_DTCODE_TIMESTAMP == eCode )
    eEndFiled = REC_DATE_SECOND;
  size_t n = strlen(dateTime);
  for (Int32 field = REC_DATE_YEAR; field <= eEndFiled; field++)
    {
      switch (field)
        {
          case REC_DATE_YEAR:
            {
              str_cpy_all((char *) &year, dateTime, sizeof(year));
              dateTime += sizeof(year);
            }
            break;
          case REC_DATE_MONTH:
            {
              month = *dateTime++;
            }
            break;
          case REC_DATE_DAY:
            {
              day = *dateTime;
              if ( REC_DATE_SECOND == eEndFiled )
                dateTime++;
            }
            break;
          case REC_DATE_HOUR:
            {
              hour = *dateTime++;
            }
            break;
          case REC_DATE_MINUTE:
            {
              minute = *dateTime++;
            }
            break;
          case REC_DATE_SECOND:
            {
              second = *dateTime;
              if (n>7)// 2018-06-20 20:30:15.12  length = 8
                {
                  dateTime++;
                  millisencond = *dateTime;
                }
            }
            break;
        }
    }
  switch (eField)
    {
      case REC_DATE_DOW:
        {//same with built-in function dayofweek  ex_function_dayofweek::eval
          Int64 interval = datetimeOpType->getTotalDays(year, month, day);
          return lcl_dayofweek(interval);
        }
      case REC_DATE_DOY:
        {
          return lcl_dayofyear(year,month,day);
        }
      case REC_DATE_WOM:
        {
          return ((day-1)/7+1);
        }
      case REC_DATE_CENTURY:
        {
          return (year+99)/100;
        }
      case REC_DATE_DECADE:
        {
          return year/10;
        }
      case REC_DATE_WEEK:
        {//same with built-in function week  ITM_WEEK
          Int64 interval = datetimeOpType->getTotalDays(year, 1, 1);
          Int64 dayofweek = lcl_dayofweek(interval);
          Int64 dayofyear = lcl_dayofyear(year,month,day);
          return (dayofyear-1+dayofweek-1)/7+1;
        }
      case REC_DATE_QUARTER:
        {
          return (month-1)/3+1;
        }
      case REC_DATE_EPOCH:
        {
          Int64 ndays = datetimeOpType->getTotalDays(year, month, day);
          Int64 nJuliandays = datetimeOpType->getTotalDays(1970, 1, 1);
          ndays = ndays - nJuliandays;
          Int64 ntimestamp = ndays*86400+hour*3600+minute*60+second;
          if ( 0!=millisencond )
            ntimestamp = ntimestamp*100+millisencond;
          return ntimestamp;
        }
    }
  return 0;
}

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_CENTURY && extractStartField<=REC_DATE_WOM )
    {
      result = getExtraTimeValue(extractStartField, datetimeOpType->getPrecision(), datetimeOpData);
      copyInteger (op_data[0], getOperand(0)->getLength(), &result, sizeof(result));
      return ex_expr::EXPR_OK;
    }

    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 {
    if (getExtractField() == REC_DATE_DECADE
        || getExtractField() == REC_DATE_QUARTER
        || getExtractField() == REC_DATE_EPOCH)
      {
        ExpDatetime *datetimeOpType = (ExpDatetime *) getOperand(1);
        result = lcl_interval(getExtractField(),getOperand(1)->getDatatype(),op_data[1],getOperand(1)->getLength());
        copyInteger (op_data[0], getOperand(0)->getLength(), &result, sizeof(result));
        return ex_expr::EXPR_OK;
      }
    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
      // 2147483647 are equally valid.  So, we just need to pick one
      // in this range.  Do this based on a timestamp.
      struct timespec seedTime;

      clock_gettime(CLOCK_REALTIME, &seedTime);

      seed_  = (Int32) (seedTime.tv_sec  % 2147483648);
      seed_ ^= (Int32) (seedTime.tv_nsec % 2147483648L);

      // Go through one step of a linear congruential random generator.
      // (https://en.wikipedia.org/wiki/Linear_congruential_generator).
      // This is to avoid seed values that are close to each other when
      // we call this method again within a short time. The eval() method
      // below doesn't handle seed values that are close to each other
      // very well.
      seed_ = (((Int64) seed_) * 1664525L + 1013904223L) % 2147483648;

      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 if(getOperType() == ITM_UNIQUE_ID_SYS_GUID)
  {
    uuid_t uu;
    uuid_generate( uu ); 
    str_cpy_all(result, (char*)&uu,sizeof(uu));
  }
  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;
}
