/*********************************************************************
// @@@ 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),
    retryNum_(),
    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
                                              const char * optionalStr)
: ex_function_clause (ITM_RAISE_ERROR, (hasStringExp ? 2 : 1), attr, space),
  theSQLCODE_(sqlCode),
  constraintName_((char *)constraintName),
  tableName_((char *)tableName)
{
  setRaiseError(raiseError);

  if (optionalStr)
    {
      strncpy(optionalStr_, optionalStr, MAX_OPTIONAL_STR_LEN);
      optionalStr_[MAX_OPTIONAL_STR_LEN] = 0;
    }
  else
    optionalStr_[0] = 0;
};

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(),
                    NULL, NULL, NULL, NULL,
                    getOptionalStr());
  else
    ExRaiseSqlWarning(heap, diagsArea, (ExeErrorCode)getSQLCODE(),
                      NULL, NULL, NULL, NULL,
                      getOptionalStr());

  // 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();
  seqValGen->setRetryNum(getRetryNum());
  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;
}
