/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/
/* -*-C++-*-
******************************************************************************
*
* File:         ExSequenceFunction.cpp
* RCS:          $Id
* Description:  ExSequenceFunction class Implementation
* Created:      9/11/98
* Modified:     $Author
* Language:     C++
* Status:       $State
*
*
*
*
******************************************************************************
*/

#include "Platform.h"


// Includes
//
#include "SQLTypeDefs.h"
#include "exp_clause.h"
#include "exp_attrs.h"
#include "ExpPCode.h"
#include "ExpSequenceFunction.h" // <--- See here for comments.

// ExpSequenceFunction::ExpSequenceFunction
//
// Constructs an ExpSequenceFunction object
//
// IN     : oper_type - The type of clause, must be ITM_OFFSET
// IN     : arity     - The number of input arguments
// IN     : space     - Memory allocator.
// EFFECTS: Calls the base class constructor
// PRECOND: The oper_type is equal to ITM_OFFSET.
//        : The arity doesn't exceed MAX_OPERANDS.
//        : The attributes pointer is valid.
//        : The space object is valid.
// PSTCOND: ExpSequenceFunction is constructed.
//
ExpSequenceFunction::ExpSequenceFunction
(OperatorTypeEnum oper_type, Int32 arity, Int32 index,
 Attributes ** attr, Space * space)
  : ex_function_clause(oper_type, arity, attr, space), offsetIndex_(index), flags_(0) {
};

// ExpSequenceFunction::ExpSequenceFunction
//
// Pseudo Constructor for getting VTable
//
// EFFECTS: None
//
ExpSequenceFunction::ExpSequenceFunction() {;};

// ExpSequenceFunction::pack
//
// Packs an ExpSequenceFunction object
//
// IN     : space - The memory allocator.
// RETURN : the offset withing space of the packed object.
// EFFECTS: Pointers are changed to offsets within space.
// PRECOND: Space is a valid space object.
Long ExpSequenceFunction::pack(void * space) {
  // Since ExpSequenceFunction has no private data, the pack_clause
  // helper of the ex_clause class can be used to pack this
  // class.
  //
  return packClause(space, sizeof(ExpSequenceFunction));
}  

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

  if(isAnyOperandNullable()) 
    return ex_clause::pCodeGenerate(space, f);

  if(getNumOperands() != 2 && getNumOperands() != 3)
    return ex_clause::pCodeGenerate(space, f);

  if(!nullRowIsZero())
    return ex_clause::pCodeGenerate(space, f);

  if(!isLeading() || (winSize() != 0))
    return ex_clause::pCodeGenerate(space, f);

  AttributesPtr *attrs = getOperand();
  Lng32 fsDataType = attrs[1]->getDatatype();
  Lng32 length = attrs[1]->getLength();
  
  if(fsDataType != REC_BIN64_SIGNED || length != 8)
    return ex_clause::pCodeGenerate(space, f);

  if(getNumOperands() == 3) {
    fsDataType = attrs[2]->getDatatype();
    length = attrs[2]->getLength();

    if(fsDataType != REC_BIN32_SIGNED || length != 4)
      return ex_clause::pCodeGenerate(space, f);
  }

  // If we get to this point, we have decided to generate PCode for this
  // particular sequence function operation.
  //
  PCIList code(space);

  // Generate pre clause PCI's
  //
  PCode::preClausePCI(this, code);

  if(getNumOperands() == 2) {
    Int32 index = offsetIndex_;
  
       
    // The 1st operand is a pointer to the function.
    // The 2nd operand is a pointer the Tcb to get to the history buffer.
    // The 3rd operand is the immediate index value.
    // The 4th operand is the memory location for the target.
    // The 5th operand is the memory location for the source.
    //
    AML aml(PCIT::IPTR, 
            PCIT::IPTR, 
            PCIT::IBIN32S,
            PCIT::getMemoryAddressingMode(attrs[0]->getDatatype()),
            PCIT::getMemoryAddressingMode(attrs[1]->getDatatype()));

    OL ol((Int64)isOLAP(), (Int64)0, index, 
          attrs[0]->getAtp(), attrs[0]->getAtpIndex(), attrs[0]->getOffset(),
          attrs[1]->getAtp(), attrs[1]->getAtpIndex(), attrs[1]->getOffset());

    // Add the OFFSET instruction.
    //
    PCI pci(PCIT::Op_OFFSET, aml, ol);
    code.append(pci);
  } else {
    // The 1st operand is a pointer to the function.
    // The 2nd operand is a pointer the Tcb to get to the history buffer.
    // The 3rd operand is the memory location for the index value.
    // The 4th operand is the memory location for the target.
    // The 5th operand is the memory location for the source.
    //
    AML aml(PCIT::IPTR,
            PCIT::IPTR,
            PCIT::getMemoryAddressingMode(attrs[2]->getDatatype()),
            PCIT::getMemoryAddressingMode(attrs[0]->getDatatype()),
            PCIT::getMemoryAddressingMode(attrs[1]->getDatatype()));

    OL ol((Int64)(isOLAP()), (Int64)0,
          attrs[2]->getAtp(), attrs[2]->getAtpIndex(), attrs[2]->getOffset(),
          attrs[0]->getAtp(), attrs[0]->getAtpIndex(), attrs[0]->getOffset(),
          attrs[1]->getAtp(), attrs[1]->getAtpIndex(), attrs[1]->getOffset());

    // Add the OFFSET instruction.
    //
    PCI pci(PCIT::Op_OFFSET, aml, ol);
    code.append(pci);
  }
  
  // Generate post clause PCI's
  //
  PCode::postClausePCI(this, code);

  setPCIList(code.getList());
  return ex_expr::EXPR_OK;
}

// ExpSequenceFunction::eval
//
// Implment sequence functions...
//
// IN     : op_data      - output/input vector
// IN     : heap         - not used
// IN     : comDiagsArea - not used
// RETURN : ex_expr::EXPR_OK is no errors
// PRECOND: The op_data vector points to the NULL/VARCHAR and data.
//
ex_expr::exp_return_type ExpSequenceFunction::eval(char *op_data[],
						   CollHeap *heap,
						   ComDiagsArea **diagsArea) {
  
  // Get a handle on the operands so they can be queried for
  // NULL and VARCHAR -ness.
  //
  AttributesPtr *attrs = getOperand();

  // Get the pointer to the index data. If this clause has three operands
  // then the index is given by the last operand. Otherwise, the index
  // is a constant set in the clause.
  //
  Int32 index;
  if(getNumOperands() >= 3) {
    if(attrs[2]->getNullFlag() && !op_data[-2 * MAX_OPERANDS + 2])
      index = -1;
    else
      index = *((Int32 *)op_data[2]);
  }
  else
    index = offsetIndex_;

  // Lookup the indexed row in the history buffer. Compute pointers
  // to the attribute data, null indicator, and varchar indicator.
  //
  char *srcData = NULL;
  UInt32 srcLen = 0;
  char *srcNull = NULL;
  char *srcVC   = NULL;
  Int32 rc=0;

  {
    char *row = (*GetRow_)(GetRowData_, index, isLeading(), winSize(), rc);

    if(rc == -1)
      {
        ExRaiseSqlError(heap, diagsArea, EXE_HISTORY_BUFFER_TOO_SMALL);
        return ex_expr::EXPR_ERROR;
      }
    if(row) 
      {
        srcData = row + attrs[1]->getOffset();
        if(attrs[1]->getVCIndicatorLength() > 0)
          srcVC = row + attrs[1]->getVCLenIndOffset();
        if(attrs[1]->getNullFlag())
          srcNull = row + attrs[1]->getNullIndOffset();

        srcLen = getOperand(1)->getLength(srcVC);
      } else {
          if(getNumOperands() == 4) {
  
             srcData = op_data[3];
             srcLen = getOperand(3)->getLength(op_data[-MAX_OPERANDS+3]);
             srcNull = NULL;
          }
      }
  }

  // Is the source null? There are two reaons the source data can be null:
  // 1. The row does not exist in the history buffer (srcData == NULL)
  // 2. The data exist but is itself NULL (srcNull == 0xFFFF)
  //
  Int32 srcIsNull = (srcData ? 0 : 1);
  if(srcData && srcNull)
    srcIsNull = *((unsigned short*)(srcNull)) == 0xFFFFU;

  // Get the pointer to the start of the result data.
  //
  char *dstData = op_data[0];
  char *dstNull = op_data[-2 * MAX_OPERANDS + 0];
  char *dstVC   = op_data[- MAX_OPERANDS];

  if (rc == -3 && !srcData )
  {
    *((unsigned short*)dstNull) = 0xFFFFU;
    return ex_expr::EXPR_OK;
  }
  // Copy the source data to the destination data.
  //
  if(srcIsNull)
    {
      if(nullRowIsZero() || (rc == -2)) {
        switch (getOperand(1)->getDatatype()) {
        case REC_BIN16_UNSIGNED:
        case REC_BIN16_SIGNED: 
        {
          // hiding code from code coverag tool-- 
          short value = 0;
          str_cpy_all(dstData, (char *) &value, sizeof(value));
          break;
        }
        case REC_BIN32_SIGNED:
        case REC_BIN32_UNSIGNED:
        {
          Lng32 value = 0;
          str_cpy_all(dstData, (char *) &value, sizeof(value));
          break;
        }
        case REC_BIN64_SIGNED:
        {
          Int64 value = 0;
          str_cpy_all(dstData, (char *) &value, sizeof(value));
          break;
        }
        case REC_IEEE_FLOAT32:
        {
          float value = 0;
          str_cpy_all(dstData, (char *) &value, sizeof(value));
          break;
        }
        case REC_IEEE_FLOAT64:
        {
          double value = 0;
          str_cpy_all(dstData, (char *) &value, sizeof(value));
          break;
        }
        default:
        {
          Lng32 value = 0;
          if (convDoIt((char *)&value,
                       sizeof(value),
                       REC_BIN32_SIGNED,
                       0,
                       0,
                       dstData,
                       getOperand(1)->getLength(),
                       getOperand(1)->getDatatype(),
                       getOperand(1)->getPrecision(),
                       getOperand(1)->getScale(),
                       NULL, 0, heap, diagsArea,
                       CONV_UNKNOWN) != ex_expr::EXPR_OK) {
            return ex_expr::EXPR_ERROR;
          }

          break;
        }
        }

        if(attrs[0]->getNullFlag())
          *((short*)dstNull) = 0x0000;

      } else {
        *((unsigned short*)dstNull) = 0xFFFFU;
      }
    }
  else
    {
      Int32 len = attrs[0]->getLength();
      str_cpy_all(dstData, srcData, attrs[0]->getLength());
      if (attrs[1]->getVCIndicatorLength() > 0)
           getOperand(0)->setVarLength(srcLen, dstVC);
           //getOperand(0)->setVarLength(getOperand(1)->getLength(srcVC), dstVC);
      if(attrs[0]->getNullFlag())
        *((short*)dstNull) = 0x0000;
    }

  // Return all OK...
  //
  return ex_expr::EXPR_OK;
};
