/**********************************************************************
// @@@ 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_CLAUSE_H
#define EXP_CLAUSE_H

/* -*-C++-*-
 *****************************************************************************
 *
 * File:         <file>
 * Description:  
 *               
 *               
 * Created:      7/10/95
 * Language:     C++
 *
 *
 *
 *
 *****************************************************************************
 */

#include "ExpError.h"
#include "exp_attrs.h"

#include "Collections.h"
#include "ComSpace.h"
#include "Int64.h"
#include "OperTypeEnum.h"
#include "ExpAtp.h"
#include "exp_expr.h"

// Forware external declaractions
//
class PCILink;

#define ADJUST(offset, alignment) ((offset > 0) ?    \
				   (((offset - 1)/alignment) + 1) * alignment : \
				   offset);

class ex_globals;
typedef NABasicPtrTempl<ex_globals>   ExGlobalsPtr; 

// -----------------------------------------------------------------------
// Classes defined in this file
// -----------------------------------------------------------------------
class ex_clause;


/////////////////////////////////////////////////
// Class ex_clause
/////////////////////////////////////////////////
class ex_clause : public NAVersionedObject {
public:
  // Possible types of clauses
  // (these codes must remain invariant across future versions)
  enum clause_type  {
    CLAUSE_ANCHOR            =-1,
    AGGREGATE_TYPE           = 1,
    ARITH_TYPE               = 2,
    BOOL_RESULT_TYPE         = 3,
    BOOL_TYPE                = 4,
    BRANCH_TYPE              = 5,
    COMP_TYPE                = 6,
    CONV_TYPE                = 7,
    FUNCTION_TYPE            = 8,
    INOUT_TYPE               = 9,
    LIKE_TYPE                =10,
    NOOP_TYPE                =11,
    UN_LOGIC_TYPE            =12,
    ARITH_SUM_TYPE           =13,
    ARITH_COUNT_TYPE         =14,
    MATH_FUNCTION_TYPE       =15,
    // we use most of the above enumerated constants as ex_clause classID's.
    // we also use the following enumerated constants as classID's of 
    // ex_clause derived classes.
    // NAVersionedObject::driveUnpack relies on classID to find and set the 
    // unpacked object's virtual function table pointer; so, classID must
    // be a  "flattened" unique class id. That is, no two ex_clause-derived 
    // classes can have the same classID.
    LIKE_CLAUSE_CHAR_ID      =16,
    LIKE_CLAUSE_DOUBLEBYTE_ID   =17,
    FUNC_ASCII_ID            =18,
    FUNC_CHAR_ID             =19,
    FUNC_CHAR_LEN_ID         =20,
    FUNC_CHAR_LEN_DOUBLEBYTE_ID =21,
    FUNC_CVT_HEX_ID          =22,
    FUNC_OCT_LEN_ID          =23,
    FUNC_POSITION_ID         =24,
    FUNC_POSITION_DOUBLEBYTE_ID =25,
    FUNC_CONCAT_ID           =26,
    FUNC_REPEAT_ID           =27,
    FUNC_REPLACE_ID          =28,
    FUNC_SUBSTR_ID           =29,
    FUNC_SUBSTR_DOUBLEBYTE_ID=30,
    FUNC_TRIM_ID             =31,
    FUNC_TRANSLATE_ID        =32,
    FUNC_TRIM_DOUBLEBYTE_ID  =33,
    FUNC_LOWER_ID            =34,
    FUNC_UPPER_ID            =35,
    FUNC_UPPER_UNICODE_ID    =36,
    FUNC_LOWER_UNICODE_ID    =37,
    FUNC_CURRENT_TIMESTAMP_ID=38,
    FUNC_ENCODE_ID           =39,
    FUNC_EXPLODE_VARCHAR_ID  =40,
    FUNC_HASH_ID             =41,
    FUNC_HASHCOMB_ID         =42,
    FUNC_BITMUX_ID           =43,
    FUNC_REPLACE_NULL_ID     =44,
    FUNC_MOD_ID              =45,
    FUNC_MASK_ID             =47,
    FUNC_ABS_ID              =48,
    FUNC_BOOL_ID             =49,
    FUNC_CONVERTTIMESTAMP_ID =50,
    FUNC_DATEFORMAT_ID       =51,
    FUNC_DAYOFWEEK_ID        =52,
    FUNC_EXTRACT_ID          =53,
    FUNC_JULIANTIMESTAMP_ID  =54,
    FUNC_EXEC_COUNT_ID       =55,
    FUNC_CURR_TRANSID_ID     =56,
    FUNC_USER_ID             =57,
    FUNC_ANSI_USER_ID        =58,
    FUNC_VARIANCE_ID         =59,
    FUNC_STDDEV_ID           =60,
    FUNC_RAISE_ERROR_ID      =61,
    FUNC_RANDOMNUM_ID        =62,
    FUNC_HDPHASH_ID          =63,
    FUNC_HDPHASHCOMB_ID      =64,
    FUNC_PROGDISTRIB_ID      =65,
    FUNC_UNPACKCOL_ID        =66,
    FUNC_PACK_ID             =67,
    FUNC_RANGE_LOOKUP_ID     =68,
    FUNC_MATH_ID             =69,
    AGGR_ONE_ROW_ID          =70,
    AGGR_ANY_TRUE_MAX_ID     =71,
    AGGR_MIN_MAX_ID          =72,
    FUNC_OFFSET_ID           =73,
    FUNC_RAND_SELECTION_ID   =74,
    FUNC_ROWSETARRAY_SCAN_ID =75,
    FUNC_ROWSETARRAY_ROW_ID  =76,
    FUNC_ROWSETARRAY_INTO_ID =77,
    FUNC_UNIQUE_EXECUTE_ID_ID=78,
    FUNC_INTERNALTIMESTAMP_ID=79,
    FUNC_GET_TRIGGERS_STATUS_ID=80,
    FUNC_GET_BIT_VALUE_AT_ID =81,
    FUNC_PROGDISTKEY_ID      =82,
    FUNC_PAGROUP_ID          =83,
    FUNC_SHIFT_ID            =84,
    FUNC_GENERICUPDATEOUTPUT_ID=85,
    FUNC_IS_BITWISE_AND_TRUE =86,
    FUNC_NULLIFZERO          =87,
    FUNC_NVL                 =88,
    FUNC_HASH2_DISTRIB_ID    =89,
    FUNC_HEADER              =92,
    FUNC_QUERYID_EXTRACT     =93,
    FUNC_BIT_OPER_ID         =94,
    FUNC_TOKENSTR_ID         =95,
    LOB_TYPE                 =96,
    LOB_INSERT               =97,
    LOB_SELECT               =98,
    LOB_DELETE               =99,
    LOB_UPDATE               =100,
    LOB_CONVERT              =101,
    LOB_CONVERTHANDLE        =102,
    LOB_LOAD                 =103,
    LOB_FUNC_TYPE            =104,
    LOB_FUNC_SUBSTR          =105,
    FUNC_HIVEHASH_ID         =106,
    FUNC_HIVEHASHCOMB_ID     =107,
    FUNC_UNIQUE_ID           = 108,
    FUNC_HBASE_COLUMN_LOOKUP = 109,
    FUNC_HBASE_COLUMNS_DISPLAY   = 110,
    FUNC_HBASE_COLUMN_CREATE = 111,
    FUNC_CAST_TYPE           = 112,
    FUNC_SEQUENCE_VALUE      = 113,
    FUNC_PIVOT_GROUP         = 114,
    FUNC_ROWNUM              = 115,
    FUNC_HBASE_TIMESTAMP     = 116,
    FUNC_HBASE_VERSION       = 117,
    FUNC_ISIP_ID             = 118,
    FUNC_INETATON_ID         = 119,
    FUNC_INETNTOA_ID         = 120,
    AGGR_GROUPING_ID         = 121,
    FUNC_CRC32_ID            = 122,
    FUNC_MD5_ID              = 123,
    FUNC_SHA1_ID             = 124,
    FUNC_SHA2_ID             = 125,
    FUNC_SOUNDEX_ID          = 126,
    REGEXP_CLAUSE_CHAR_ID    = 127,
    FUNC_JSON_ID             = 128,
    FUNC_AES_ENCRYPT         = 129,
    FUNC_AES_DECRYPT         = 130,
    FUNC_REVERSE_ID         = 131,
    FUNC_SLEEP_ID           = 132,
    FUNC_UNIX_TIMESTAMP_ID = 133,
    FUNC_SPLIT_PART_ID     = 134
  };

  // max number of operands (including result) in a clause.
  // Result occupies the first position(index = 0) in the
  // Attributes array 'op'. See exp_expr::eval in file
  // exp_eval.C for details on use of these enums.
  enum ClauseConstants {
    MAX_OPERANDS         = 5,
    MAX_TEMP_OPERAND_LEN = 64,
    NULL_HASH            = 666654765,
    SQL_INT32_MAX        = 2147483647
  };
  
  // Construction, Destruction
  //
  ex_clause() : NAVersionedObject(CLAUSE_ANCHOR), 
    nextClause_(NULL), op_(NULL) {};
  ex_clause(clause_type type_,
		       OperatorTypeEnum operType_,
		       short num_operands_,
		       Attributes ** op_,
		       Space * space_);
  ~ex_clause();

  // Bookkeeping Accessors
  //
  void generateClause(char *pt);
  inline clause_type getType();
  inline void setType(clause_type t);

  inline OperatorTypeEnum getOperType()
  {return (OperatorTypeEnum)operType_;};

  // PCode Methods
  //
  // getPCILink - returns the link to the PCI List for this clause
  //
  // setPCIList - sets the link to the PCI List for this clause
  //
  // pCodeGenerate - virtual functions used to generate the PCode for 
  // a clause. If not redefined, the default implementations generates
  // PCode to set up for and call the clause->eval() method.
  //
  inline PCILink *getPCIList() { return pciLink_; };
  inline void setPCIList(PCILink *pciLink) {
    pciLink_ = pciLink; };
  virtual ex_expr::exp_return_type pCodeGenerate(Space *space,
							    UInt32 flags);

  // Null Processing Methods
  //
  // isNullInNullOut - Pure virtual function which returns TRUE if the clause
  // semantics are any NULL input produces a NULL result.
  //
  // isNullRelevant - Pure virtual function which returns TRUE if there
  // is processing for NULLs other than in eval.
  //
  // isAnyInputNullable - Returns TRUE if any of the input operands are
  // nullable.
  //
  // isAnyOutputNullable - Returns TRUE if any of the output operands are
  // nullable.
  //
  // isAnyOperandNullable - Returns TRUE is any of the input or output
  // operands are nullable.
  //
  // useProcessNulls - Returns TRUE is processNulls should be called
  // for this clause.
  //
  // setSpecialNulls - Sets flags to indicate that NULL should compare as
  // bigger than maximum value (for sorting)
  //
  // isSpecialNulls - Return TRUE if NULL should compare bigger than maximum
  // value
  //
  virtual Int32 isNullInNullOut() const 
    { return 1;}; // must be redefined in derived classes
  virtual Int32 isNullRelevant() const
    { return 1;}; // must be redefined in derived classes
  inline Int32 isAnyInputNullable() {
    return flags_ & ANY_INPUT_NULLABLE; };

  inline Int32 isAnyOutputNullable() {
    return flags_ & ANY_OUTPUT_NULLABLE; };
 
  inline Int32 isAnyOperandNullable() { 
    return flags_ & (ANY_INPUT_NULLABLE | ANY_OUTPUT_NULLABLE); };

  inline Int32 useProcessNulls() {
    return flags_ & USE_PROCESS_NULLS; 
  };

  void setProcessNulls() {
    if(isNullRelevant() && (flags_ & (ANY_INPUT_NULLABLE|ANY_OUTPUT_NULLABLE)))
      flags_ |= USE_PROCESS_NULLS;
  };
  void setSpecialNulls() { flags_ |= SPECIAL_NULLS; };
  Int32 isSpecialNulls()   { return (flags_ & SPECIAL_NULLS) != 0; };

  NABoolean noPCodeAvailable() { return (flags_ & NO_PCODE_AVAILABLE) != 0; };
  void setNoPCodeAvailable(NABoolean v) 
  {
    (v ? flags_ |= NO_PCODE_AVAILABLE : flags_ &= ~NO_PCODE_AVAILABLE);
  };

  NABoolean handleIndirectVC() { return (flags_ & HANDLE_INDIRECT_VC) != 0; };
  void setHandleIndirectVC(NABoolean v) 
  {
    (v ? flags_ |= HANDLE_INDIRECT_VC : flags_ &= ~HANDLE_INDIRECT_VC);
  };

  NABoolean forInsertUpdate() { return (flags_ & FOR_INSERT_UPDATE) != 0; };
  void setForInsertUpdate(NABoolean v) 
  {
    (v ? flags_ |= FOR_INSERT_UPDATE : flags_ &= ~FOR_INSERT_UPDATE);
  };

  inline Int32 getAllFlags() { return flags_ ; };

  //
  // SPECIAL TRUNCATION FLAG 
  //
  // this flag is set if a character string casting is done when a larger
  // string is assigned to a smaller string size
  //
  // The following two methods are used only in ex_conv_clause objects

  void setCheckTruncationFlag()
                                    {flags_ |= CHECK_STRING_TRUNCATION;};
  Int32 getCheckTruncationFlag()
                                    {return (flags_ & CHECK_STRING_TRUNCATION); }

  void setNoTruncationWarningsFlag()
                                    {flags_ |= NO_STRING_TRUNCATION_WARNINGS; };
  Int32 getNoTruncationWarningsFlag()
                                    { return (flags_ & NO_STRING_TRUNCATION_WARNINGS); }

    // Branch handling
  //
  // isBranchingClause - Virtual function which returns TRUE if the clause
  // may change the flow on control (ie. branch)
  //
  // isBranchTarget - Returns TRUE is this clause is the target
  // of a branch clause.
  //
  // getNumberBranchTargets - Returns the number of branch clauses
  // which target this clause.
  //
  // addBranchTarget - Increments the number of branch clauses
  // which target this clause.
  //
  virtual Int32 isBranchingClause() const { return 0; };
  Int32 isBranchTarget() const { return numberBranchTargets_ != 0; };
  Int32 getNumberBranchTargets() { return numberBranchTargets_; }; 
  void setNumberBranchTargets(Int32 num) { numberBranchTargets_ = num; };
  void addBranchTarget() { numberBranchTargets_++; };

    
  unsigned short &clauseNum() { return clauseNum_; }

  // Operand Accessors
  //
  inline short getNumOperands();
  inline Attributes *getOperand(short operand_num);
  inline AttributesPtr *getOperand();
  inline void setOperand(AttributesPtrPtr& attr_);

  // Clause List Accessors
  //
  inline ex_clause *getNextClause();
  inline void setNextClause(ex_clause *clause_);
  inline void setNextPackedClause(Int64 offset);
  inline void setNext(Lng32 next_clause_offset);
  inline void setLastClause();

  // Packing, Unpacking, and Fixup
  //
  virtual Long pack(void *);
  virtual Lng32 unpack(void *, void * reallocator);
  Long packClause(void *, Lng32 size);
  Lng32 unpackClause(void *base, void * reallocator);

  virtual Lng32 initClause(){return 0;};

  // SpaceCompOnly: if TRUE, then compute space requirement only.
  //                Do not make any changes to the generated expressions,
  //                (like assigning tempsArea, assigning generated pcode, etc).
  virtual ex_expr::exp_return_type fixup(Space * space = 0,
						    CollHeap * exHeap = 0,
						    char * constants_area = 0,
						    char * temps_area = 0,
						    char * persistentArea = 0,
						    short = 0,
						    NABoolean spaceCompOnly = FALSE);
  
  // Execution
  //
  // isEvalRelevant - Returns true if eval() does any work. The eval()
  // methods for some clauses do nothing but serve as placeholders. These
  // clauses can be identified using this routine.
  //
  // eval - Actually does the work based on the pointers in the op_data
  // vector. The op_data vector has the following layout:
  //
  // 0 - pointer to result null indicator
  // 1 - TRUE if 1st arg is not NULL
  // 2 - TRUE if 2nd arg is not NULL
  // MAX_OPERANDS-1 - TRUE if MAX_OPERANDS-2(th) arg is not NULL
  //
  // MAX_OPERANDS+0 - pointer to result varchar length (NULL for non-varchar)
  // MAX_OPERANDS+1 - pointer to 1st arg varchar length (NULL for non-varchar)
  // MAX_OPERANDS+2 - pointer to 2nd arg varchar length (NULL for non-varchar)
  // 2*MAX_OPERANDS-1 - pointer to 2*MAX_OPERANDS-2(th) arg
  //
  // 2*MAX_OPERANDS+0 - pointer to result attribute
  // 2*MAX_OPERANDS+1 - pointer to 1st arg attribute (maybe null for NULL attr)
  // 2*MAX_OPERANDS+2 - pointer to 2nd arg attribute (maybe null for NULL attr)
  // 3*MAX_OPERANDS-1 - pointer to 3*MAX_OPERANDS-2(th) arg
  //
  // The processNulls method gets passed &(op_data[0]) so that addressing
  // the null indicators is done with op_data[0], op_data[1], etc.
  // The method returns EXPR_ERROR for attempt to assign a NULL to a nonnullable
  // column, EXPR_NULL for NULL successfully processed (assigned to a nullable
  // column), EXPR_OK for no error and no null -- caller must continue eval.
  //
  // The eval method gets passed &(op_data[2*MAX_OPERANDS+0]) so that
  // addressing the attributes is done with op_data[0], op_data[1], etc. The
  // null and varchar information is accessed using negative offsets:
  // op_data[-2*MAX_OPERANDS], etc.
  //
  //
  virtual Int32 isEvalRelevant() const
  { return 1;}; // must be redefined in derived classes
  virtual ex_expr::exp_return_type processNulls(char *op_data[],
							   CollHeap * = 0,
							   ComDiagsArea ** = 0);
  virtual ex_expr::exp_return_type eval(char *op_data[],
						   CollHeap * = 0,
						   ComDiagsArea ** = 0);
 
  // Display
  //
  virtual void displayContents(Space * space, const char * displayStr, 
					  Int32 clauseNum, char * constsArea);
  
  void displayContents(Space * space, const char * displayStr, 
                                  Int32 clauseNum, char * constsArea, 
                                  UInt32 clauseFlags,
                                  Int16 instruction = -1,
                                  const char * instrText = NULL);

  static void clearVOA(Attributes *attr, atp_struct *atp)
  {
    CollIndex atpIdx = attr->getAtpIndex();
    
    if (attr->isSQLMXDiskFormat() && (attr->getVCIndicatorLength() > 0))
      str_pad((atp->getTupp(atpIdx)).getDataPointer(), sizeof(Int32), 0);
  }


  static void setRowLength(Attributes * attr, 
				      atp_struct * atp,
				      UInt32     * rowLen,
				      UInt32       newLength)
  {
    if (attr->isSQLMXAlignedFormat())
    {
      *rowLen = ExpAlignedFormat::adjustDataLength(
                             atp->getTupp(attr->getAtpIndex()).getDataPointer(),
                             newLength,
                             ExpAlignedFormat::ALIGNMENT
                             );
    }
    else
      *rowLen = newLength;
  }


  static void setVoaData(char *dataPtr, UInt32 voaOffset, UInt32 value)
   {
     assert(dataPtr);
     if (voaOffset != ExpOffsetMax)
       str_cpy_all(dataPtr + voaOffset, (char *)&value, ExpVoaSize);
   }
  
  static void evalSetRowLength(Attributes *attr, 
					  atp_struct *atp,
					  UInt32     *rowLen,
					  UInt32      newLength)
  {
    // Only adjust the length if using aligned row format.
    // If the row lengths are equal, then use the computed at codegen it is
    // adjusted already for alignment purposes.
    if (attr && attr->isSQLMXAlignedFormat() && (*rowLen != newLength))
    {
      *rowLen = ExpAlignedFormat::adjustDataLength(
                      (char*)atp->getTupp(attr->getAtpIndex()).getDataPointer(),
                      newLength,
                      ExpAlignedFormat::ALIGNMENT
                      );
    }
    else
      *rowLen = newLength;
  }

  void copyOperands(ex_clause* clause, Space* space);

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

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(0,getClassVersionID());
  }

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

  void setExeGlobals(ex_globals * glob)
  {
    globals_ = glob;
  }

  Int16 getInstrArrayIndex() { return instrArrayIndex_; }
  void setInstrArrayIndex(Int16 index) { instrArrayIndex_ = index; }

protected:
  ex_globals * getExeGlobals() 
  {
    return globals_;
  }

private:  
  ExClausePtr                nextClause_;          // 00-07
  PCILink                   *pciLink_;             // 08-15
  AttributesPtrPtr           op_;                  // 16-23
  UInt16                     clauseNum_;           // 24-25
  UInt16                     numberBranchTargets_; // 26-27
  UInt32                     flags_;               // 28-31
  enum flags_type {
    SPECIAL_NULLS = 0x0001,       // Compare NULLs as values
    ANY_INPUT_NULLABLE = 0x0002,  // Nullable Input
    ANY_OUTPUT_NULLABLE = 0x0004, // Nullable Ouput
    USE_PROCESS_NULLS = 0x0008,   // Use processNulls
    CHECK_STRING_TRUNCATION = 0x0010,  // check for string truncation
    NO_PCODE_AVAILABLE = 0x0020,
    NO_STRING_TRUNCATION_WARNINGS = 0x0040,
    HANDLE_INDIRECT_VC = 0x0080,
    FOR_INSERT_UPDATE  = 0x0100
  };
  Int16                      numOperands_;         // 32-33
  Int16 /*OperatorTypeEnum*/ operType_;            // 34-35
  Int16 /*clause_type*/      clauseType_;          // 36-37

  // index into static clause array struct containing details about
  // this clause (datatypes, operation, etc) if derived clause has
  // this array defined.
  // See derived clauses for details.
  Int16 instrArrayIndex_;                       // 48-49

  // this field is set at runtime when this clause is fixed up.
  // It is used in eval for cases where an expression needs to access 
  // executor globals.
  // Not valid for EID expressions.
  // Only used for SQ.
  ExGlobalsPtr globals_;                           // 40-47

  // ---------------------------------------------------------------------
  // 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_[16];          // 52-63
};


inline ex_clause::clause_type ex_clause::getType(){
  
  return (clause_type)clauseType_;
};

inline void ex_clause::setType(ex_clause::clause_type t){
  clauseType_ = t;
};

inline void ex_clause::setLastClause(){
  nextClause_ = 0;
};

inline short ex_clause::getNumOperands(){
  return numOperands_;
};

inline Attributes *ex_clause::getOperand(short operand_num){
  return op_[operand_num];
};

inline AttributesPtr *ex_clause::getOperand(){
  return op_;
};

inline void ex_clause::setOperand(AttributesPtrPtr& attr)
{
  op_ = attr;
};

inline void ex_clause::setNextClause(ex_clause *clause_){
  nextClause_ = clause_;
};

inline ex_clause *ex_clause::getNextClause(){
  return nextClause_;
};

inline void ex_clause::setNextPackedClause(Int64 offset){
  nextClause_ = offset;
};

// functions to compare two strings
Int32 charStringCompareWithPad(char* in_s1, Int32 length1, 
                                          char* in_s2, Int32 length2, 
                                          char space);

Int32 wcharStringCompareWithPad(NAWchar* s1, Int32 length1, 
                                           NAWchar* s2, Int32 length2, 
                                           NAWchar space);
#endif
