/**********************************************************************
// @@@ 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:         LmResultSetJava.cpp
* Description:  Container for Java specific result set data.
*
* Created:      09/07/2005
* Language:     C++
*
******************************************************************************
*/
#include "Platform.h"
  #include "lmjni.h"
#include "LmResultSetJava.h"
#include "jni.h"
#include "LmJavaExceptionReporter.h"
#include "LmDebug.h"
#include "LmExtFunc.h"
#include "LmJavaType.h"
// #include "ExpError.h"

// Constructor
// Makes a JNI call to LmUtility::getRSInfo()
// to get result set information for the passed in 
// java.sql.ResultSet object (parameter rsRef) and
// initializes the data members accordingly.
LmResultSetJava::LmResultSetJava(LmLanguageManagerJava *lm,
                                 LmHandle rsRef,
                                 Int32 paramPos,
                                 const char *routineName,
                                 LmResultSetInfoStatus &status,
                                 NAList<LmConnection*> &lmConnList,
                                 ComDiagsArea *da)

 : LmResultSet(), lmj_(lm), jdbcRSRef_(NULL), proxySyntax_(NULL),
   firstBufferedRow_(0),
   lastBufferedRow_(0), currentRowPosition_(0),
   cursorType_(RS_TYPE_UNKNOWN), rsCounter_(0),
   iArray_(NULL), lArray_(NULL), oArray_(NULL),
   errCode_(NULL), errDetail_(NULL),
   lmConn_(NULL), lmConnList_(lmConnList),CLIStmtClosed_(0)
{
  JNIEnv *jni = (JNIEnv*)lmj_->jniEnv_;
 
  status = RS_INFO_OK;

  // Find if this Result Set is using  T2 or T4 connection.
  Int32 connType = jni->CallStaticIntMethod((jclass) lmj_->utilityClass_,
		        (jmethodID) lmj_->utilityGetConnTypeId_,
			(jobject) rsRef);

  connectionType_ = (LmJDBCConnectionType) connType;

  // Create a global reference of Result Set object
  jdbcRSRef_ = (jobject)jni->NewGlobalRef((jobject)rsRef);

  if (connectionType_ == JDBC_TYPE4_CONNECTION)
    initType4ResultSet(paramPos, routineName, status, lmConnList, da);
  else if (connectionType_ == JDBC_TYPE2_CONNECTION)
    initType2ResultSet(paramPos, routineName, status, lmConnList, da);
  else
  {
    *da << DgSqlCode(-LME_RS_INFO_ERROR)
        << DgInt0((Lng32) paramPos)
        << DgString0("An unknown Connection type found for ResultSet"); 

    status  = RS_INFO_ERROR;
    return;
  }

}

void LmResultSetJava::initType4ResultSet(Int32 paramPos,
		                         const char *routineName,
					 LmResultSetInfoStatus &status,
					 NAList<LmConnection*> &lmConnList,
					 ComDiagsArea *da)
{ 
  JNIEnv *jni = (JNIEnv*)lmj_->jniEnv_;

  jlongArray lArray = jni->NewLongArray(1);
  jbooleanArray bArray = jni->NewBooleanArray(1);
  jbooleanArray bArray2 = jni->NewBooleanArray(1);
  jintArray iArray = jni->NewIntArray(1);
  jobjectArray oArray1 =
    jni->NewObjectArray(1, (jclass)lmj_->stringClass_, NULL);
  jobjectArray oArray2 =
    jni->NewObjectArray(1, (jclass)lmj_->connClass_, NULL);

  // Call getT4RSInfo() of LmUtility java class
  jni->CallStaticVoidMethod((jclass) lmj_->utilityClass_,
		            (jmethodID) lmj_->utilityGetT4RSInfoId_,
		            (jobject) jdbcRSRef_,
			    lArray,
			    bArray,
			    iArray,
			    bArray2,
			    oArray1,
			    oArray2);

  // Check if any exceptions are thrown by the above JNI call and report it
  if (jni->ExceptionOccurred())
  {
    *da << DgSqlCode(-LME_RS_INFO_ERROR)
        << DgInt0((Lng32) paramPos)
        << DgString0("An unexpected Java exception was encountered when invoking \
                      org.trafodion.sql.udr.LmUtility.getT4RSInfo().");

    lmj_->exceptionReporter_->checkJVMException(da, 0);

    status = RS_INFO_ERROR;
    return;
  }

  // Now process the values returned by getT4RSInfo()

  // Check RS status
  jboolean closeStatus[1];
  jni->GetBooleanArrayRegion(bArray, 0, 1, closeStatus);
  LM_ASSERT(jni->ExceptionOccurred() == NULL);
  if (closeStatus[0])
  {
    status = RS_INFO_CLOSED;
    return;
  }

  // Check for any LOB columns
  jboolean lobData[1];
  jni->GetBooleanArrayRegion(bArray2, 0, 1, lobData);
  LM_ASSERT(jni->ExceptionOccurred() == NULL);
  if (lobData[0])
  {
    *da << DgSqlCode(-LME_LOB_COL_IN_RS_ERROR)
        << DgString0(routineName);

    status = RS_INFO_LOBCOL;
    return;
  }

  // Get RS Counter
  jlong rsCounter[1];
  jni->GetLongArrayRegion(lArray, 0, 1, rsCounter);
  LM_ASSERT(jni->ExceptionOccurred() == NULL);
  rsCounter_ = rsCounter[0];

  // Get RS Type
  jint rsType[1];
  jni->GetIntArrayRegion(iArray, 0, 1, rsType);
  LM_ASSERT(jni->ExceptionOccurred() == NULL);
  cursorType_ = (LmResultSetType) rsType[0];

  // Get proxy syntax
  jstring pSyntax = (jstring) jni->GetObjectArrayElement(oArray1, 0);
  const char *str = jni->GetStringUTFChars(pSyntax, NULL);
  ComUInt32 strSize = str_len(str);
  proxySyntax_ =  new (collHeap()) char[strSize + 1];
  str_cpy(proxySyntax_, str, (Int32)strSize);
  proxySyntax_[strSize] = '\0';
  jni->ReleaseStringUTFChars(pSyntax, str);
  jni->DeleteLocalRef(pSyntax);


  // Get connection reference
  jobject connObj = jni->GetObjectArrayElement(oArray2, 0);
  jobject jdbcConnRef = jni->NewGlobalRef(connObj);
  jni->DeleteLocalRef(connObj);

  // Set RS cursor to to point before first row for Scrollable RS.
  if (isScrollable())
  {
    jni->CallVoidMethod((jobject) jdbcRSRef_,
                        (jmethodID) lmj_->rsBeforeFirstId_);
    currentRowPosition_ = 0;
  }

  // Check if a LmConnection object has already been created for
  // 'jdbcConnRef' if it is then increment the reference count 
  // for that LmConnection object. If not then create a new 
  // LmConnection object add it to the connectionList_.
  ComUInt32 i;
  for( i = 0; i < lmConnList.entries(); i++ )
  {
    lmConn_ = lmConnList[ i ];
    if( jni->IsSameObject( lmConn_->getConnRef(), (jobject)jdbcConnRef ) )
    {
      lmConn_->incrRefCnt();
      jni->DeleteGlobalRef( jdbcConnRef );
      break;
    }
  }

  if( i == lmConnList.entries() ) {
  	//This is not a default connection. For non-default connections we do not perform any transaction 
  	//management so we can set the LmConnection transaction attribute to NO TRANSACTION REQUIRED.
    lmConn_ = new (collHeap()) LmConnection( lmj_,
                                            (jobject)jdbcConnRef,
                                            LmConnection::NON_DEFAULT_CONN, COM_NO_TRANSACTION_REQUIRED);                                             																															
    lmConn_->incrRefCnt();
    lmConnList.insert( lmConn_ );
  }
}

// Exclude the following functions for coverage as Type 2 JDBC is not used any more
void
LmResultSetJava::initType2ResultSet(Int32 paramPos,
                                    const char *routineName,
                                    LmResultSetInfoStatus &status,
                                    NAList<LmConnection*> &lmConnList,
                                    ComDiagsArea *da)
{
  JNIEnv *jni = (JNIEnv*)lmj_->jniEnv_;

  // We will now call the getRSInfo() method in the LmUtility Java class 
  // to get the information for the result set object (jdbcRSRef_).
  // Refer to the LmUtility.java file for details on the parameters 
  // expected by the getRSInfo() method.

  // *** Note: *** 
  // Any change to the parameters in LmUtility::getRSInfo() java method 
  // will impact the code below.

  // The magic number 9 below is to match one of the output int
  // array parameter returned by a call to LmUtility.getRSInfo().
  const Int32 arrSize = 9;

  // Allocate the parameters for the JNI call.
  iArray_ = jni->NewIntArray(arrSize);
  lArray_ = jni->NewLongArray(1);
  oArray_ = jni->NewObjectArray(1, (jclass)lmj_->connClass_, NULL);
  errCode_ = jni->NewIntArray(1);
  errDetail_ = jni->NewObjectArray(1, (jclass)lmj_->stringClass_, NULL);

  if( jni->ExceptionOccurred() || iArray_ == NULL || 
      lArray_ == NULL          || oArray_ == NULL ||
      errCode_ == NULL         || errDetail_ == NULL ) {

    // JVM Out of memory
    *da << DgSqlCode(-LME_JVM_OUT_OF_MEMORY);

    lmj_->exceptionReporter_->checkJVMException(da, 0);
    status = RS_INFO_ERROR;
    return;
  }

  jni->CallStaticVoidMethod((jclass) lmj_->utilityClass_,
                            (jmethodID) lmj_->utilityGetRSInfoId_,
                            (jobject) jdbcRSRef_,
                            iArray_,
                            lArray_,
                            oArray_,
                            errCode_,
                            errDetail_);

  // Check if any exceptions are thrown by the above JNI call and report it
  if (jni->ExceptionOccurred())
  {
    *da << DgSqlCode(-LME_RS_INFO_ERROR)
        << DgInt0((Lng32) paramPos)
        << DgString0("An unexpected Java exception was encountered when invoking \
                      org.trafodion.sql.udr.LmUtility.getRSInfo().");

    lmj_->exceptionReporter_->checkJVMException(da, 0);

    status = RS_INFO_ERROR;
    return;
  }

  // Check the errCode_ parameter to see if any errors have been reported
  // by LmUtility::getRSInfo().
  jint error[1];

  jni->GetIntArrayRegion(errCode_, 0, 1, error);
  LM_ASSERT(jni->ExceptionOccurred() == NULL);

  if( error[0] != 0 ) { // A non-zero value indicates an error
    // Get the value in errDetail_
    jstring jstr = (jstring) jni->GetObjectArrayElement(errDetail_, 0);
    const char *errStr = jni->GetStringUTFChars(jstr, NULL);
    LM_ASSERT(jni->ExceptionOccurred() == NULL);

    lmj_->exceptionReporter_->insertDiags(da,
                                         -error[0], // LME_RS_INFO_ERROR
                                          errStr);

    jni->ReleaseStringUTFChars(jstr, errStr);
    jni->DeleteLocalRef(jstr);
    status = RS_INFO_ERROR;
    return;
  }

  jint ia[arrSize];
  jlong la[1];

  jni->GetIntArrayRegion(iArray_, 0, arrSize, ia);
  LM_ASSERT(jni->ExceptionOccurred() == NULL);

  jni->GetLongArrayRegion(lArray_, 0, 1, la);
  LM_ASSERT(jni->ExceptionOccurred() == NULL);

  // If the result set is already closed then no further
  // processing is required and return back with
  // the appropriate status
  NABoolean rsClosed = (ia[7] == 0 ? FALSE : TRUE);
  if( rsClosed )
  {
    status = RS_INFO_CLOSED;
    return;
  }

  NABoolean lobData = (ia[0] == 0 ? FALSE : TRUE);
  if( lobData ) {
    *da << DgSqlCode(-LME_LOB_COL_IN_RS_ERROR)
	<< DgString0(routineName);

    status = RS_INFO_LOBCOL;
    return;
  }

  setCtxHandle( (SQLCTX_HANDLE)ia[1] );
  setStmtID( (SQLSTMT_ID *)((long)ia[2]) );

  firstBufferedRow_		= ia[3];
  lastBufferedRow_		= ia[4];
  currentRowPosition_	= ia[5];
  cursorType_         = (LmResultSetType) ia[6]; 
  rsCounter_          = la[0];
  CLIStmtClosed_    = (ia[8] == 0 ? FALSE : TRUE);

  jobject connObj = jni->GetObjectArrayElement(oArray_, 0);

  // Create a global references of Connection object
  jobject jdbcConnRef = jni->NewGlobalRef( connObj );

  jni->DeleteLocalRef(connObj);

  // Set RS cursor to to point before first row for Scrollable RS.
  if (isScrollable())
  {
    jni->CallVoidMethod((jobject) jdbcRSRef_,
                        (jmethodID) lmj_->rsBeforeFirstId_);
    currentRowPosition_ = 0;
  }

  // Check if a LmConnection object has already been created for
  // 'jdbcConnRef' if it is then increment the reference count 
  // for that LmConnection object. If not then create a new 
  // LmConnection object add it to the connectionList_.
  ComUInt32 i;
  for( i = 0; i < lmConnList.entries(); i++ )
  {
    lmConn_ = lmConnList[ i ];
    if( jni->IsSameObject( lmConn_->getConnRef(), (jobject)jdbcConnRef ) )
    {
      lmConn_->incrRefCnt();
      jni->DeleteGlobalRef( jdbcConnRef );
      break;
    }
  }

  if( i == lmConnList.entries() ) {
  	//This is not a default connection. For non-default connections we do not perform any transaction 
  	//management so we can set the LmConnection transaction attribute to NO TRANSACTION REQUIRED.
    lmConn_ = new (collHeap()) LmConnection( lmj_,
                                            (jobject)jdbcConnRef,
                                            LmConnection::NON_DEFAULT_CONN, COM_NO_TRANSACTION_REQUIRED); 
    lmConn_->incrRefCnt();
    lmConnList.insert( lmConn_ );
  }

}

// Destructor:
LmResultSetJava::~LmResultSetJava()
{
  JNIEnv *jni = (JNIEnv*)lmj_->jniEnv_;

  if( iArray_ )
    jni->DeleteLocalRef( iArray_ );

  if( lArray_ )
    jni->DeleteLocalRef( lArray_ );

  if( oArray_ )
    jni->DeleteLocalRef( oArray_ );

  if( errCode_ )
    jni->DeleteLocalRef( errCode_ );

  if( errDetail_ )
    jni->DeleteLocalRef( errDetail_ );

  if( jdbcRSRef_ != NULL )
    jni->DeleteGlobalRef((jobject)jdbcRSRef_);

  if (proxySyntax_)
    NADELETEBASIC(proxySyntax_, collHeap());
}

// Makes a JNI call to invoke the close() method on the 
// jdbcRSRef_ object reference (a java.sql.ResultSet object)
// to close the result set.
// 
// Decrements the reference count in the associated LmConnection 
// object.
//
// NOTE: This method should Not return without decrementing it's
// LmConnection object's reference count. Otherwise the LmConnection
// object will not get deleted and it's associated Java connection
// will Not get closed.
void LmResultSetJava::close( ComDiagsArea *da )
{
  JNIEnv *jni = (JNIEnv*)lmj_->jniEnv_;


  if( jdbcRSRef_ != NULL )
  {
    LM_DEBUG0( "LmResultSetJava::close() - closing result set" );

    jni->CallVoidMethod((jobject)jdbcRSRef_,
                        (jmethodID)lmj_->rsCloseId_);

    LM_DEBUG1( "ResultSet.close() returned %s", 
               jni->ExceptionOccurred() ? "an Exception" : "no Exception" );


    // Populate ComDiagsArea if there are any Java exceptions
    if( da )
      lmj_->exceptionReporter_->checkJVMException( da, 0 );
    else
      jni->ExceptionClear();  // If ComDiagsArea is not availabe then we clear
                              // any pending exception
  }

  // The below assertion check is only for an internal sanity check.
  //
  // We will need to decrement the reference count in the LmConnection
  // object but before that we first check if the LmConnection associated 
  // with this result set is existing otherwise we will assert.
  //
  NABoolean found = FALSE;
  ComUInt32 i = 0;

  for( i = 0; i < lmConnList_.entries(); i++ )
  {
    if( lmConn_ == lmConnList_[i] ) {
      found = TRUE;
      break;
    }
  }

  LM_ASSERT(found == TRUE);

  // Decrement the reference count on the associated
  // LmConnection object and remove the object from 
  // lmConnList_ if the connection gets closed.
  if( lmConn_->decrRefCnt() )
    lmConnList_.removeAt( i );


  // Finally delete this object
  delete this;
}

// This function handles the diagnostics
void
LmResultSetJava::insertIntoDiagnostic(ComDiagsArea &da, ComUInt32 col_num)
{
   da << DgSqlCode(-LME_JVM_RESULTSET_ROW_COLUMN_EXCEPTION)
      << DgInt0 ((Lng32) col_num); 
   lmj_->exceptionReporter_->checkJVMException(&da, 0);
}

// This function gets the value of given column of RS object
// as jlong value.
LmResult
LmResultSetJava::getValueAsJlong(jobject javaRS,
                                 ComUInt32 columnIndex,
                                 ComDiagsArea &da,
                                 NABoolean &wasNull,
                                 jlong &returnvalue)
{
  JNIEnv *jni = (JNIEnv*)lmj_->jniEnv_;

  // Get value as BigDecimal object
  jobject bigdecObj = jni->CallObjectMethod(javaRS,
                        (jmethodID)lmj_->rsGetBigDecimalId_,
                        columnIndex);

  if (jni->ExceptionOccurred())
  {
    insertIntoDiagnostic(da, columnIndex);
    return LM_ERR;
  }

  // Check if the value read was null
  wasNull = jni->CallBooleanMethod(javaRS, (jmethodID)lmj_->rsWasNullId_);
  if (jni->ExceptionOccurred())
  {
    insertIntoDiagnostic(da, columnIndex);
    return LM_ERR;
  }

  if (wasNull)
  {
    // Value is NULL, return from here
    return LM_OK;
  }

  // Get BigInteger from bigdecObj
  jobject bigintObj;
  bigintObj = jni->CallObjectMethod(bigdecObj,
                                    (jmethodID)lmj_->bigdecUnscaleId_);
  jni->DeleteLocalRef(bigdecObj);
  if (jni->ExceptionOccurred())
  {
    insertIntoDiagnostic(da, columnIndex);
    return LM_ERR;
  }

  // Get value as jlong from BigInteger
  returnvalue = jni->CallLongMethod(bigintObj,
                                    (jmethodID)lmj_->bigintLongValueId_);
  jni->DeleteLocalRef(bigintObj);

  if (jni->ExceptionOccurred())
  {
    insertIntoDiagnostic(da, columnIndex);
    return LM_ERR;
  }

  return LM_OK;
}

// This function processes one row at a time and returns 1, if it successes.
// If this code is changed in future to process more than one row and returns  
// more than 1, then fetchRowsFromJDBC() function in UdrResultSet.cpp file 
// is also required to change.  
Lng32
LmResultSetJava::fetchSpecialRows(void *dataPtr,
		                  LmParameter *colDesc,
                                  ComUInt32 numCols, 
                                  ComDiagsArea &da,  // will have errors 
                                  ComDiagsArea *rda) // will have warnings
{
  if (! moreSpecialRows())
    return 0;

  JNIEnv *jni = (JNIEnv*)lmj_->jniEnv_;
  jobject javaRS = (jobject) getResultSet();

  // The row at currentRowPosition_ is already accessed.
  // We need to move to next row and advance currentRowPosition_.
  NABoolean ret = (jni->CallBooleanMethod(javaRS, (jmethodID) lmj_->rsNextId_));
  if (jni->ExceptionOccurred())
  {  
     da << DgSqlCode(-LME_JVM_RESULTSET_NEXT_EXCEPTION);
     lmj_->exceptionReporter_->checkJVMException(&da, 0);
     return -1;
  } 

  if (ret)
  { // got next row
    currentRowPosition_++;
    Int32 has_warning = 0;
    
    for (ComUInt32 index = 0; index < numCols; index++)
    {
      Int32 conv_ret = 0;
      NABoolean wasNull = FALSE;
      LmParameter *col = &colDesc[index];
      char *thisColDataPtr = (char*)dataPtr + col->outDataOffset();

      Lng32 retcode = 0;
      LmResult lmResult = LM_OK;

      switch(LmJavaType(col).getType())
      {
        case LmJavaType::JT_TINY:
        {
          jlong jlval;
          lmResult = getValueAsJlong(javaRS, index + 1, da, wasNull, jlval);

          if (lmResult == LM_ERR)
          {
            retcode = -1;  // Diags are already populated
            break;
          }

          if (!wasNull)
	  {
            // Now cast jlong to appropriate value
            if (col->fsType() == COM_SIGNED_BIN8_FSDT)
            {
	      char sval = (char) jlval;
              memcpy(thisColDataPtr, (char *)&sval, col->outSize());
            }
            else
            {
              unsigned char sval = (unsigned char) jlval;
              memcpy(thisColDataPtr, (char *)&sval, col->outSize());
            }
	  }
          
        } // JT_TINY
        break;
        
        case LmJavaType::JT_SHORT:
        {
          jlong jlval;
          lmResult = getValueAsJlong(javaRS, index + 1, da, wasNull, jlval);

          if (lmResult == LM_ERR)
          {
            retcode = -1;  // Diags are already populated
            break;
          }

          if (!wasNull)
	  {
            // Now cast jlong to appropriate value
            if (col->fsType() == COM_SIGNED_BIN16_FSDT)
            {
	      short sval = (short) jlval;
              memcpy(thisColDataPtr, (char *)&sval, col->outSize());
            }
            else
            {
              unsigned short sval = (unsigned short) jlval;
              memcpy(thisColDataPtr, (char *)&sval, col->outSize());
            }
	  }
          
        } // JT_SHORT
        break;
        
        case LmJavaType::JT_INT:
        {
          jlong jlval;
          lmResult = getValueAsJlong(javaRS, index + 1, da, wasNull, jlval);
          
          if (lmResult == LM_ERR)
          {
            retcode = -1;  // Diags are already populated
            break;
          }
          
          if (!wasNull)
          {
            // Now cast jlong to appropriate value
            if (col->fsType() == COM_SIGNED_BIN32_FSDT)
            {
              Int32 ival = (Int32)jlval;
              memcpy(thisColDataPtr, (char *)&ival, col->outSize());
            }
            else
            {
              UInt32 ival = (UInt32)jlval;
              memcpy(thisColDataPtr, (char *)&ival, col->outSize());
            }
          }
          
        } // JT_INT
        break;
        
        case LmJavaType::JT_LONG:
        {
          jlong jlval;
          lmResult = getValueAsJlong(javaRS, index + 1, da, wasNull, jlval);
          
          if (lmResult == LM_ERR)
          {
            retcode = -1;  // Diags are already populated
            break;
          }

          if (!wasNull)
          {
            // Note: don't cast val to long. (long lval = (long) val;)
            // The reason is jlong is 64 bits long. On NSK system long long 
            // is 64 bits long and long is 32 bits long. 
	    // SQL LARGEINT is 64 bit long.
            memcpy(thisColDataPtr, (char *)&jlval, col->outSize());
          }
          
        } // JT_LONG
        break;
        
        case LmJavaType::JT_FLOAT:
        {
          jfloat val = jni->CallFloatMethod(javaRS,
                                            (jmethodID)lmj_->rsGetFloatId_,
                                            index + 1);
          if (jni->ExceptionOccurred())
          {
            insertIntoDiagnostic(da, index + 1);
            retcode = -1;
            break;
          }

          // Check if the value read was null
          wasNull = jni->CallBooleanMethod(javaRS,
                                           (jmethodID)lmj_->rsWasNullId_);
          if (jni->ExceptionOccurred())
          {
            insertIntoDiagnostic(da, index + 1);
            retcode = -1;
          }
          else if (!wasNull)
          {
            memcpy(thisColDataPtr, (char *)&val, col->outSize()); 
          }
          
        } // JT_FLOAT
        break;

        case LmJavaType::JT_DOUBLE:
        {
          jdouble val = jni->CallDoubleMethod(javaRS,
                                              (jmethodID)lmj_->rsGetDoubleId_,
                                              index + 1);
          if (jni->ExceptionOccurred())
          {
            insertIntoDiagnostic(da, index + 1);
            retcode = -1;
            break;
          }

          // Check if the value read was null
          wasNull = jni->CallBooleanMethod(javaRS,
                                           (jmethodID)lmj_->rsWasNullId_);
          if (jni->ExceptionOccurred())
          {
            insertIntoDiagnostic(da, index + 1);
            retcode = -1;
          }
          else if (!wasNull)
          {
            memcpy(thisColDataPtr, (char *)&val, col->outSize());
          }
          
        } // JT_DOUBLE
        break;
        
        case LmJavaType::JT_LANG_STRING:
        {
          // The SQL CHAR strings and SQL INTERVAL types are set as 
          // java string types since JDBC doesn't have type INTERVAL.
          // JDBC handles SQL INTERVAL types as Types.OTHER.
          jobject strObj =
            jni->CallObjectMethod(javaRS,
                                  (jmethodID)lmj_->rsGetObjectId_,
                                  index + 1);
          
          if (jni->ExceptionOccurred())
          {
            insertIntoDiagnostic(da, index + 1);
            retcode = -1;
            break;
          }

          // Check if the value read was null
          wasNull = jni->CallBooleanMethod(javaRS,
                                           (jmethodID)lmj_->rsWasNullId_);
          if (jni->ExceptionOccurred())
          {
            insertIntoDiagnostic(da, index + 1);
            retcode = -1;
          }
          else if (!wasNull)
          {
            if (col->isCharacter())
              conv_ret = lmj_->convertFromString(col, dataPtr, strObj, &da);
            else  // all interval types
              conv_ret = lmj_->convertFromInterval(col, dataPtr, strObj, &da);
            
            if (conv_ret == LM_PARAM_OVERFLOW)
              *rda << DgSqlCode(LME_DATA_OVERFLOW_WARN)
                   << DgInt0((Lng32) index + 1);
            
            if (conv_ret == LM_ERR)
	      retcode = -1;
          }

          jni->DeleteLocalRef(strObj);
                      
        } // JT_LANG_STRING
        break;

        case LmJavaType::JT_MATH_BIGDEC:
        {
          // NOTE: this is a long CASE block. If no Java exception
          // occurs inside the following call then we own an object
          // reference on the BigDecimal object that must be released
          // at the end of the CASE block. Try to avoid early return
          // or break statements or if any are necessary, use caution
          // and be sure to release the reference.

          jobject bigdecObj = jni->CallObjectMethod(javaRS,
                          (jmethodID)lmj_->rsGetBigDecimalId_,
                          index + 1);
          if (jni->ExceptionOccurred())
          {
            insertIntoDiagnostic(da, index + 1);
            retcode = -1;
            break;
          }

          // Check if the value read was null
          wasNull = jni->CallBooleanMethod(javaRS,
                                           (jmethodID)lmj_->rsWasNullId_);
          if (jni->ExceptionOccurred())
          {
            insertIntoDiagnostic(da, index + 1);
            retcode = -1;
          }
          else if (!wasNull)
          {
            // Several SQL types map to the Java BigDecimal type. Cases
            // to consider:
            // * NUMERIC precision > 18 (BIGNUM)
            // * NUMERIC precision <= 18
            // * DECIMAL
            
            if (col->isNumeric())
            {
	      if (col->isBigNum())
	      {
	        // NUMERIC precision > 18

                // Get the value in string format then call convDoIt
	        // to convert it to binary
		conv_ret = lmj_->convertFromBigdec(col, dataPtr, bigdecObj,
                                                   FALSE, // isDecimal
                                                   TRUE,  // copyBinary
                                                   &da);
                
                if (conv_ret == LM_PARAM_OVERFLOW)
                {
                   *rda << DgSqlCode(LME_DATA_OVERFLOW_WARN)
                        << DgInt0((Lng32) index + 1);
                }
                else if (conv_ret == LM_CONV_ERROR)
                {
                  da << DgSqlCode(-LME_CONVERT_ERROR)
                     << DgInt0 ((Lng32) (index + 1));
                  retcode = -1;
                }
                else if (conv_ret == LM_ERR)
                {
                  retcode = -1;
                }
                
	      } // NUMERIC precision > 18

              else
              {
                // NUMERIC precision <= 18
                jobject bigintObj;
                bigintObj =
                  jni->CallObjectMethod(bigdecObj, 
                                        (jmethodID)lmj_->bigdecUnscaleId_);
                
                if (jni->ExceptionOccurred())
                {
                  insertIntoDiagnostic(da, index + 1);
                  retcode = -1;
                }
                else
                {
                  jlong jlval;
                  jlval =
                    jni->CallLongMethod(bigintObj, 
                                        (jmethodID)lmj_->bigintLongValueId_);
                  jni->DeleteLocalRef(bigintObj);
                  
                  if (jni->ExceptionOccurred())
                  {
                    insertIntoDiagnostic(da, index + 1);
                    retcode = -1;
                  }
                  else
                  {
                    if ((col->fsType() == COM_SIGNED_BIN8_FSDT) ||
                        (col->fsType() == COM_UNSIGNED_BIN8_FSDT))
                    {
                      char sval = (char)jlval;
                      memcpy(thisColDataPtr, (char *)&sval, col->outSize());
                    }
                    else
                    if ((col->fsType() == COM_SIGNED_BIN16_FSDT) ||
                        (col->fsType() == COM_UNSIGNED_BIN16_FSDT))
                    {
                      short sval = (short)jlval;
                      memcpy(thisColDataPtr, (char *)&sval, col->outSize());
                    }
                    else
                    if ((col->fsType() == COM_SIGNED_BIN32_FSDT) ||
                          (col->fsType() == COM_UNSIGNED_BIN32_FSDT))
                    {
                      Int32 ival = (Int32)jlval;
                      memcpy(thisColDataPtr, (char *)&ival, col->outSize());
                    }
                    else
                    {
                      // 64 bit value
                      memcpy(thisColDataPtr, (char *)&jlval, col->outSize());
                    }
                  }

                } // if (exception) else ...
                
              } // NUMERIC precision <= 18
            } // NUMERIC
            
            else
            {
              // DECIMAL
              conv_ret = lmj_->convertFromBigdec(col, dataPtr, bigdecObj, 
                                                 col->isDecimal(),
                                                 TRUE /*copyBinary*/, &da); 
              
              if (conv_ret == LM_PARAM_OVERFLOW)
              {
                *rda << DgSqlCode(LME_DATA_OVERFLOW_WARN)
                     << DgInt0((Lng32) index + 1);
              }
              else if (conv_ret == LM_CONV_ERROR)
              {
                // We could have used EXE_CONVERT_STRING_ERROR. To use this
                // error we need to include ExpError.h file. If we include it,
                // then we had compilation issue even after changing 
                // the tdm_sqllangman.mak file.
                da << DgSqlCode(-LME_CONVERT_ERROR)
                   << DgInt0 ((Lng32) (index + 1));
                retcode = -1;
              }
              else if (conv_ret == LM_ERR)
              {
                retcode = -1;
              }
              
            } // DECIMAL
          } // if (!wasNull)
          
          jni->DeleteLocalRef(bigdecObj);
          
        } // JT_MATH_BIGDEC
        break;
        
        case LmJavaType::JT_SQL_DATE:
        {
          jobject dateObj = jni->CallObjectMethod(javaRS,
                                  (jmethodID)lmj_->rsGetObjectId_,
                                  index + 1);
          if (jni->ExceptionOccurred())
          {
            insertIntoDiagnostic(da, index + 1);
            retcode = -1;
            break;
          }
          
          // Check if the value read was null
          wasNull = jni->CallBooleanMethod(javaRS,
                                           (jmethodID)lmj_->rsWasNullId_);
          if (jni->ExceptionOccurred())
          {
            insertIntoDiagnostic(da, index + 1);
            retcode = -1;
          }
          else if (!wasNull)
          {
            conv_ret = lmj_->convertFromDate(col, dataPtr, dateObj, &da);
            
            if (conv_ret == LM_PARAM_OVERFLOW)
            {
              *rda << DgSqlCode(LME_DATA_OVERFLOW_WARN)
                   << DgInt0((Lng32) index + 1);
            }
            else if (conv_ret == LM_ERR)
            {
              retcode = -1;
            }
          }
          
          jni->DeleteLocalRef(dateObj);
          
        } // JT_SQL_DATE
        break;
        
        case LmJavaType::JT_SQL_TIME:
        {
          jobject timeObj =
            jni->CallObjectMethod(javaRS,
                                  (jmethodID)lmj_->rsGetTimeId_,
                                  index + 1);
          if (jni->ExceptionOccurred())
          {
            insertIntoDiagnostic(da, index + 1);
            retcode = -1;
            break;
          }
          
          // Check if the value read was null
          wasNull = jni->CallBooleanMethod(javaRS,
                                           (jmethodID)lmj_->rsWasNullId_);
          if (jni->ExceptionOccurred())
          {
            insertIntoDiagnostic(da, index + 1);
            retcode = -1;
          }
          else if (!wasNull)
          {
            conv_ret = lmj_->convertFromTime(col, dataPtr, timeObj, &da);

            if (conv_ret == LM_PARAM_OVERFLOW)
            {
              *rda << DgSqlCode(LME_DATA_OVERFLOW_WARN)
                   << DgInt0((Lng32) index + 1);
            }
            else if (conv_ret == LM_ERR)
            {
              retcode = -1;
            }
          }
          
          jni->DeleteLocalRef(timeObj);
          
        } // JT_SQL_TIME
        break;
        
        case LmJavaType::JT_SQL_TIMESTAMP:
        {
          jobject timestampObj =
            jni->CallObjectMethod(javaRS,
                                  (jmethodID)lmj_->rsGetTimestampId_,
                                  index + 1);
          if (jni->ExceptionOccurred())
          {
            insertIntoDiagnostic(da, index + 1);
            retcode = -1;
            break;
          }
          
          // Check if the value read was null
          wasNull = jni->CallBooleanMethod(javaRS,
                                           (jmethodID)lmj_->rsWasNullId_);
          if (jni->ExceptionOccurred())
          {
            insertIntoDiagnostic(da, index + 1);
            retcode = -1;
          }
          else if (!wasNull)
          {
            conv_ret = lmj_->convertFromTimestamp(col, dataPtr,
                                                  timestampObj, &da);
            if (conv_ret == LM_PARAM_OVERFLOW)
            {
              *rda << DgSqlCode(LME_DATA_OVERFLOW_WARN)
                   << DgInt0((Lng32) index + 1);
            }
            else if (conv_ret == LM_ERR)
            {
              retcode = -1;
            }
          }
          
          jni->DeleteLocalRef(timestampObj);

        } // JT_SQL_TIMESTAMP
        break;

        default:
          LM_ASSERT(TRUE); 
          break;
          
      } // switch (getType())
      
      if (retcode < 0)
        return retcode;
      
      if ((conv_ret == LM_PARAM_OVERFLOW) && (has_warning == 0))
        has_warning = 1;
      
      // Fill NULL indicator with correct bytes by calling setNull.
      col->setNullOutput((char *)dataPtr, wasNull);

    }  // for each column

    if (has_warning)
    {
      rda->setAllRowNumber(1, DgSqlCode::WARNING_);
    }
   
  }
  else
  {
    // RS.next() returned FALSE. This means that there are no rows left
    // for reading.
    currentRowPosition_ = lastBufferedRow_;
    return 0;
  }

  return 1;
}
