/**********************************************************************
// @@@ 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 @@@
**********************************************************************/
#ifndef EXP_FUNCTION_H
#define EXP_FUNCTION_H

/* -*-C++-*-
 *****************************************************************************
 *
 * File:         <file>
 * Description:  Expression clauses for functions, like string or datetime
 *               functions
 *               
 * Created:      7/10/95
 * Language:     C++
 *
 *
 *
 *
 *****************************************************************************
 */

#include "exp_clause.h"
#include "exp_clause_derived.h"
#include "dfs2rec.h"
#include "exp_dp2_expr.h"
#include "SequenceGeneratorAttributes.h"


class ex_function_clause;

// Both op1 and op2 are unsigned long.
// 3 bit left circular shift op1, and xor with op2.
// If (op1 << 3) has sign bit on, clear it and toggle one other bit
// by xor with 0x80000002.
// op2 remains intact.
//
// result and op2 have the identical sign bit value.
#define EXP_SHIFT31_XOR(op1, op2) \
  ( ((op1) & 0x10000000) ? \
    ( ( ((op1) << 3) | ((op1) >> 29) ) ^ 0x80000002 ^ (op2) ) : \
    ( ( ((op1) << 3) | ((op1) >> 29) ) ^ (op2) ) \
  )
// Both op1 and op2 are unsigned short
#define EXP_SHIFT15_XOR(op1, op2) \
  ( ((op1) & 0x1000) ? \
    ( ( ((op1) << 3) | ((op1) >> 13) ) ^ 0x8002 ^ (op2) ) : \
    ( ( ((op1) << 3) | ((op1) >> 13) ) ^ (op2) ) \
  )

#define EXP_SCRAMBLE 0x35
#define MAX_IPV4_STRING_LEN  15
#define MAX_IPV6_STRING_LEN  8 * 4 + 7 
#define MIN_IPV4_STRING_LEN  7
#define MIN_IPV6_STRING_LEN  2
#define IPV6_PARTS_NUM       8

UInt32 FastHash(char *data, Int32 length);

class  ExFunctionAscii : public ex_function_clause {
public:
  ExFunctionAscii(OperatorTypeEnum oper_type,
			     Attributes ** attr,
			     Space * space);
  ExFunctionAscii();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*,
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ExFunctionChar : public ex_function_clause {
public:
  ExFunctionChar(OperatorTypeEnum oper_type,
			    Attributes ** attr,
			    Space * space);
  ExFunctionChar();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*,
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ExFunctionConvertHex : public ex_function_clause {
public:
  ExFunctionConvertHex(OperatorTypeEnum oper_type,
				  Attributes ** attr,
				  Space * space);
  ExFunctionConvertHex();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*,
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ExFunctionRepeat : public ex_function_clause {
public:
  ExFunctionRepeat(OperatorTypeEnum oper_type,
			     Attributes ** attr,
			     Space * space);
  ExFunctionRepeat();


  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*,
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ExFunctionReplace : public ex_function_clause {
public:
  ExFunctionReplace(OperatorTypeEnum oper_type,
			     Attributes ** attr,
			     Space * space);
  ExFunctionReplace();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*,
					   ComDiagsArea** = 0);  
  Long pack(void *);
  
  // ---------------------------------------------------------------------
  // collation
  // ---------------------------------------------------------------------

  CharInfo::Collation getCollation()
  {
    return (CharInfo::Collation) collation_;
  }

  void setCollation( CharInfo::Collation c)
  {
    collation_ = (Int16) c;
  }

  Int16 getArgEncodedLen( Int16 i)
  {
    assert(i <2 && i>=0);
    return argsEncodedLen_[i];
  }
  
  void setArgEncodedLen( Int16 v, Int16 i)
  {
    assert(i <2 && i>=0);
    argsEncodedLen_[i] = v;
  }

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
 
private:
  Int16 collation_;
  Int16 argsEncodedLen_[2];
  char	fillers_[2];

  // ---------------------------------------------------------------------
};

class  ex_function_char_length : public ex_function_clause {
public:
  ex_function_char_length(OperatorTypeEnum oper_type,
				     Attributes ** attr,
				     Space * space);
  ex_function_char_length();


  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*,
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ex_function_oct_length : public ex_function_clause {
public:
  ex_function_oct_length(OperatorTypeEnum oper_type,
				    Attributes ** attr,
				    Space * space);
  ex_function_oct_length();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);
  
  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ex_function_char_length_doublebyte : 
	public ex_function_clause 
{
public:
  ex_function_char_length_doublebyte(OperatorTypeEnum oper_type,
                                   Attributes ** attr,
                                   Space * space);
  ex_function_char_length_doublebyte();


  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*,
                                         ComDiagsArea** = 0);
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ex_function_position : public ex_function_clause {
public:
  ex_function_position(OperatorTypeEnum oper_type,
                       Attributes ** attr,
                       Space * space,
                       int in_args_num);
  ex_function_position();


  ////////////////////////////////////////////////////////
  // Routine to find position of pattern string within
  // source string.  For use with ISO88591 chars only.
  // Caller is to verify that lengths are > 0.  This
  // function does check, however, to see if the pattern
  // length is <= the source length.
  //
  // Furthermore, this function takes a boolean flag
  // called "patternInFront" which indicates that the
  // caller only wants to check if the pattern resides at
  // the beginning of the string (and not waste time
  // checking the entire string).  This is used by LIKE
  // clauses.
  ////////////////////////////////////////////////////////
  static
  Int32 findPosition(char* pat,
                     Int32 patLen,
                     char* src,
                     Int32 srcLen,
                     NABoolean patternInFront);

  ////////////////////////////////////////////////////////
  // If searchLen is <= 0 or searchLen > sourceLen or 
  // searchStr is not present in sourceStr,
  // return a position of 0; 
  // otherwise return the position of searchStr in
  // sourceStr.
  ////////////////////////////////////////////////////////
  static
  Lng32 findPosition(char * sourceStr, 
		    Lng32 sourceLen,
		    char * searchStr, 
		    Lng32 searchLen,
		    short bytesPerChar = 1,
                    Int16 nPasses = 1,
                    CharInfo::Collation collation = CharInfo::DefaultCollation,
                    short charOffsetFlag = 0,
                    CharInfo::CharSet cs = CharInfo::ISO88591);

  static Lng32 errorChecks(Lng32 startPos, Lng32 occurrence,
                           CollHeap* heap, ComDiagsArea** diagsArea);

  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  ex_expr::exp_return_type eval(char *op_data[], CollHeap* heap, 
                                ComDiagsArea** = 0);  
  Long pack(void *);
  
  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }


  // ---------------------------------------------------------------------
  // collation.
  // ---------------------------------------------------------------------

  CharInfo::Collation getCollation() 
  {
    return (CharInfo::Collation) collation_;
  }

  void setCollation(CharInfo::Collation v) 
  {
    collation_ = (Int16) v;
  }

private:
  Int16	collation_; 

  Int16 args_num;

  char             fillers_[4];  // 
};

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


  ex_expr::exp_return_type eval(char *op_data[], CollHeap* heap,
                                ComDiagsArea** = 0);
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------

private:
  Int16 args_num;

  char             fillers_[6];  // 
};

class  ex_function_concat : public ex_function_clause {
public:
  ex_function_concat(OperatorTypeEnum oper_type,
				Attributes ** attr,
				Space * space);
  ex_function_concat();


  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);
  
  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ex_function_lower : public ex_function_clause {
public:
  ex_function_lower(OperatorTypeEnum oper_type,
			       Attributes ** attr,
			       Space * space);
  ex_function_lower();


  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);
  
  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ex_function_lower_unicode : public ex_function_clause {
public:
  ex_function_lower_unicode(OperatorTypeEnum oper_type,
                             Attributes ** attr,
                             Space * space);
  ex_function_lower_unicode();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*,
                                         ComDiagsArea** = 0);
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ex_function_upper : public ex_function_clause {
public:
  ex_function_upper(OperatorTypeEnum oper_type,
			       Attributes ** attr,
			       Space * space);
  ex_function_upper();


  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);
  
  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ex_function_upper_unicode : public ex_function_clause {
public:
  ex_function_upper_unicode(OperatorTypeEnum oper_type,
                             Attributes ** attr,
                             Space * space);
  ex_function_upper_unicode();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*,
                                         ComDiagsArea** = 0);
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

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


  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

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


  inline Int32 getTrimMode() const {return mode_;}
  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0) = 0;  
  Long pack(void *) = 0;

    // ---------------------------------------------------------------------
  // collation
  // ---------------------------------------------------------------------

  CharInfo::Collation getCollation()
  {
    return (CharInfo::Collation) collation_;
  }

  void setCollation( CharInfo::Collation c)
  {
    collation_ = (Int16) c;
  }

  Int16 getSrcStrEncodedLength()
  {
    return srcStrEncodedLength_;
  }
  
  void setSrcStrEncodedLength( Int16 v)
  {
    srcStrEncodedLength_ = v;
  }

  
  Int16 getTrimCharEncodedLength()
  {
    return trimCharEncodedLength_;
  }
  
  void setTrimCharEncodedLength( Int16 v)
  {
    trimCharEncodedLength_ = v;
  }
  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
  
private:
  Int32            mode_;                     //00-03
  Int16            collation_;                //04-05
  Int16            srcStrEncodedLength_;      //06-07
  Int16            trimCharEncodedLength_;    //08-09
  // ---------------------------------------------------------------------
  // Fillers for potential future extensions without changing class size.
  // When a new member is added, size of this filler should be reduced so
  // that the size of the object remains the same (and is modulo 8).
  // ---------------------------------------------------------------------
  char             fillers_[6];          // 10-15
};

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


  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);
  ex_expr::exp_return_type eval(char *op_data[], CollHeap*,
                                         ComDiagsArea** = 0);
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(3,getClassVersionID());
    ex_function_trim::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class ExFunctionCrc32: public ex_function_clause {
public:
  ExFunctionCrc32(OperatorTypeEnum oper_type,
				Attributes ** attr,
				Space * space);
  ExFunctionCrc32();

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class ExFunctionSha: public ex_function_clause {
public:
  ExFunctionSha(OperatorTypeEnum oper_type,
				Attributes ** attr,
				Space * space);
  ExFunctionSha();

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

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

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------

private:
  Lng32 mode;
};

class ExFunctionSoundex: public ex_function_clause {
public:
  ExFunctionSoundex(OperatorTypeEnum oper_type,
				Attributes ** attr,
				Space * space);
  ExFunctionSoundex();

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class ExFunctionMd5: public ex_function_clause {
public:
  ExFunctionMd5(OperatorTypeEnum oper_type,
				Attributes ** attr,
				Space * space);
  ExFunctionMd5();

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class ExFunctionIsIP : public ex_function_clause {
public:
  ExFunctionIsIP(OperatorTypeEnum oper_type,
				Attributes ** attr,
				Space * space);
  ExFunctionIsIP();

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class ExFunctionInetAton: public ex_function_clause {
public:
  ExFunctionInetAton(OperatorTypeEnum oper_type,
				Attributes ** attr,
				Space * space);
  ExFunctionInetAton();

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};


class ExFunctionInetNtoa: public ex_function_clause {
public:
  ExFunctionInetNtoa(OperatorTypeEnum oper_type,
				Attributes ** attr,
				Space * space);
  ExFunctionInetNtoa();

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class ExFunctionAESEncrypt : public ex_function_clause {
public:
  ExFunctionAESEncrypt(OperatorTypeEnum oper_type,
                                  Attributes ** attr,
                                  Space * space,
                                  int args_num,
                                  Int32 aes_mode);
  ExFunctionAESEncrypt();

  ex_expr::exp_return_type eval(char *op_datap[], CollHeap*,
                                           ComDiagsArea** = 0);
  long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }

  // ---------------------------------------------------------------------
private:
  Int32 aes_mode;
  Int32 args_num;
};

class ExFunctionAESDecrypt : public ex_function_clause {
public:
  ExFunctionAESDecrypt(OperatorTypeEnum oper_type,
                                  Attributes ** attr,
                                  Space *space,
                                  int args_num,
                                  Int32 aes_mode);

  ExFunctionAESDecrypt();

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*,
                                           ComDiagsArea ** = 0);

  long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }

  // ---------------------------------------------------------------------
private:
  Int32 aes_mode;
  Int32 args_num;
};

class  ExFunctionTokenStr : public ex_function_clause {
public:
  ExFunctionTokenStr(OperatorTypeEnum oper_type,
				Attributes ** attr,
				Space * space);
  ExFunctionTokenStr();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);
  
  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ExFunctionReverseStr : public ex_function_clause {
public:
  ExFunctionReverseStr(OperatorTypeEnum oper_type,
				Attributes ** attr,
				Space * space);
  ExFunctionReverseStr();

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
                                ComDiagsArea** = 0);  
  //  Long pack(void *);
  
  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ex_function_trim_doublebyte : public ex_function_trim {
public:
  ex_function_trim_doublebyte(OperatorTypeEnum oper_type,
                            Attributes ** attr,
                            Space * space, Int32 mode);
  ex_function_trim_doublebyte();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*,
                                         ComDiagsArea** = 0);
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(3,getClassVersionID());
    ex_function_trim::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

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


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ex_function_unixtime: public ex_function_clause {
public:
  ex_function_unixtime(OperatorTypeEnum oper_type, short num,
				 Attributes ** attr,
				 Space * space);
  ex_function_unixtime();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ex_function_current : public ex_function_clause {
public:
  ex_function_current(OperatorTypeEnum oper_type,
				 Attributes ** attr,
				 Space * space);
  ex_function_current();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

// ++ Triggers -
class ex_function_unique_execute_id : public ex_function_clause {
public:
  ex_function_unique_execute_id(OperatorTypeEnum oper_type,
				 Attributes ** attr,
				 Space * space);
  ex_function_unique_execute_id();
  // this eval is dummy, the value is set in ex_root
  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					ComDiagsArea** = 0){ return ex_expr::EXPR_OK;};
  Long pack(void *);
  
};

// ++ Triggers -
class ex_function_get_triggers_status : public ex_function_clause {
public:
  ex_function_get_triggers_status(OperatorTypeEnum oper_type,
				 Attributes ** attr,
				 Space * space);
  ex_function_get_triggers_status();
  // this eval is dummy, the value is set in ex_root
  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					ComDiagsArea** = 0){ return ex_expr::EXPR_OK;};
  Long pack(void *);
};

// ++ Triggers -
class ex_function_get_bit_value_at : public ex_function_clause {
public:
  ex_function_get_bit_value_at(OperatorTypeEnum oper_type,
				 Attributes ** attr,
				 Space * space);
  ex_function_get_bit_value_at();
  // this eval is dummy, the value is set in ex_root
  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					ComDiagsArea** = 0);
  Long pack(void *);
};

// ++ MV
class ex_function_is_bitwise_and_true : public ex_function_clause {
public:
  ex_function_is_bitwise_and_true(OperatorTypeEnum oper_type,
				 Attributes ** attr,
				 Space * space);
  ex_function_is_bitwise_and_true();
  // this eval is dummy, the value is set in ex_root
  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					ComDiagsArea** = 0);
  Long pack(void *);
  virtual short getClassSize() { return (short)sizeof(*this); }

};

class  ex_function_substring_doublebyte: public ex_function_clause {
public:
  ex_function_substring_doublebyte(OperatorTypeEnum oper_type,
                                 short num_operands,
                                 Attributes ** attr,
                                 Space * space);
  ex_function_substring_doublebyte();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*,
                                         ComDiagsArea** = 0);
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ex_function_translate : public ex_function_clause {

public:
  ex_function_translate (OperatorTypeEnum oper_type,
                                    Attributes ** attr,
                                    Space * space,
                                    Int32 conv_type,
                                    Int16 flags);
  ex_function_translate () {};


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*,
                                           ComDiagsArea** = 0);
  Long pack(void *);

  Int32 get_conv_type() { return conv_type_; };

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }

  // flags:
  // 0x0001 set the CONV_ALLOW_INVALID_CODE_VALUE flag when converting
  //        the data to allow invalid code points and replace them
  //        with a replacement character
  enum TranslateFlags
  {
    TRANSLATE_FLAG_ALLOW_INVALID_CODEPOINT = 0x001
  };

  // ---------------------------------------------------------------------

private:
  Int32            conv_type_;           // 00-03
  // flags, see TranslateFlags enum above
  Int16            flags_;               // 04-05
  // ---------------------------------------------------------------------
  // Fillers for potential future extensions without changing class size.
  // When a new member is added, size of this filler should be reduced so
  // that the size of the object remains the same (and is modulo 8).
  // ---------------------------------------------------------------------
  char             fillers_[2];          // 06-07

};

class  ex_function_encode : public ex_function_clause {
	       public:

  // Construction
  // 
  ex_function_encode();
  ex_function_encode(OperatorTypeEnum oper_type,
				Attributes ** attr,
				Space * space,
				short descFlag = 0);

  ex_function_encode(OperatorTypeEnum oper_type,
				Attributes ** attr,
				Space * space,
				CharInfo::Collation collation = CharInfo::DefaultCollation,
				short descFlag = 0,
				CollationInfo::CollationType collType = CollationInfo::Sort);


  // Null Semantics
  //
  Int32 isNullInNullOut() const { return 0; };
  Int32 isNullRelevant() const { return 1; };
  ex_expr::exp_return_type processNulls(char *op_data[], CollHeap*, 
						   ComDiagsArea** = 0);

  // Execution
  //
  Int32 isEvalRelevant() const { return 1; };
  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);

  // Fixup
  //
  Long pack(void *);
  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);
  
  // Helpers
  //
  static void encodeKeyValue(Attributes * attr, 
					const char *source,
					const char *varlen_ptr,
					char *target,
					NABoolean isCaseInsensitive,
                                        Attributes * tgtAttr = NULL,
                                        char *tgt_varlen_ptr = NULL,
			                const Int32 tgtLength = 0,
					CharInfo::Collation collation = CharInfo::DefaultCollation,
					CollationInfo::CollationType collType = CollationInfo::Sort);
					

  static void encodeCollationKey(const UInt8 * src,
					    Int32 srcLength,
					    UInt8 * encodedKey,
					    const Int32 encodedKeyLength,
					    Int16 nPasses,
					    CharInfo::Collation  collation = CharInfo::DefaultCollation,
					    NABoolean rmTSpaces = TRUE);

  static void encodeCollationSearchKey(
					    const UInt8 * src,
					    Int32 srcLength,
					    UInt8 * encodedKey,
					    const Int32 encodedKeyLength,
                                            Int32 & effEncodedKeyLength,
					    Int16 nPasses,
					    CharInfo::Collation  collation = CharInfo::DefaultCollation,
					    NABoolean rmTSpaces = TRUE);

  ex_expr::exp_return_type evalDecode(char *op_data[],
				      CollHeap* heap);

  static short decodeKeyValue(Attributes * attr, 
					 NABoolean isDesc,
					 char *source,
					 char *varlen_ptr,
					 char *target,
                                         char *target_varlen_ptr,
					 NABoolean handleNullability);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------

  NABoolean isDesc()
  {
    return ((flags_ & IS_DESC) != 0);
  };

  inline void setIsDesc(NABoolean v)
  {
    (v) ? flags_ |= IS_DESC: flags_ &= ~IS_DESC;
  };

  NABoolean caseInsensitive()
  {
    return ((flags_ & CASE_INSENSITIVE) != 0);
  };

  inline void setCaseInsensitive(NABoolean v)
  {
    (v) ? flags_ |= CASE_INSENSITIVE: flags_ &= ~CASE_INSENSITIVE;
  };

  NABoolean regularNullability()
  {
    return ((flags_ & REGULAR_NULLABILITY) != 0);
  };

  inline void setRegularNullability(NABoolean v)
  {
    (v) ? flags_ |= REGULAR_NULLABILITY: flags_ &= ~REGULAR_NULLABILITY;
  };

  NABoolean isDecode()
  {
    return ((flags_ & IS_DECODE) != 0);
  };

  inline void setIsDecode(NABoolean v)
  {
    (v) ? flags_ |= IS_DECODE: flags_ &= ~IS_DECODE;
  };


   static unsigned char getCollationWeight( 
                                                      CharInfo::Collation collation,
						      Int16 pass,
						      UInt16 chr) ;

   static void getCollationWeight( 
					CharInfo::Collation collation,
					Int16 pass,
                                        UInt16 chr,
                                        UInt8 * weightStr,
                                        Int16 & weightStrLen);

  CollationInfo::CollationType getCollEncodingType() const
  {
    return (CollationInfo::CollationType)CollEncodingType_;
  };

  void setCollEncodingType(CollationInfo::CollationType v)
  {
    CollEncodingType_ = (UInt8)v;
  };

  CharInfo::Collation getCollation() const	
  { 
    return (CharInfo::Collation) collation_; 
  }

  void setCollation(CharInfo::Collation v) 	
  { 
    collation_ = (Int16)v;; 
  }


  static Int16 getNumberOfDigraphs(CharInfo::Collation collation);	

  static UInt8 * getDigraph(const CharInfo::Collation collation, const Int32 digraphNum);	

  static Int16 getDigraphIndex(const CharInfo::Collation collation, const Int32 digraphNum);	
  
  static NABoolean getRmTSpaces(const CharInfo::Collation collation);

  static NABoolean getNumberOfChars(const CharInfo::Collation collation);

  static NABoolean isOneToOneCollation(const CharInfo::Collation collation);

private:
  enum
  {
    // encode for case insensitive comparison for character datatypes.
    IS_DESC                        = 0x0001,
    CASE_INSENSITIVE        = 0x0002,
    REGULAR_NULLABILITY = 0x0004,
    IS_DECODE                    = 0x0008
  };

  Int16            flags_;		   // 00-01
  Int16		   collation_;		   //02-03
  UInt8		   CollEncodingType_;      //04-04
  // ---------------------------------------------------------------------
  // Fillers for potential future extensions without changing class size.
  // When a new member is added, size of this filler should be reduced so
  // that the size of the object remains the same (and is modulo 8).
  // ---------------------------------------------------------------------
  char             fillers_[3];          // 05-07
};

// ---------------------------------------------------------------------
// METHOD:  Collated_cmp()
// PURPOSE: Compare 2 strings using specified collation
// RETCODE:  0 - The two strings collate as EQUAL to each other
//          < 0 if string1 < string2
//          > 0 if string1 > string2
// INPUT:   char *string1: Ptr to first string
//          char *string2: Ptr to second string
//          int length:    Amt to compare (in bytes)
//          CharInfo::Collation Collation: Enum value for Collation
//          char *sortBuffer1 - buffer to hold encoded Collation Key 1
//          char *sortBuffer2 - buffer to hold encoded Collation Key 2
// NOTE:    sortBuffer1 & sortBuffer2 MUST BE preallocated and big enough.
// ---------------------------------------------------------------------
// NOTE: No need to use ... maybe in the future?
static Int32 Collated_cmp(char *string1, char *string2, Int32 length,
                 CharInfo::Collation Collation,
                 char *sortBuffer1, char *sortBuffer2)
{
    Int16 nPasses = CollationInfo::getCollationNPasses(Collation);
    Int32 encodeKeyBufLen = length * nPasses + 2 + nPasses;

    ex_function_encode::encodeCollationKey( (const UInt8 *)string1,
                                            length,
                                            (UInt8 *)sortBuffer1,
                                            encodeKeyBufLen,
                                            nPasses,
                                            Collation,
                                            FALSE /*remove trailing spaces */
                                            );
    ex_function_encode::encodeCollationKey( (const UInt8 *)string2,
                                            length,
                                            (UInt8 *)sortBuffer2,
                                            encodeKeyBufLen,
                                            nPasses,
                                            Collation,
                                            FALSE /*remove trailing spaces */
                                            );
    return ( str_cmp(sortBuffer1, sortBuffer2, encodeKeyBufLen) );
};



//-- Czech collation info START
struct collationParams 
{
  Int16     numberOfPasses;
  Int16     numberOfChars;
  Int16     numberOfDigraphs;
  Int16     numberOfLigatures;
  NABoolean rmTSpaces; // for varchar. for char we trim Tspaces
  UInt8     digraphs[10][2];
  Int16     digraphIdx[10];
  UInt8     weightTable[4][300];  // need to change 4 to collationInfo::maxNbrePAsses after defining it in charinfo.h
};

typedef struct collationParams CollationParams;

static const CollationParams collParams[3]=
{
  {//XCZECH
    2, //collationNPasses[0],
    259,
    3,
    0,
    0,  
    {
      {'c','h'},
      {'C','h'},
      {'C','H'}
    },
    {256,  257,  258},
    //XCZECH weights
    {
      {	0,	0,	0,	0,	0,	0,	0,	0,
	0,	1,	0,	0,	0,	0,	0,	0,	
	0,	0,	0,	0,	0,	0,	0,	0,	
	0,	0,	0,	0,	0,	0,	0,	0,	
	1,	0,	0,	0,	0,	0,	0,	0,	
	0,	0,	0,	0,	0,	0,	0,	0,	
	240,	241,	242,	243,	244,	245,	246,	247,	
	248,	249,	0,	0,	0,	0,	0,	0,	
	0,	20,	25,	30,	35,	40,	45,	50,	
	55,	60,	65,	70,	75,	80,	85,	90,	
	95,	98,	100,	105,	110,	115,	120,	122,	
	125,	130,	135,	0,	0,	0,	0,	0,	
	0,	20,	25,	30,	35,	40,	45,	50,	
	55,	60,	65,	70,	75,	80,	85,	90,	
	95,	98,	100,	105,	110,	115,	120,	122,	
	125,	130,	135,	0,	0,	0,	0,	0,	
	0,	0,	0,	0,	0,	0,	0,	0,	
	0,	0,	0,	0,	0,	0,	0,	0,	
	0,	0,	0,	0,	0,	0,	0,	0,	
	0,	0,	0,	0,	0,	0,	0,	0,	
	0,	20,	0,	75,	0,	75,	105,	0,	
	0,	107,	105,	110,	135,	0,	138,	135,	
	0,	20,	0,	75,	0,	75,	105,	0,	
	0,	107,	105,	110,	135,	0,	138,	135,	
	100,	20,	20,	20,	20,	75,	30,	30,	
	32,	40,	40,	40,	40,	60,	60,	35,	
	35,	85,	85,	90,	90,	90,	90,	0,	
	102,	115,	115,	115,	115,	130,	110,	105,	
	100,	20,	20,	20,	20,	75,	30,	30,	
	32,	40,	40,	40,	40,	60,	60,	35,	
	35,	85,	85,	90,	90,	90,	90,	0,	
	102,	115,	115,	115,	115,	130,	110,	0,
	57,	57,	57}
    ,
      {	0,	1,	2,	3,	4,	5,	6,	7,	
	8,	2,	10,	11,	12,	13,	14,	15,	
	16,	17,	18,	19,	20,	21,	22,	23,	
	24,	25,	26,	27,	28,	29,	30,	31,	
	1,	33,	34,	35,	36,	37,	38,	39,	
	40,	41,	42,	43,	44,	45,	46,	47,	
	1,	1,	1,	1,	1,	1,	1,	1,	
	1,	1,	58,	59,	60,	61,	62,	63,	
	64,	2,	2,	2,	2,	2,	2,	2,	
	2,	2,	2,	2,	2,	2,	2,	2,	
	2,	2,	2,	3,	2,	2,	2,	2,	
	2,	2,	2,	91,	92,	93,	94,	95,	
	96,	1,	1,	1,	1,	1,	1,	1,	
	1,	1,	1,	1,	1,	1,	1,	1,	
	1,	1,	1,	2,	1,	1,	1,	1,	
	1,	1,	1,	123,	124,	125,	126,	127,	
	128,	129,	130,	131,	132,	133,	134,	135,	
	136,	137,	138,	139,	140,	141,	142,	143,	
	144,	145,	146,	147,	148,	149,	150,	151,	
	152,	153,	154,	155,	156,	157,	158,	159,	
	160,	28,	216,	32,	164,	14,	5,	167,	
	168,	14,	26,	14,	4,	173,	14,	22,	
	176,	27,	219,	31,	180,	13,	4,	199,	
	184,	13,	25,	13,	3,	221,	13,	21,	
	4,	4,	12,	16,	10,	4,	22,	26,	
	14,	4,	28,	22,	14,	4,	8,	14,	
	32,	22,	14,	4,	8,	18,	10,	215,	
	14,	6,	4,	18,	10,	4,	26,	1,	
	3,	3,	11,	15,	9,	3,	21,	25,	
	13,	3,	27,	21,	13,	3,	7,	13,	
	31,	21,	13,	3,	7,	17,	9,	247,	
	13,	5,	3,	17,	9,	3,	25,	217,
	1,	2,	3}
    }

  }
,
  {//XCZECH_CI
    2, //collationNPasses[1],
    259,
    3,
    0,
    0,  
    {
      {'c','h'},
      {'C','h'},
      {'C','H'}
    },
    {256,  257,  258},
    {
      {	0,	0,	0,	0,	0,	0,	0,	0,
	0,	1,	0,	0,	0,	0,	0,	0,	
	0,	0,	0,	0,	0,	0,	0,	0,	
	0,	0,	0,	0,	0,	0,	0,	0,	
	1,	0,	0,	0,	0,	0,	0,	0,	
	0,	0,	0,	0,	0,	0,	0,	0,	
	240,	241,	242,	243,	244,	245,	246,	247,	
	248,	249,	0,	0,	0,	0,	0,	0,	
	0,	20,	25,	30,	35,	40,	45,	50,	
	55,	60,	65,	70,	75,	80,	85,	90,	
	95,	98,	100,	105,	110,	115,	120,	122,	
	125,	130,	135,	0,	0,	0,	0,	0,	
	0,	20,	25,	30,	35,	40,	45,	50,	
	55,	60,	65,	70,	75,	80,	85,	90,	
	95,	98,	100,	105,	110,	115,	120,	122,	
	125,	130,	135,	0,	0,	0,	0,	0,	
	0,	0,	0,	0,	0,	0,	0,	0,	
	0,	0,	0,	0,	0,	0,	0,	0,	
	0,	0,	0,	0,	0,	0,	0,	0,	
	0,	0,	0,	0,	0,	0,	0,	0,	
	0,	20,	0,	75,	0,	75,	105,	0,	
	0,	107,	105,	110,	135,	0,	138,	135,	
	0,	20,	0,	75,	0,	75,	105,	0,	
	0,	107,	105,	110,	135,	0,	138,	135,	
	100,	20,	20,	20,	20,	75,	30,	30,	
	32,	40,	40,	40,	40,	60,	60,	35,	
	35,	85,	85,	90,	90,	90,	90,	0,	
	102,	115,	115,	115,	115,	130,	110,	105,	
	100,	20,	20,	20,	20,	75,	30,	30,	
	32,	40,	40,	40,	40,	60,	60,	35,	
	35,	85,	85,	90,	90,	90,	90,	0,	
	102,	115,	115,	115,	115,	130,	110,	0,
	57,	57,	57}
    ,
      {	
	0,	1,	2,	3,	4,	5,	6,	7,	
	8,	2,	10,	11,	12,	13,	14,	15,	
	16,	17,	18,	19,	20,	21,	22,	23,	
	24,	25,	26,	27,	28,	29,	30,	31,	
	1,	33,	34,	35,	36,	37,	38,	39,	
	40,	41,	42,	43,	44,	45,	46,	47,	
	1,	1,	1,	1,	1,	1,	1,	1,	
	1,	1,	58,	59,	60,	61,	62,	63,	
	64,	1,	1,	1,	1,	1,	1,	1,	
	1,	1,	1,	1,	1,	1,	1,	1,	
	1,	1,	1,	1,	1,	1,	1,	1,	
	1,	1,	1,	91,	92,	93,	94,	95,	
	96,	1,	1,	1,	1,	1,	1,	1,	
	1,	1,	1,	1,	1,	1,	1,	1,	
	1,	1,	1,	1,	1,	1,	1,	1,	
	1,	1,	1,	123,	124,	125,	126,	127,	
	128,	129,	130,	131,	132,	133,	134,	135,	
	136,	137,	138,	139,	140,	141,	142,	143,	
	144,	145,	146,	147,	148,	149,	150,	151,	
	152,	153,	154,	155,	156,	157,	158,	159,	
	160,	27,	216,	31,	164,	13,	3,	167,	
	168,	13,	25,	13,	3,	173,	13,	21,	
	176,	27,	219,	31,	180,	13,	3,	199,	
	184,	13,	25,	13,	3,	221,	13,	21,	
	3,	3,	11,	15,	9,	3,	21,	25,	
	13,	3,	27,	21,	13,	3,	7,	13,	
	31,	21,	13,	3,	7,	17,	9,	215,	
	13,	5,	3,	17,	9,	3,	25,	0,	
	3,	3,	11,	15,	9,	3,	21,	25,	
	13,	3,	27,	21,	13,	3,	7,	13,	
	31,	21,	13,	3,	7,	17,	9,	247,	
	13,	5,	3,	17,	9,	3,	25,	217,
	1,	1,	1}
      }

  }

,

  { // Czech standard

    4, //collationNPasses[2],
    259,
    3,
    0,
    1,
    {
      {'c','h'},
      {'C','h'},
      {'C','H'}
    },
    {256,  257,  258},
    {
      {	0,	0,	0,	0,	0,	0,	0,	0,	
	0,	4,	4,	4,	4,	4,	0,	0,	
	0,	0,	0,	0,	0,	0,	0,	0,	
	0,	0,	0,	0,	0,	0,	0,	0,	
	4,	0,	0,	0,	0,	0,	0,	0,	
	0,	0,	0,	0,	0,	0,	0,	0,	
	36,	37,	38,	39,	40,	41,	42,	43,	
	44,	45,	0,	0,	0,	0,	0,	0,	
	0,	5,	6,	7,	9,	10,	11,	12,	
	13,	15,	16,	17,	18,	19,	20,	21,	
	22,	23,	24,	26,	28,	29,	30,	31,	
	32,	33,	34,	0,	0,	0,	0,	0,	
	0,	5,	6,	7,	9,	10,	11,	12,	
	13,	15,	16,	17,	18,	19,	20,	21,	
	22,	23,	24,	26,	28,	29,	30,	31,	
	32,	33,	34,	0,	0,	0,	0,	0,	
	48,	53,	53,	55,	53,	53,	55,	55,	
	53,	55,	53,	55,	55,	55,	55,	55,	
	46,	54,	54,	56,	54,	56,	56,	56,	
	54,	56,	56,	56,	56,	56,	56,	56,	
	4,	5,	0,	18,	0,	18,	26,	0,	
	0,	27,	26,	28,	34,	0,	35,	34,	
	0,	5,	0,	18,	0,	18,	26,	0,	
	0,	27,	26,	28,	34,	0,	35,	34,	
	24,	5,	5,	5,	5,	18,	7,	7,	
	8,	10,	10,	10,	10,	15,	15,	9,	
	9,	20,	20,	21,	21,	21,	21,	0,	
	25,	29,	29,	29,	29,	33,	28,	26,	
	24,	5,	5,	5,	5,	18,	7,	7,	
	8,	10,	10,	10,	10,	15,	15,	9,	
	9,	20,	20,	21,	21,	21,	21,	0,	
	25,	29,	29,	29,	29,	33,	28,	0,	
	14,	14,	14} 
    ,
      {	0,	0,	0,	0,	0,	0,	0,	0,	
      0,	4,	4,	4,	4,	4,	0,	0,	
      0,	0,	0,	0,	0,	0,	0,	0,	
      0,	0,	0,	0,	0,	0,	0,	0,	
      4,	0,	0,	0,	0,	0,	0,	0,	
      0,	0,	0,	0,	0,	0,	0,	0,	
      1,	1,	1,	1,	1,	1,	1,	1,	
      1,	1,	0,	0,	0,	0,	0,	0,	
      0,	1,	1,	1,	1,	1,	1,	1,	
      1,	1,	1,	1,	1,	1,	1,	1,	
      1,	1,	1,	2,	1,	1,	1,	1,	
      1,	1,	1,	0,	0,	0,	0,	0,	
      0,	1,	1,	1,	1,	1,	1,	1,	
      1,	1,	1,	1,	1,	1,	1,	1,	
      1,	1,	1,	2,	1,	1,	1,	1,	
      1,	1,	1,	0,	0,	0,	0,	0,	
      1,	1,	1,	1,	1,	1,	1,	1,	
      1,	1,	1,	1,	1,	1,	1,	1,	
      1,	1,	1,	1,	1,	1,	1,	1,	
      1,	1,	1,	1,	1,	1,	1,	1,	
      4,	6,	0,	4,	0,	3,	3,	0,	
      0,	1,	4,	2,	2,	0,	1,	3,	
      0,	6,	0,	4,	0,	3,	3,	0,	
      0,	1,	4,	2,	2,	0,	1,	3,	
      2,	2,	3,	4,	5,	2,	2,	3,	
      1,	2,	5,	4,	3,	2,	3,	3,	
      2,	3,	2,	2,	3,	5,	4,	0,	
      1,	3,	2,	5,	4,	2,	3,	1,	
      2,	2,	3,	4,	5,	2,	2,	3,	
      1,	2,	5,	4,	3,	2,	3,	3,	
      2,	3,	2,	2,	3,	5,	4,	0,	
      1,	3,	2,	5,	4,	2,	3,	0,	
      1,	1,	1}
    ,
      {	0,	0,	0,	0,	0,	0,	0,	0,	
      0,	7,	3,	1,	4,	2,	0,	0,	
      0,	0,	0,	0,	0,	0,	0,	0,	
      0,	0,	0,	0,	0,	0,	0,	0,	
      5,	0,	0,	0,	0,	0,	0,	0,	
      0,	0,	0,	0,	0,	0,	0,	0,	
      1,	1,	1,	1,	1,	1,	1,	1,	
      1,	1,	0,	0,	0,	0,	0,	0,	
      0,	2,	2,	2,	2,	2,	2,	2,	
      2,	2,	2,	2,	2,	2,	2,	2,	
      2,	2,	2,	2,	2,	2,	2,	2,	
      2,	2,	2,	0,	0,	0,	0,	0,	
      0,	1,	1,	1,	1,	1,	1,	1,	
      1,	1,	1,	1,	1,	1,	1,	1,	
      1,	1,	1,	1,	1,	1,	1,	1,	
      1,	1,	1,	0,	0,	0,	0,	27,	
      6,	4,	5,	3,	6,	2,	1,	5,	
      3,	4,	1,	8,	2,	6,	7,	9,	
      8,	2,	3,	5,	4,	2,	3,	7,	
      1,	6,	1,	10,	4,	8,	9,	11,	
      6,	2,	0,	2,	0,	2,	2,	0,	
      0,	2,	2,	2,	2,	0,	2,	2,	
      0,	1,	0,	1,	0,	1,	1,	0,	
      0,	1,	1,	1,	1,	0,	1,	1,	
      2,	2,	2,	2,	2,	2,	2,	2,	
      2,	2,	2,	2,	2,	2,	2,	2,	
      2,	2,	2,	2,	2,	2,	2,	0,	
      2,	2,	2,	2,	2,	2,	2,	1,	
      1,	1,	1,	1,	1,	1,	1,	1,	
      1,	1,	1,	1,	1,	1,	1,	1,	
      1,	1,	1,	1,	1,	1,	1,	0,	
      1,	1,	1,	1,	1,	1,	1,	0,	
      1,	2,	3}
    ,
      {0,	0,	0,	0,	0,	0,	0,	0,	
      0,	255,	255,	255,	255,	255,	0,	0,	
      0,	0,	0,	0,	0,	0,	0,	0,	
      0,	0,	0,	0,	0,	0,	0,	0,	
      255,	10,	14,	64,	52,	48,	44,	74,	
      28,	30,	66,	62,	4,	18,	2,	24,	
      255,	255,	255,	255,	255,	255,	255,	255,	
      255,	255,	12,	6,	36,	60,	38,	8,	
      58,	255,	255,	255,	255,	255,	255,	255,	
      255,	255,	255,	255,	255,	255,	255,	255,	
      255,	255,	255,	255,	255,	255,	255,	255,	
      255,	255,	255,	32,	26,	34,	84,	56,	
      76,	255,	255,	255,	255,	255,	255,	255,	
      255,	255,	255,	255,	255,	255,	255,	255,	
      255,	255,	255,	255,	255,	255,	255,	255,	
      255,	255,	255,	40,	22,	42,	78,	255,	
      54,	255,	255,	255,	255,	255,	255,	255,	
      255,	255,	255,	255,	255,	255,	255,	255,	
      16,	255,	255,	255,	255,	255,	255,	255,	
      255,	255,	255,	255,	255,	255,	255,	255,	
      255,	255,	86,	255,	50,	255,	255,	46,	
      90,	255,	255,	255,	255,	20,	255,	255,	
      72,	255,	94,	255,	82,	255,	255,	88,	
      96,	255,	255,	255,	255,	92,	255,	255,	
      255,	255,	255,	255,	255,	255,	255,	255,	
      255,	255,	255,	255,	255,	255,	255,	255,	
      255,	255,	255,	255,	255,	255,	255,	68,	
      255,	255,	255,	255,	255,	255,	255,	255,	
      255,	255,	255,	255,	255,	255,	255,	255,	
      255,	255,	255,	255,	255,	255,	255,	255,	
      255,	255,	255,	255,	255,	255,	255,	70,	
      255,	255,	255,	255,	255,	255,	255,	80,	
      255,	255,	255}

    }

  }

};
//-- Czech collation info END
class  ex_function_explode_varchar : public ex_function_clause {
public:
  ex_function_explode_varchar(OperatorTypeEnum oper_type,
					 short num_operands,
					 Attributes ** attr,
					 Space * space,
					 NABoolean forInsert);

  ex_function_explode_varchar();


  // Null Semantics
  //
  Int32 isNullInNullOut() const { return 0; };
  Int32 isNullRelevant() const { return 1; };

  // Execution
  //
  Int32 isEvalRelevant() const { return 1; };

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);
  
  virtual ex_expr::exp_return_type processNulls(char *op_data[],
							   CollHeap * = 0,
							   ComDiagsArea ** = 0);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------

private:
  Int32            forInsert_;           // 00-03
  // ---------------------------------------------------------------------
  // Fillers for potential future extensions without changing class size.
  // When a new member is added, size of this filler should be reduced so
  // that the size of the object remains the same (and is modulo 8).
  // ---------------------------------------------------------------------
  char             fillers_[4];          // 04-07

};

class  ex_function_hash : public ex_function_clause {
public:
  ex_function_hash(OperatorTypeEnum oper_type,
			      Attributes ** attr,
			      Space * space);
  ex_function_hash();


  Int32 isNullInNullOut() const { return 0; };
  Int32 isNullRelevant() const { return 0; };
  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);
  Long pack(void *);
  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
  
private:
  // ---------------------------------------------------------------------
  // Fillers for potential future extensions without changing class size.
  // When a new member is added, size of this filler should be reduced so
  // that the size of the object remains the same (and is modulo 8).
  // ---------------------------------------------------------------------
  char          fillers_[8];                // 00-07
  ULng32 HashHash(ULng32 inValue);

};

class  ex_function_hivehash : public ex_function_clause {
public:
  ex_function_hivehash(OperatorTypeEnum oper_type,
			      Attributes ** attr,
			      Space * space);
  ex_function_hivehash();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);
  Long pack(void *);
  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f)
    { return ex_clause::pCodeGenerate(space, f); };

  virtual unsigned char getClassVersionID() { return 1; }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }


  virtual short getClassSize() { return (short)sizeof(*this); }
  
protected:

  virtual Lng32 hashForCharType(char*, Lng32);


private:
  char          fillers_[8];                // 00-07

};

class ExHashComb : public ex_function_clause {
public:
  ExHashComb(OperatorTypeEnum oper_type,
                        Attributes ** attr,
                        Space * space);
  ExHashComb();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);
  Long pack(void *);
  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class ExHiveHashComb : public ex_function_clause {
public:
  ExHiveHashComb(OperatorTypeEnum oper_type,
                        Attributes ** attr,
                        Space * space);
  ExHiveHashComb();


  virtual unsigned char getClassVersionID() { return 1; }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);
  Long pack(void *);
  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f)
    { return ex_clause::pCodeGenerate(space, f); };

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

// 256 pregenerated randome 32-bit values.
// Do not edit.
static const ULng32 randomHashValues[256] = {
    0x905ebe29, 0x95ff0b84, 0xe5357ed6, 0x2cffae90,
    0x8350b3f1, 0x1748a7eb, 0x2a0695db, 0x1e7ca00c,
    0x60f80c24, 0x9a41fe1c, 0xa985a647, 0x0ed7e512,
    0xcd34ef43, 0xe06325a6, 0xecbf735a, 0x76540d38,
    0x35cba55d, 0xff539efc, 0x64545d45, 0xd7112c0d,
    0x17e09e1c, 0x02359d32, 0x45976350, 0xd630a578,
    0x34cd0c12, 0x754546f6, 0x1bf4f249, 0xbc65c34f,
    0x5c932f44, 0x6cb0d8d0, 0xfd0e7030, 0x2b160e3b,
    0x101daff6, 0x25bbcb9d, 0xe7eca21f, 0x6d3b24ca,
    0xaef7e6b9, 0xd212f049, 0x2de2817e, 0x2792bcd5,
    0x67f794b2, 0xaec6f7cc, 0x79a3e367, 0xd5a85114,
    0xa98ecc2d, 0xf373e266, 0x58ae2757, 0xd8faa0ff,
    0x45e7eb61, 0xbd72ba1e, 0xc28f6b16, 0x804bc2e6,
    0xfed74984, 0x881cd177, 0xa02647e8, 0xd799d053,
    0xbe143d12, 0x49177474, 0xbbc0c5f4, 0x99f7fe9f,
    0x24fc1559, 0xce0925cf, 0x1dded5f4, 0x1d1a2cd3,
    0xafe3ef48, 0x6fd5d075, 0x4a63bc1d, 0x93aa36c0,
    0x2942d778, 0xb26a2444, 0x5616cc50, 0x7565c161,
    0xa006197b, 0xee700b07, 0x4a236a82, 0x693db870,
    0x9a919e64, 0x995b05b1, 0xd4659569, 0x90e45846,
    0xbca11996, 0x3e345cd9, 0xb29a9967, 0x7e9e66f7,
    0x9ce136d0, 0xcde74e76, 0xde56e4bb, 0xba4dc6ae,
    0xf9d40779, 0x4e5c0bdb, 0xde14f9e5, 0x278f8745,
    0x13ce0128, 0x8bb308f5, 0x4c41a359, 0x273d1927,
    0x50338e76, 0xdfceb7c2, 0xf1b86f68, 0xc8b12d6a,
    0xf4cb0e08, 0xa74b4b14, 0x81571c6a, 0xebc4a928,
    0x1d6d5fd6, 0x7f4bbc87, 0x61ba542f, 0x9b06d11d,
    0xb53ae1c1, 0xdcc2a6c0, 0x7f04f8a8, 0x8da9d186,
    0xa168e054, 0x21ed0ce7, 0x9ca9e9d1, 0x0e01fb38,
    0xd8b6b1d9, 0xb8d10266, 0x203a9de1, 0x37ba3ffe,
    0x9fefb09f, 0x5e4cb3e2, 0xcecd03b4, 0xcc270838,
    0xa1619089, 0x22995679, 0x6dcd6b78, 0x8c50f9b1,
    0x1c354ada, 0x48a0f13e, 0xca7b4696, 0x5c1fe8bf,
    0xdd0f433f, 0x8aa411f1, 0x149b2ee3, 0x181d16a1,
    0x3b84b01d, 0xee745103, 0x0f230907, 0x663d1014,
    0xd614181b, 0xb1b88cc9, 0x015f672c, 0x660ea636,
    0x4107c7f3, 0x6f0d8afe, 0xf0aeffeb, 0x93b25fa0,
    0x620c9075, 0x155a4d7e, 0x10fdbd73, 0xb162eabe,
    0xaf9605db, 0xba35d441, 0xde327cfa, 0x15a6fd70,
    0x0f2f4b54, 0xfb1b4995, 0xec092e68, 0x37ebade6,
    0x850f63ca, 0xe72a879f, 0xc823f741, 0xc6f114b8,
    0x74e461f6, 0x1d01ad14, 0xfe1ed7d3, 0x306b9444,
    0x9ebd40a6, 0x3275b333, 0xa8540ca1, 0xeb8d394c,
    0xa2aef54c, 0xf12d0705, 0x8974e70e, 0x59ae82cf,
    0x32469aca, 0x973325d8, 0x27ba604d, 0x9aeb7827,
    0xaf0af97c, 0x9783e6f8, 0xe0725a87, 0x2f02d864,
    0x717a0587, 0x0c90d7b0, 0x6828b84e, 0xba08ebe7,
    0x65cf8360, 0x63132f80, 0xbb8d4a41, 0xbd5b8b41,
    0x459f019f, 0x5e68369f, 0xe855f000, 0xa79a634c,
    0x172c7704, 0x07337ab3, 0xb2926453, 0x11084c8a,
    0x328689ca, 0xa7e3efcf, 0x8b9a5695, 0x76b65bbe,
    0x87bb5a2a, 0x5f73e6ad, 0xcf59b265, 0x4fe46ec9,
    0x52561232, 0x70db002c, 0xc21d1b8f, 0xd7ceb1c6,
    0xff4a97c8, 0xdd21c90b, 0x48c14c38, 0x64262c68,
    0x74c5d3f9, 0x66bf60e7, 0xce804348, 0x98585792,
    0x7619fc86, 0x91de3f72, 0x57f5191c, 0x576d9737,
    0x5f4535b0, 0xb9ee8ef5, 0x2e9eff6c, 0xc7c9f874,
    0xe6ac0843, 0xd93b8c08, 0x2f34a779, 0x407799eb,
    0x2b9904e0, 0x14bb018f, 0x1fcf367b, 0x7975c362,
    0xba31448f, 0xa59286f7, 0x1255244a, 0xd685169b,
    0xc791ec84, 0x3b5461b1, 0x4822924a, 0x26d86175,
    0x596e6b2f, 0x6a157bef, 0x8bc98a9b, 0xa8220343,
    0x91eaad8a, 0x42b89a9e, 0x7c9b5f81, 0xb5f9ec6c,
    0xd999ef9e, 0xa547f6a3, 0xc391f010, 0xe9d8bb43
  };


// The following two classes (ExHDPHash and ExHDPHashComb) are used by
// the HashDistPartitioningFunction.  They are isolated from the other
// general purpose versions of these functions so that they won't be
// inadvertently altered.  Any changes these functions that results in
// a different runtime behavior will cause existing hash partitioned
// tables to be invalid.
//
// Hash Function 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.
//
class ExHDPHash : public ex_function_clause {
public:
  ExHDPHash(OperatorTypeEnum oper_type,
                       Attributes ** attr,
                       Space * space);
  ExHDPHash();


  enum
  {
    NO_FLAGS      = 0x0000,
    SWAP_TWO      = 0x0001,
    SWAP_FOUR     = 0x0002,
    SWAP_EIGHT    = 0x0004,
    SWAP_FIRSTTWO = 0x0008,
    SWAP_LASTFOUR = 0x0010
  };


  Int32 isNullInNullOut() const { return 0; };
  Int32 isNullRelevant() const { return 0; };
  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);
  Long pack(void *);
  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  static ULng32 hash(const char *data, UInt32 flags, Int32 length);

  static UInt64 hashP(const unsigned char *src1,
                                             const unsigned char *src2,
                                             Int32 len1, Int32 len2)
  {
    Int32 i = 0;
    ULng32 hash1 = 0;
    ULng32 hash2 = 0;

    // Loop over all the bytes of the value and compute the hash value.
    for(; i < len1; i++) {
      // Make sure the hashValue is sensitive to the byte position.
      // One bit circular shift.
      hash1 = (hash1 << 1 | hash1 >> 31);
      hash2 = (hash2 << 1 | hash2 >> 31);

      hash1 = hash1 ^ randomHashValues[*src1++];
      hash2 = hash2 ^ randomHashValues[*src2++];
    }

    for(; i < len2; i++) {
      hash2 = (hash2 << 1 | hash2 >> 31) ^ randomHashValues[*src2++];
    }

    return (((UInt64)hash1 << 32) | hash2);
  }

  // Hash an 8 byte long key
  static ULng32 hash8(const char *data, UInt32 flags)
  {
    unsigned char *valp = (unsigned char *)data;
    ULng32 hashValue = 0;

    switch(flags) {
    case NO_FLAGS:
      {
        hashValue = randomHashValues[*valp++];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*valp++];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*valp++];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*valp++];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*valp++];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*valp++];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*valp++];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*valp++];
        break;
      }
    case SWAP_TWO:
      {
    
        hashValue = randomHashValues[*(valp+1)];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*(valp+0)];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*(valp+3)];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*(valp+2)];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*(valp+5)];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*(valp+4)];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*(valp+7)];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*(valp+6)];
        break;
      } 
    case SWAP_EIGHT:
      {
        valp += 8;
    
        hashValue = randomHashValues[*--valp];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*--valp];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*--valp];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*--valp];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*--valp];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*--valp];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*--valp];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*--valp];
        break;
      } 
    default:
      assert(FALSE);
      break;
    }
    return hashValue;
  }
  
  // Hash a 4-byte long key
  static ULng32 hash4(const char *data, UInt32 flags)
  {
    unsigned char *valp = (unsigned char *)data;
    ULng32 hashValue = 0;
    
    switch(flags) {
    case NO_FLAGS:
      {
        hashValue = randomHashValues[*valp++];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*valp++];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*valp++];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*valp++];
        break;
      }
    case SWAP_TWO:
      {
    
        hashValue = randomHashValues[*(valp+1)];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*(valp+0)];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*(valp+3)];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*(valp+2)];
        break;
      }
    case SWAP_FOUR:
      {
        valp += 4;
        hashValue = randomHashValues[*--valp];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*--valp];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*--valp];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*--valp];
        break;
      } 
    default:
      assert(FALSE);
      break;
    }
    return hashValue;
  }
  
  // Hash a 2-byte long key
  static ULng32 hash2(const char *data, UInt32 flags)
  {
    unsigned char *valp = (unsigned char *)data;
    ULng32 hashValue = 0;

    switch(flags) {
    case NO_FLAGS:
      {
        hashValue = randomHashValues[*valp++];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*valp++];
        break;
      }
    case SWAP_TWO:
      {
        valp += 2;
        hashValue = randomHashValues[*--valp];
        hashValue = (hashValue << 1 | hashValue >> 31) ^ randomHashValues[*--valp];
        break;
      } 
    default:
      assert(FALSE);
      break;
    }
    return hashValue;
  }

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
  
  static const UInt32 nullHashValue = 666654765;
private:
  // ---------------------------------------------------------------------
  // Fillers for potential future extensions without changing class size.
  // When a new member is added, size of this filler should be reduced so
  // that the size of the object remains the same (and is modulo 8).
  // ---------------------------------------------------------------------
  char          fillers_[8];                // 00-07
};

// 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.
//
class ExHDPHashComb : public ex_function_clause {
public:
  ExHDPHashComb(OperatorTypeEnum oper_type,
                           Attributes ** attr,
                           Space * space);
  ExHDPHashComb();


  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ex_function_replace_null : public ex_function_clause {
public:
  ex_function_replace_null(OperatorTypeEnum oper_type,
				      Attributes ** attr,
				      Space * space);
  ex_function_replace_null();


  Int32 isNullInNullOut() const { return 0; };
  Int32 isNullRelevant() const { return 0; };
  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);
  ex_expr::exp_return_type processNulls(char *op_data[], CollHeap*,
                                                   ComDiagsArea** = 0);
  Long pack(void *);
  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
  
private:
  // ---------------------------------------------------------------------
  // Fillers for potential future extensions without changing class size.
  // When a new member is added, size of this filler should be reduced so
  // that the size of the object remains the same (and is modulo 8).
  // ---------------------------------------------------------------------
  char          fillers_[8];                // 00-07

};

class  ex_function_mod : public ex_function_clause {
public:
  ex_function_mod(OperatorTypeEnum oper_type,
			     Attributes ** attr,
			     Space * space);
  ex_function_mod();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);
  Long pack(void *);
  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ex_function_mask : public ex_function_clause {
public:
  ex_function_mask(OperatorTypeEnum oper_type,
                              Attributes ** attr,
                              Space * space);
  ex_function_mask();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);
  Long pack(void *);
//  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ExFunctionShift : public ex_function_clause {
public:
  ExFunctionShift(OperatorTypeEnum oper_type,
                             Attributes ** attr,
                             Space * space);
  ExFunctionShift();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);
  Long pack(void *);
//  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

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


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);
  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ex_function_converttimestamp : public ex_function_clause {
public:
  ex_function_converttimestamp(OperatorTypeEnum oper_type,
					  Attributes ** attr, 
					  Space * space);
  ex_function_converttimestamp();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);
  
  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ex_function_dateformat : public ex_function_clause {
public:
  ex_function_dateformat(OperatorTypeEnum oper_type,
				    Attributes ** attr, 
				    Space * space, Int32 dateformat);
  ex_function_dateformat();

 void displayContents(Space * space, const char * displayStr, 
                      Int32 clauseNum, char * constsArea);

  inline Int32 getDateFormat() const { return dateformat_; }
  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
  
private:
  // formats defined in class ExpDatetime in exp/exp_datetime.h
  Int32            dateformat_;          // 00-03
  // ---------------------------------------------------------------------
  // Fillers for potential future extensions without changing class size.
  // When a new member is added, size of this filler should be reduced so
  // that the size of the object remains the same (and is modulo 8).
  // ---------------------------------------------------------------------
  char             fillers_[4];          // 04-07
};

class  ex_function_dayofweek : public ex_function_clause {
public:
  ex_function_dayofweek(OperatorTypeEnum oper_type,
				   Attributes ** attr, 
				   Space * space);
  ex_function_dayofweek();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);
  
  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ex_function_extract : public ex_function_clause {
public:
  ex_function_extract(OperatorTypeEnum oper_type,
				 Attributes ** attr, 
				 Space * space, rec_datetime_field extractField);
  ex_function_extract();


  rec_datetime_field getExtractField() const
    { return (rec_datetime_field)extractField_; }

  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
  
private:
  Int16 /*rec_datetime_field*/ extractField_; // 00-01
  // ---------------------------------------------------------------------
  // Fillers for potential future extensions without changing class size.
  // When a new member is added, size of this filler should be reduced so
  // that the size of the object remains the same (and is modulo 8).
  // ---------------------------------------------------------------------
  char                         fillers_[6];   // 02-07
};

class  ex_function_juliantimestamp : public ex_function_clause {
public:
  ex_function_juliantimestamp(OperatorTypeEnum oper_type,
					 Attributes ** attr, 
					 Space * space);
  ex_function_juliantimestamp();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ex_function_exec_count : public ex_function_clause {
public:
  ex_function_exec_count(OperatorTypeEnum oper_type,
				    Attributes ** attr, 
				    Space * space);
  ex_function_exec_count();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------

private:

  // NOTE: keeping this count in the clause means that it is shared
  // among all statements that refer to this expression (e.g.
  // in a multi-threaded environment). The only problem with this
  // is that a statement must not rely on the counts being
  // the true number of executions. Each statement will still get
  // a unique, increasing count each time it executes, but the
  // number may sometimes increase by more than 1 between executions.
  Int64            execCount_;           // 00-07
  // ---------------------------------------------------------------------
  // Fillers for potential future extensions without changing class size.
  // When a new member is added, size of this filler should be reduced so
  // that the size of the object remains the same (and is modulo 8).
  // ---------------------------------------------------------------------
  char          fillers_[8];             // 08-15

};

class  ex_function_curr_transid : public ex_function_clause {
public:
  ex_function_curr_transid(OperatorTypeEnum oper_type,
				      Attributes ** attr, 
				      Space * space);
  ex_function_curr_transid();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

// Helper routines used by ansi_user::eval and MXUDR code to obtain
// CURRENT_USER or SESSION_USER value. Not used by DP2.

short exp_function_get_user(
     OperatorTypeEnum user_type,
     char *userNameBuffer,
     Lng32 inputBufferLength,
     Lng32 *actualLength);       // OUT optional

class  ex_function_ansi_user : public ex_function_clause {
public:
  ex_function_ansi_user(OperatorTypeEnum oper_type,
				   Attributes ** attr,
				   Space * space);
  ex_function_ansi_user();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ex_function_user : public ex_function_clause {
public:
  ex_function_user(OperatorTypeEnum oper_type,
			      Attributes ** attr,
			      Space * space);
  ex_function_user();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ExpRaiseErrorFunction : public ex_function_clause {

public:
  ExpRaiseErrorFunction (Attributes ** attr,
				    Space *space,
				    Lng32 sqlCode,
				    NABoolean raiseError = TRUE,
				    const char *constraintName=NULL,
				    const char *tableName=NULL,
					const NABoolean hasStringExp=FALSE);  // -- Triggers
  ExpRaiseErrorFunction();
 
 
  //isNullInNullOut() const { return 0;};
  //isNullRelevant() const {return 0;};
  ex_expr::exp_return_type eval(char *op_data[], CollHeap*,
					    ComDiagsArea** = 0);
  Long pack(void *);
  Lng32 unpack(void *, void * reallocator);
  
  Lng32 getSQLCODE() {return theSQLCODE_;};
  const char *getConstraintName() {return constraintName_;};
  void setConstraintName(const char * constraintName) 
  { constraintName_ = (char*)constraintName;};
  const char *getTableName() {return tableName_;};
  void setTableName(const char * tableName) 
  { tableName_ = (char*)tableName;};

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  inline NABoolean raiseError(void)
  {
    return ((flags_ & RAISE_ERROR) != 0);
  };

  inline void setRaiseError(NABoolean v)
  {
    (v)? flags_ |= RAISE_ERROR: flags_ &= ~RAISE_ERROR;
  };

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------

private:
  enum
  {
    RAISE_ERROR	=0x00000001	// Raise Error if set, or it's warning
  };

  NABasicPtr /*const char* */ constraintName_; // 00-07
  NABasicPtr /*const char* */ tableName_;      // 08-15
  Int32                       theSQLCODE_;     // 16-19
  Int32                       flags_;          // 20-23
  // TRUE, raise error. FALSE, raise warning.
  // ---------------------------------------------------------------------
  // Fillers for potential future extensions without changing class size.
  // When a new member is added, size of this filler should be reduced so
  // that the size of the object remains the same (and is modulo 8).
  // ---------------------------------------------------------------------
  char          fillers_[8];                   // 24-31

};

class  ExFunctionSVariance : public ex_function_clause {
public:
  ExFunctionSVariance(Attributes **attr, Space *space);

  ExFunctionSVariance();


  ex_expr::exp_return_type eval(char *op_data[],
				CollHeap *, 
				ComDiagsArea** diagsArea = 0);
  Long pack(void *space);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ExFunctionSStddev : public ex_function_clause {
public:
  ExFunctionSStddev(Attributes **attr, Space *space);

  ExFunctionSStddev();


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

  Long pack(void *space);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

// class ExUnPackCol ----------------------------------------------
// This function clause implements the UnPackCol ItemExpr.  It is used
// to extract column values from a packed row.  The data members of
// this class are:
//
//   long width_: The width of the data to be extracted (in BITS).
//
//   long base_: The offset of the Data section of the packed row (in BYTES).
//
//   nullsPresent_: If TRUE, a NULL Bitmap section of the packed row is
//   present.
//
// This node has two children. The first is the source packed row and is
// of type char(n) not null, the second is the index into the packed row 
// and is of type int not null.
//
class  ExUnPackCol : public ex_function_clause {
public:
  ExUnPackCol(Attributes **attr,
              Space *space,
              Lng32 width,
              Lng32 base,
              NABoolean nullsPresent);

  ExUnPackCol();


  // Null Semantics
  //
  // NullInNullOut also implies, NotNullInNotNullOut. Since
  // this clause does not have NULL in, but can have NULL out,
  // This method must return 0.
  //
  Int32 isNullInNullOut() const { return 0; };

  // This clause handles all NULL processing in the eval()
  // method.
  //
  Int32 isNullRelevant() const { return 0; };

  // This is where all the work is done.
  //
  ex_expr::exp_return_type eval(char *op_data[],
                                CollHeap *, 
                                ComDiagsArea** diagsArea = 0);

  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  // This is a different kind of packing, done to relocate the
  // expressions.
  //
  Long pack(void *space);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  inline NABoolean nullsPresent(void) const
  {
    return ((flags_ & NULLS_PRESENT) != 0);
  };

  inline void setNullsPresent(NABoolean v)
  {
    (v)? flags_ |= NULLS_PRESENT: flags_ &= ~NULLS_PRESENT;
  };

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------

private:
  enum
  {
    NULLS_PRESENT = 0x00000001 		// Nulls present if set
  };

  // The width of the data to be extracted. (in BITS).
  //
  Int32               width_;            // 00-03

  // The offset to the Data section of the packed row (in BYTES).
  //
  Int32               base_;             // 04-07

  // If TRUE, a NULL Bitmap is present in the packed row.
  //
  Int32		     flags_;             // 08-11
  // ---------------------------------------------------------------------
  // Fillers for potential future extensions without changing class size.
  // When a new member is added, size of this filler should be reduced so
  // that the size of the object remains the same (and is modulo 8).
  // ---------------------------------------------------------------------
  char             fillers_[4];          // 12-15

};

class  ExFunctionRandomNum : public ex_function_clause {
public:
  ExFunctionRandomNum(OperatorTypeEnum opType, 
		      short num_operands,
		      NABoolean simpleRandom,
		      Attributes **attr, Space *space);

  ExFunctionRandomNum();


  void genRand(char *op_data[]);

  Lng32 getRand() { return seed_; };

  
  virtual ex_expr::exp_return_type eval(char *op_data[],
				        CollHeap *,
                                        ComDiagsArea** diagsArea = 0);

  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  Long pack(void *space);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }

  // ---------------------------------------------------------------------

private:
  enum
  {
    SIMPLE_RANDOM = 0x0001
  };

  void initSeed(char *op_data[]);

  NABoolean simpleRandom() { return (flags_ & SIMPLE_RANDOM) != 0; }

  Int32            seed_;                // 00-03

  Int16            flags_;               // 04-05
  // ---------------------------------------------------------------------
  // Fillers for potential future extensions without changing class size.
  // When a new member is added, size of this filler should be reduced so
  // that the size of the object remains the same (and is modulo 8).
  // ---------------------------------------------------------------------
  char             fillers_[2];          // 06-07

};

class  ExFunctionRandomSelection : public ExFunctionRandomNum {
public:
  
  
  ExFunctionRandomSelection (OperatorTypeEnum opType,
                             Attributes ** attr, 
                             Space * space, 
                             float selProb
                            );
  
  ExFunctionRandomSelection ();
 
  
  
  virtual ex_expr::exp_return_type eval(char *op_data[], 
                                        CollHeap*, 
                                        ComDiagsArea** = 0);  

  
  Long pack(void *);
  
private:
  //TODO: when ready to require dp2 rebuild
  //virtual short getClassSize() { return (short)sizeof(*this); }

  void initDiff();

  Float32	selProbability_;		// 00-03
  Int32		difference_;			// 04-07
  Int32		normProbability_;		// 08-11

  // ---------------------------------------------------------------------
  // Fillers for potential future extensions without changing class size.
  // When a new member is added, size of this filler should be reduced so
  // that the size of the object remains the same (and is modulo 8).
  // ---------------------------------------------------------------------
  char          fillers_[12];         	  	// 12-23
};

// MV,
class  ExFunctionGenericUpdateOutput : public ex_function_clause {
public:
  ExFunctionGenericUpdateOutput(OperatorTypeEnum oper_type,
				 Attributes ** attr,
				 Space * space);
  ExFunctionGenericUpdateOutput();
  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);
  Long pack(void *space);
  virtual short getClassSize() { return (short)sizeof(*this); }

};

// ++ Triggers -
class  ExFunctionInternalTimestamp : public ex_function_clause {
public:
  ExFunctionInternalTimestamp(OperatorTypeEnum oper_type,
				 Attributes ** attr,
				 Space * space);
  ExFunctionInternalTimestamp();
  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);
  Long pack(void *space);
  
};


class  ExHash2Distrib : public ex_function_clause {
public:
  ExHash2Distrib(Attributes **attr, Space *space);

  ExHash2Distrib();


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

  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);
  Long pack(void *space);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ExProgDistrib : public ex_function_clause {
public:
  ExProgDistrib(Attributes **attr, Space *space);

  ExProgDistrib();


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

  Long pack(void *space);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ExProgDistribKey : public ex_function_clause {
public:
  ExProgDistribKey(Attributes **attr, Space *space);

  ExProgDistribKey();


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

  Long pack(void *space);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ExPAGroup : public ex_function_clause {
public:
  ExPAGroup(Attributes **attr, Space *space);

  ExPAGroup();


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

  Long pack(void *space);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------
};

class  ExFunctionPack : public ex_function_clause
{
public:
  ExFunctionPack(Attributes** attr, Space* space, Lng32 width, Lng32 base,
                 NABoolean nullsPresent);

  ExFunctionPack();


  Int32 isNullInNullOut() const { return 0; }

  // Processing of null is in eval().
  Int32 isNullRelevant() const { return 0; }

  Int32 isEvalRelevant() const { return 1; }

  // ex_expr::exp_return_type processNulls(char *op_data[], 
  //						      CollHeap*, 
  //						      ComDiagsArea** = 0);

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

  Long pack(void* space);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  inline NABoolean nullsPresent(void)
  {
    return ((flags_ & NULLS_PRESENT) != 0);
  };

  inline void setNullsPresent(NABoolean v)
  {
    (v)? flags_ |= NULLS_PRESENT: flags_ &= ~NULLS_PRESENT;
  };

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------

private:
  enum
  {
    NULLS_PRESENT = 0x00000001 		// Nulls present if set
  };

  Int32               width_;            // 00-03
  Int32               base_;             // 04-07
  Int32               flags_;            // 08-11
  // ---------------------------------------------------------------------
  // Fillers for potential future extensions without changing class size.
  // When a new member is added, size of this filler should be reduced so
  // that the size of the object remains the same (and is modulo 8).
  // ---------------------------------------------------------------------
  char                fillers_[4];       // 12-15
};

class ExFunctionRangeLookup : public ex_function_clause
{
public:
  ExFunctionRangeLookup(Attributes** attr,
			Space* space,
			Lng32 numParts,
			Lng32 partKeyLen);

  ExFunctionRangeLookup();


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

  Long pack(void* space);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------

private:
  Int32            numParts_;            // 00-03
  Int32            partKeyLen_;          // 04-07

  // ---------------------------------------------------------------------
  // Fillers for potential future extensions without changing class size.
  // When a new member is added, size of this filler should be reduced so
  // that the size of the object remains the same (and is modulo 8).
  // ---------------------------------------------------------------------
  char          fillers_[8];             // 08-15

};


// class ExRowsetArrayScan
// The ExRowsetArrayScan class is the physical implementation of the 
// RowsetArrayScan node which is used to extract an element of a Rowset
// array. 
// Items of this type are attached to the UnpackRows node at bind time.
// When the generator finds an UnpackRows node, it creates an
// PhysUnPackRows node, and when it finds an RowsetArrayScan item, it
// generates a ExRowsetArrayScan node. At run time, each ExRowsetArrayScan
// node is evaluated and the corresponding element is returned by the
// PhysUnPackRows node to its parent.
// This class is derived from the ex_function_clause and has two children.
// The first child is the host variable array and the second child is
// the host variable used at execution time to index the array. 

class ExRowsetArrayScan : public ex_function_clause {
public:
  ExRowsetArrayScan(Attributes **attr,
                    Space     *space,
                    Lng32      maxNumElem,
                    Lng32      elemSize,
                    NABoolean elemNullInd);

  ExRowsetArrayScan();


  // This clause handles all NULL processing in the eval()
  // method.
  //
  Int32 isNullRelevant() const { return 0; };
    ex_expr::exp_return_type eval(char *op_data[],
                                  CollHeap *, 
                                  ComDiagsArea** diagsArea = 0);
  Long pack(void *space);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------

private:
  Int32        maxNumElem_;  // Maximum number of elements          // 00-03
  Int32        elemSize_;    // Element storage length in bytes     // 04-07
  Int32        elemNullInd_; // Null Present ?                      // 08-11
  char         fillersRowset_[4];                                   // 12-15

};

class ExRowsetArrayRowid : public ex_function_clause {
public:
  ExRowsetArrayRowid(Attributes **attr,
                     Space     *space,
                     Lng32      maxNumElem);

  ExRowsetArrayRowid();


  // This clause handles all NULL processing in the eval()
  // method.
  //
  Int32 isNullRelevant() const { return 0; };
    ex_expr::exp_return_type eval(char *op_data[],
                                  CollHeap *, 
                                  ComDiagsArea** diagsArea = 0);

  Long pack(void *space);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }
  // ---------------------------------------------------------------------

private:
  Int32        maxNumElem_;  // Maximum number of elements          // 00-03
  char         fillersRowset_[4];                                   // 04-07

};

class ExRowsetArrayInto : public ex_function_clause
{
public:
  ExRowsetArrayInto(Attributes **attr,
                    Space     *space,
                    Lng32      maxNumElem,
                    Lng32      elemSize,
                    NABoolean elemNullInd);

  ExRowsetArrayInto();


  // This clause handles all NULL processing in the eval()
  // method.
  //
  Int32 isNullRelevant() const { return 0; };
  Int32 isEvalRelevant() const { return 1; }
    ex_expr::exp_return_type eval(char *op_data[],
                                  CollHeap *, 
                                  ComDiagsArea** diagsArea = 0);

  // ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  Long pack(void *space);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize() { return (short)sizeof(*this); }

  virtual Int32 getElemSize() 
  {
    return elemSize_;
  }

  virtual Int32 getElemNullInd() 
  {
    return elemNullInd_;
  }

  // ---------------------------------------------------------------------

private:
  Int32        maxNumElem_;  // Maximum number of elements          // 00-03
  Int32        numElem_;     // Actual number of elements           // 04-07
  Int32        elemSize_;    // Element storage length in bytes     // 08-11
  Int32        elemNullInd_; // Null Present ?                      // 12-15

  // ---------------------------------------------------------------------
  // Fillers for potential future extensions without changing class size.
  // When a new member is added, size of this filler should be reduced so
  // that the size of the object remains the same (and is modulo 8).
  // ---------------------------------------------------------------------
  char          fillers_[8];               			    // 16-23

};

class  ex_function_nullifzero : public ex_function_clause {
public:
  ex_function_nullifzero(OperatorTypeEnum oper_type,
				    Attributes ** attr,
				    Space * space);
  ex_function_nullifzero();


  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  virtual short getClassSize() { return (short)sizeof(*this); }

private:
  char fillers_[64];
  // ---------------------------------------------------------------------
};

class  ex_function_nvl : public ex_function_clause {
public:
  ex_function_nvl(OperatorTypeEnum oper_type,
			     Attributes ** attr,
			     Space * space);
  ex_function_nvl();


  ex_expr::exp_return_type pCodeGenerate(Space *space, UInt32 f);

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  virtual short getClassSize() { return (short)sizeof(*this); }

  // This clause handles all NULL processing in the eval() method.
  Int32 isNullRelevant() const { return 0; };

private:
  char fillers_[64];
  // ---------------------------------------------------------------------
};

class  ex_function_json_object_field_text : public ex_function_clause {
public:
  ex_function_json_object_field_text(OperatorTypeEnum oper_type,
			     Attributes ** attr,
			     Space * space);
  ex_function_json_object_field_text();

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  virtual short getClassSize() { return (short)sizeof(*this); }

  // This clause handles all NULL processing in the eval() method.
  Int32 isNullRelevant() const { return 0; };

private:
  char fillers_[64];
  // ---------------------------------------------------------------------
};

class  ex_function_queryid_extract : public ex_function_clause {
public:
  ex_function_queryid_extract(OperatorTypeEnum oper_type,
					 Attributes ** attr,
					 Space * space);
  ex_function_queryid_extract();


  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);

  virtual short getClassSize() { return (short)sizeof(*this); }

private:
  char fillers_[64];
  // ---------------------------------------------------------------------
};

class  ExFunctionUniqueId : public ex_function_clause {
public:
  ExFunctionUniqueId(OperatorTypeEnum oper_type,
				Attributes ** attr,
				Space * space);
  ExFunctionUniqueId();

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);
  
  virtual short getClassSize() { return (short)sizeof(*this); }
  
 private:
  char fillers_[64];
  // ---------------------------------------------------------------------
};

class  ExFunctionRowNum : public ex_function_clause {
public:
  ExFunctionRowNum(OperatorTypeEnum oper_type,
				Attributes ** attr,
				Space * space);
  ExFunctionRowNum();

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);
  
  virtual short getClassSize() { return (short)sizeof(*this); }
  
 private:
  char fillers_[64];
  // ---------------------------------------------------------------------
};

class  ExFunctionHbaseColumnLookup : public ex_function_clause {
public:
  ExFunctionHbaseColumnLookup(OperatorTypeEnum oper_type,
					 Attributes ** attr,
					 const char * colName,
					 Space * space);
  ExFunctionHbaseColumnLookup();

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);
  
  virtual short getClassSize() { return (short)sizeof(*this); }

  // This clause handles all NULL processing in the eval() method.
  Int32 isNullRelevant() const { return 0; };
  
  static short extractColFamilyAndName(const char * input, 
                                       short len,
				       NABoolean isVarchar,
				       std::string &colFam, std::string &colName);
 private:
  char colName_[256];
  // ---------------------------------------------------------------------
};

class  ExFunctionHbaseColumnsDisplay : public ex_function_clause {
public:
  ExFunctionHbaseColumnsDisplay(OperatorTypeEnum oper_type,
					   Attributes ** attr,
					   Lng32 numCols,
					   char * colNames,
					   Space * space);
  ExFunctionHbaseColumnsDisplay();

  void init(OperatorTypeEnum oper_type,
	    Attributes ** attr,
	    Lng32 numCols,
	    char * colNames,
	    Space * space);

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);
  Lng32 unpack(void *base, void * reallocator);
  
  virtual short getClassSize() { return (short)sizeof(*this); }

  char * colNames() { return colNames_; }

 private:
  NABoolean toBeDisplayed(char * colName, Lng32 colNameLen);

  Lng32 numCols_;
  char filler1_[4];
  NABasicPtr colNames_;
 
  // ---------------------------------------------------------------------
};

class  ExFunctionHbaseColumnCreate : public ex_function_clause {
public:
  ExFunctionHbaseColumnCreate(OperatorTypeEnum oper_type,
					 Attributes ** attr,
					 short numEntries,
					 short colNameMaxLen,
					 Int32 colValMaxLen,
                                         short colValVCIndLen,
					 Space * space);
  ExFunctionHbaseColumnCreate();

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  Long pack(void *);
  Lng32 unpack(void *base, void * reallocator);

  virtual short getClassSize() { return (short)sizeof(*this); }

 private:
  Lng32 flags_;

  short numEntries_;
  short colNameMaxLen_;
  Int32 colValMaxLen_;
  short colValVCIndLen_; // 2 or 4 bytes
  char filler1_[2];
};

class  ExFunctionCastType : public ex_function_clause {
public:
  ExFunctionCastType(OperatorTypeEnum oper_type,
					 Attributes ** attr,
					 Space * space);
  ExFunctionCastType();

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  //  Long pack(void *);
  
  virtual short getClassSize() { return (short)sizeof(*this); }

 private:
};

class  ExFunctionSequenceValue : public ex_function_clause {
public:
  ExFunctionSequenceValue(OperatorTypeEnum oper_type,
				     Attributes ** attr,
				     const SequenceGeneratorAttributes &sga,
				     Space * space);
  ExFunctionSequenceValue();

  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
					   ComDiagsArea** = 0);  
  //  Long pack(void *);
  
  virtual short getClassSize() { return (short)sizeof(*this); }

  // This clause handles all NULL processing in the eval() method.
  Int32 isNullRelevant() const { return 0; };

  void setIsCurr(NABoolean v)
  {
    (v) ? flags_ |= IS_CURR: flags_ &= ~IS_CURR;
  };

  NABoolean isCurr() { return ((flags_ & IS_CURR) != 0); }

 private:
enum
  {
    IS_CURR = 0x0001
  };

  SequenceGeneratorAttributes sga_;

  UInt32 flags_;
  char filler1_[4];
  // ---------------------------------------------------------------------
};

class ExFunctionHbaseTimestamp : public ex_function_clause {
public:
  ExFunctionHbaseTimestamp(OperatorTypeEnum oper_type,
                           Attributes ** attr,
                           Lng32 colIndex,
                           Space * space);
  ExFunctionHbaseTimestamp();

 void displayContents(Space * space, const char * displayStr, 
                      Int32 clauseNum, char * constsArea);
 
  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
                                ComDiagsArea** = 0);  
  
  virtual short getClassSize() { return (short)sizeof(*this); }

 private:
  Lng32 colIndex_;
  ULng32 flags_;
  // ---------------------------------------------------------------------
};

class ExFunctionHbaseVersion : public ex_function_clause {
public:
  ExFunctionHbaseVersion(OperatorTypeEnum oper_type,
                           Attributes ** attr,
                           Lng32 colIndex,
                           Space * space);
  ExFunctionHbaseVersion();

 void displayContents(Space * space, const char * displayStr, 
                      Int32 clauseNum, char * constsArea);
 
  ex_expr::exp_return_type eval(char *op_data[], CollHeap*, 
                                ComDiagsArea** = 0);  
  
  virtual short getClassSize() { return (short)sizeof(*this); }

 private:
  Lng32 colIndex_;
  ULng32 flags_;
  // ---------------------------------------------------------------------
};

class  ExHeaderClause : public ex_function_clause
{
public:

  ExHeaderClause()
  {}

  ExHeaderClause( Attributes  **attr,
                  Space        *space,
                  UInt16        adminSize,
                  UInt16        entryOffset,
                  UInt16        bitmapOffset,
                  UInt16        firstFixedOffset )
    : ex_function_clause(ITM_HEADER, 1, attr, space),
      adminSz_(adminSize),
      entryOffset_(entryOffset),
      bitmapOffset_(bitmapOffset),
      firstFixedOffset_(firstFixedOffset)
  {}

  virtual ~ExHeaderClause()
  {}

  // Null values aren't relevant for this clause.
  Int32 isNullRelevant() const
  { return 0; };

  // This is where all the work is done.
  //
  ex_expr::exp_return_type eval(char            *op_data[],
                                CollHeap        *heap, 
                                ComDiagsArea   **diagsArea = 0);

  ex_expr::exp_return_type pCodeGenerate(Space  *space,
                                         UInt32  flags);

  // This is a different kind of packing, done to relocate the
  // expressions.
  //
  Long pack(void *space);

  // ---------------------------------------------------------------------
  // Redefinition of methods inherited from NAVersionedObject.
  // ---------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {  return 1; }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(2,getClassVersionID());
    ex_function_clause::populateImageVersionIDArray();
  }

  virtual short getClassSize()
  { return (short)sizeof(*this); }

  NABoolean isSQLMXAlignedFormat()
  {  return(entryOffset_ > 0); }


  // ---------------------------------------------------------------------
private:

  // The complete admin size - header, complete VOA, bitmap, any padding before
  // the first fixed field.
  UInt16   adminSz_;                     // 00-01

  // Actual offset value to where the bitmap resides within the data record.
  // This value is the number of bytes to the start of the bitmap.
  // This value may be 0 if no null columns are present (bitmapSize_ is 0 too),
  // OR if this expression clause is used for SQL
  UInt16   bitmapOffset_;               // 02-03

  // Where in the header the bitmap offset value is written.
  UInt16   entryOffset_;                // 04-05

  // Offset to the first fixed field (may be 0).
  UInt16   firstFixedOffset_;           // 06-07

  // ---------------------------------------------------------------------
  // Fillers for potential future extensions without changing class size.
  // When a new member is added, size of this filler should be reduced so
  // that the size of the object remains the same (and is modulo 8).
  // ---------------------------------------------------------------------
  char          fillers_[8];            // 08-15

};


#ifndef ULONG
  #define ULONG ULng32
#endif


#endif
