| /************************************************************************** |
| // @@@ 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 @@@ |
| **************************************************************************/ |
| // |
| // MODULE: SQLMXCommonFunctions.cpp |
| // |
| |
| #include <string> |
| #include <platform_ndcs.h> |
| #include <stdlib.h> |
| #include <wchar.h> |
| #include <errno.h> |
| #include <time.h> |
| #include <sql.h> |
| #include <sqlext.h> |
| #include <sqltypes.h> |
| #include <math.h> |
| #include <limits.h> |
| #include <float.h> |
| #include "sqlcli.h" |
| #include "JdbcDriverGlobal.h" |
| #include "org_apache_trafodion_jdbc_t2_SQLMXConnection.h" |
| #include "org_apache_trafodion_jdbc_t2_DataWrapper.h" |
| #include "SQLMXCommonFunctions.h" |
| #include "CoreCommon.h" |
| #include "SrvrCommon.h" |
| #include "SrvrOthers.h" |
| #include "Debug.h" |
| #include "GlobalInformation.h" |
| #include "org_apache_trafodion_jdbc_t2_T2Driver.h" //spjrs |
| |
| static const int INVALID_TRANSACTION_STATE = -1; |
| |
| static Charset_def CHARSET_INFORMATION[] = { |
| { SQLCHARSETCODE_ISO88591, "ISO8859_1", NULL, NULL}, |
| { SQLCHARSETCODE_KANJI, "Shift_JIS", NULL, NULL}, |
| { SQLCHARSETCODE_KSC5601, "EUC-KR", NULL, NULL}, |
| { SQLCHARSETCODE_SJIS, "SJIS", NULL, NULL}, |
| // { SQLCHARSETCODE_UCS2, "UTF-16BE", NULL, NULL}, |
| { SQLCHARSETCODE_UCS2, "UTF-16LE", NULL, NULL}, |
| { SQLCHARSETCODE_EUCJP, "EUCJP", NULL, NULL}, |
| { SQLCHARSETCODE_GB18030, "GB18030", NULL, NULL}, |
| { SQLCHARSETCODE_UTF8, "UTF-8", NULL, NULL}, |
| { SQLCHARSETCODE_GB2312, "GB2312", NULL, NULL}, |
| { 0, NULL, NULL, NULL}}; |
| |
| static bool createWrapper(struct WrapperInfoStruct *wrapperInfo, JNIEnv *jenv, jsize totalColumns, bool allocateWrapper) |
| { |
| FUNCTION_ENTRY("createWrapper", |
| ("size=%ld, allocateWrapper=%s", |
| totalColumns, |
| DebugBoolStr(allocateWrapper))); |
| memset(wrapperInfo,0,sizeof(*wrapperInfo)); |
| wrapperInfo->jenv = jenv; |
| wrapperInfo->totalColumns = totalColumns; |
| if (allocateWrapper) |
| { |
| wrapperInfo->wrapper = wrapperInfo->jenv->NewObject(gJNICache.wrapperClass,gJNICache.wrapperConstructorId, totalColumns); |
| |
| if (wrapperInfo->wrapper == NULL) |
| { |
| // Could not allocate JVM memory. |
| FUNCTION_RETURN_NUMERIC(FALSE,("%s",DebugBoolStr(FALSE))); |
| } |
| } |
| FUNCTION_RETURN_NUMERIC(TRUE,("%s",DebugBoolStr(TRUE))); |
| } |
| |
| static void updateWrapperElements(struct WrapperInfoStruct *wrapperInfo) |
| { |
| FUNCTION_ENTRY("updateWrapperElements", |
| ("wrapper=0x%08x, wrapperInfo->totalColumns=%ld", |
| wrapperInfo->wrapper, |
| wrapperInfo->totalColumns)); |
| if (wrapperInfo->dataTypeObject) |
| JNI_SetByteArrayRegion(wrapperInfo->jenv,wrapperInfo->dataTypeObject,0,wrapperInfo->totalColumns,wrapperInfo->dataType); |
| if (wrapperInfo->setNeededObject) |
| JNI_SetBooleanArrayRegion(wrapperInfo->jenv,wrapperInfo->setNeededObject,0,wrapperInfo->totalColumns,wrapperInfo->setNeeded); |
| if (wrapperInfo->longValueObject) |
| JNI_SetLongArrayRegion(wrapperInfo->jenv,wrapperInfo->longValueObject,0,wrapperInfo->totalColumns,wrapperInfo->longValue); |
| if (wrapperInfo->floatValueObject) |
| JNI_SetFloatArrayRegion(wrapperInfo->jenv,wrapperInfo->floatValueObject,0,wrapperInfo->totalColumns,wrapperInfo->floatValue); |
| if (wrapperInfo->doubleValueObject) |
| JNI_SetDoubleArrayRegion(wrapperInfo->jenv,wrapperInfo->doubleValueObject,0,wrapperInfo->totalColumns,wrapperInfo->doubleValue); |
| if (wrapperInfo->SQLbytesArrayObject) |
| JNI_SetByteArrayRegion(wrapperInfo->jenv,wrapperInfo->SQLbytesArrayObject,0,wrapperInfo->totalColumns,wrapperInfo->SQLbytesArray); |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| static jbyte getWrapperDataType(struct WrapperInfoStruct *wrapperInfo, jint paramNumber) |
| { |
| FUNCTION_ENTRY("getWrapperDataType", |
| ("wrapper=0x%08x, paramNumber=%ld", |
| wrapperInfo->wrapper, |
| paramNumber)); |
| if (wrapperInfo->dataTypeObject==NULL) |
| { |
| jboolean isCopy; |
| wrapperInfo->dataTypeObject = (jbyteArray) JNI_GetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperDataTypeFieldId); |
| DEBUG_ASSERT(wrapperInfo->dataTypeObject!=NULL,("GetObjectField() failed")); |
| wrapperInfo->dataType = JNI_GetByteArrayElements(wrapperInfo->jenv,wrapperInfo->dataTypeObject, &isCopy); |
| DEBUG_ASSERT(wrapperInfo->dataType!=NULL,("GetByteArrayElements() failed")); |
| } |
| FUNCTION_RETURN_NUMERIC(wrapperInfo->dataType[paramNumber], |
| ("dataType=%s",WrapperDataTypeStr(wrapperInfo->dataType[paramNumber]))); |
| } |
| |
| static void setWrapperDataType(struct WrapperInfoStruct *wrapperInfo, jint paramNumber, jbyte value) |
| { |
| FUNCTION_ENTRY("setWrapperDataType", |
| ("wrapper=0x%08x, paramNumber=%ld, value=%s", |
| wrapperInfo->wrapper, |
| paramNumber, |
| WrapperDataTypeStr(value))); |
| |
| // If the dataType array object is not allocated, just call getWrapperDataType() |
| // to allocate it. |
| if (wrapperInfo->dataTypeObject==NULL) getWrapperDataType(wrapperInfo, paramNumber); |
| wrapperInfo->dataType[paramNumber] = value; |
| if (wrapperInfo->setNeededObject==NULL) |
| { |
| jboolean isCopy; |
| wrapperInfo->setNeededObject = (jbooleanArray) JNI_GetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperSetNeededFieldId); |
| DEBUG_ASSERT(wrapperInfo->setNeededObject!=NULL,("GetObjectField() failed")); |
| wrapperInfo->setNeeded = JNI_GetBooleanArrayElements(wrapperInfo->jenv,wrapperInfo->setNeededObject, &isCopy); |
| DEBUG_ASSERT(wrapperInfo->setNeeded!=NULL,("GetBooleanArrayElements() failed")); |
| } |
| wrapperInfo->setNeeded[paramNumber] = true; |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| static jboolean getWrapperIsNull(struct WrapperInfoStruct *wrapperInfo, jint paramNumber) |
| { |
| FUNCTION_ENTRY("getWrapperIsNull", |
| ("wrapper=0x%08x, paramNumber=%ld", |
| wrapperInfo->wrapper, |
| paramNumber)); |
| if (wrapperInfo->isNullObject==NULL) |
| { |
| jboolean isCopy; |
| wrapperInfo->isNullObject = (jbooleanArray) JNI_GetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperIsNullFieldId); |
| DEBUG_ASSERT(wrapperInfo->isNullObject!=NULL,("GetObjectField() failed")); |
| wrapperInfo->isNull = JNI_GetBooleanArrayElements(wrapperInfo->jenv,wrapperInfo->isNullObject, &isCopy); |
| DEBUG_ASSERT(wrapperInfo->isNull!=NULL,("GetBooleanArrayElements() failed")); |
| } |
| FUNCTION_RETURN_NUMERIC(wrapperInfo->isNull[paramNumber],(NULL)); |
| |
| } |
| |
| static jbyte *getWrapperBytes(struct WrapperInfoStruct *wrapperInfo, jint paramNumber) |
| { |
| FUNCTION_ENTRY("getWrapperBytes", |
| ("wrapper=0x%08x, paramNumber=%ld", |
| wrapperInfo->wrapper, |
| paramNumber)); |
| jboolean isCopy; |
| if (wrapperInfo->bytesValueObject==NULL) |
| { |
| wrapperInfo->bytesValueObject = (jobjectArray) JNI_GetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperBytesFieldId); |
| DEBUG_ASSERT(wrapperInfo->bytesValueObject!=NULL,("GetObjectField() failed")); |
| } |
| if (wrapperInfo->bytesArrayObject) |
| JNI_ReleaseByteArrayElements(wrapperInfo->jenv,wrapperInfo->bytesArrayObject,wrapperInfo->bytesArray,JNI_ABORT); |
| wrapperInfo->bytesArrayObject = (jbyteArray) JNI_GetObjectArrayElement(wrapperInfo->jenv,wrapperInfo->bytesValueObject,paramNumber); |
| DEBUG_ASSERT(wrapperInfo->bytesArrayObject!=NULL,("GetObjectArrayElement() failed")); |
| wrapperInfo->bytesArray = JNI_GetByteArrayElements(wrapperInfo->jenv,wrapperInfo->bytesArrayObject, &isCopy); |
| DEBUG_ASSERT(wrapperInfo->bytesArray!=NULL,("GetByteArrayElements() failed")); |
| FUNCTION_RETURN_PTR(wrapperInfo->bytesArray,(NULL)); |
| } |
| |
| static void setupWrapperBytes(struct WrapperInfoStruct *wrapperInfo) |
| { |
| // This method is implemented in DataWrapper.setupBytes() also. Any changes need to be made in both places |
| FUNCTION_ENTRY("setupWrapperBytes", |
| ("wrapper=0x%08x", |
| wrapperInfo->wrapper)); |
| |
| DEBUG_ASSERT(wrapperInfo->bytesValueObject==NULL,("Bytes array object is not NULL")); |
| wrapperInfo->bytesValueObject = JNI_NewObjectArray(wrapperInfo->jenv,wrapperInfo->totalColumns,gJNICache.byteArrayClass,NULL); |
| DEBUG_ASSERT(wrapperInfo->bytesValueObject!=NULL,("NewObjectArray() failed")); |
| JNI_SetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperBytesFieldId,wrapperInfo->bytesValueObject); |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| static void setWrapperBytes(struct WrapperInfoStruct *wrapperInfo, jint paramNumber, jbyteArray value) |
| { |
| FUNCTION_ENTRY("setWrapperBytes", |
| ("wrapper=0x%08x, paramNumber=%ld", |
| wrapperInfo->wrapper, |
| paramNumber)); |
| if (wrapperInfo->bytesValueObject==NULL) |
| { |
| wrapperInfo->bytesValueObject = (jobjectArray) JNI_GetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperBytesFieldId); |
| if (wrapperInfo->bytesValueObject==NULL) |
| { |
| // Need to setup bytes array |
| setupWrapperBytes(wrapperInfo); |
| } |
| } |
| JNI_SetObjectArrayElement(wrapperInfo->jenv,wrapperInfo->bytesValueObject,paramNumber,value); |
| setWrapperDataType(wrapperInfo,paramNumber,org_apache_trafodion_jdbc_t2_DataWrapper_BYTES); |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| static void setupWrapperSQLBytes(struct WrapperInfoStruct *wrapperInfo) |
| { |
| // This method is implemented in DataWrapper.setupSQLBytes() also. Any changes need to be made in both places |
| FUNCTION_ENTRY("setupWrapperSQLBytes", |
| ("wrapper=0x%08x", |
| wrapperInfo->wrapper)); |
| |
| DEBUG_ASSERT(wrapperInfo->SQLbytesArrayObject==NULL,("SQLBytes array object is not NULL")); |
| wrapperInfo->SQLbytesValueObject = JNI_NewObjectArray(wrapperInfo->jenv,wrapperInfo->totalColumns,gJNICache.SQLbyteArrayClass,NULL); |
| DEBUG_ASSERT(wrapperInfo->SQLbytesValueObject!=NULL,("NewObjectArray() failed")); |
| JNI_SetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperSQLBytesFieldId,wrapperInfo->SQLbytesValueObject); |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| static void setWrapperSQLBytes(struct WrapperInfoStruct *wrapperInfo, jint paramNumber, jbyteArray value) |
| { |
| FUNCTION_ENTRY("setWrapperSQLBytes", |
| ("wrapper=0x%08x, paramNumber=%ld", |
| wrapperInfo->wrapper, |
| paramNumber)); |
| if (wrapperInfo->SQLbytesValueObject==NULL) |
| { |
| wrapperInfo->SQLbytesValueObject = (jobjectArray) JNI_GetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperSQLBytesFieldId); |
| if (wrapperInfo->SQLbytesValueObject==NULL) |
| { |
| // Need to setup bytes array |
| setupWrapperSQLBytes(wrapperInfo); |
| } |
| } |
| JNI_SetObjectArrayElement(wrapperInfo->jenv,wrapperInfo->SQLbytesValueObject,paramNumber,value); |
| setWrapperDataType(wrapperInfo,paramNumber,org_apache_trafodion_jdbc_t2_DataWrapper_BYTES); |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| //============================ |
| // Big Num Changes |
| static jbyteArray convertBigDecimalToSQLBigNum(struct WrapperInfoStruct *wrapperInfo, jint paramNumber, jint scale, jint targetLength) |
| { |
| FUNCTION_ENTRY("convertBigDecimalToSQLBigNum", |
| ("wrapper=0x%08x, paramNumber=%ld, scale=%ld, targetLength=%ld", |
| wrapperInfo->wrapper, |
| paramNumber, scale, targetLength)); |
| // We are incrementing the param number because its zero based in Native side |
| jbyteArray returnValue = (jbyteArray)wrapperInfo->jenv->CallObjectMethod(wrapperInfo->wrapper, |
| gJNICache.wrapperconvertBigDecimalToSQLBigNum, paramNumber+1, scale, targetLength); |
| FUNCTION_RETURN_PTR((jbyteArray)returnValue,(NULL)); |
| } |
| static jstring convertSQLBigNumToBigDecimal2(struct WrapperInfoStruct *wrapperInfo, jbyteArray columnValue, jint scale) |
| { |
| FUNCTION_ENTRY("convertSQLBigNumToBigDecimal2", |
| ("wrapper=0x%08x, columnValue=0x%08x, scale=%ld", |
| wrapperInfo->wrapper, columnValue, |
| scale)); |
| // Call the method. |
| jstring returnValue = (jstring)wrapperInfo->jenv->CallObjectMethod(wrapperInfo->wrapper, |
| gJNICache.wrapperconvertSQLBigNumToBigDecimal2, columnValue, scale); |
| FUNCTION_RETURN_PTR((jstring)returnValue,(NULL)); |
| } |
| // Big Num Changes |
| static jobject getWrapperObject(struct WrapperInfoStruct *wrapperInfo, jint paramNumber) |
| { |
| FUNCTION_ENTRY("getWrapperObject", |
| ("wrapper=0x%08x, paramNumber=%ld", |
| wrapperInfo->wrapper, |
| paramNumber)); |
| if (wrapperInfo->objectValueObject==NULL) |
| { |
| wrapperInfo->objectValueObject = (jobjectArray) JNI_GetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperObjectFieldId); |
| DEBUG_ASSERT(wrapperInfo->objectValueObject!=NULL,("GetObjectField() failed")); |
| } |
| wrapperInfo->objectValue = JNI_GetObjectArrayElement(wrapperInfo->jenv,wrapperInfo->objectValueObject,paramNumber); |
| DEBUG_ASSERT(wrapperInfo->objectValue!=NULL,("GetObjectArrayElement() failed")); |
| FUNCTION_RETURN_PTR(wrapperInfo->objectValue,(NULL)); |
| } |
| |
| static bool setWrapperObject(struct WrapperInfoStruct *wrapperInfo, jint paramNumber, jobject value, jbyte data_type) |
| { |
| FUNCTION_ENTRY("setWrapperObject", |
| ("wrapper=0x%08x, paramNumber=%ld, data_type=%s", |
| wrapperInfo->wrapper, |
| paramNumber, |
| WrapperDataTypeStr(data_type))); |
| |
| if (data_type==org_apache_trafodion_jdbc_t2_DataWrapper_STRING) |
| DEBUG_OUT(DEBUG_LEVEL_ENTRY,("String Value=%s",DebugJString(wrapperInfo->jenv,value))); |
| |
| if (wrapperInfo->objectValueObject==NULL) |
| { |
| wrapperInfo->objectValueObject = (jobjectArray) JNI_GetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperObjectFieldId); |
| if (wrapperInfo->objectValueObject==NULL) |
| { |
| wrapperInfo->jenv->CallVoidMethod(wrapperInfo->wrapper, gJNICache.wrapperSetupObjectsMethodId); |
| wrapperInfo->objectValueObject = (jobjectArray) JNI_GetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperObjectFieldId); |
| DEBUG_ASSERT(wrapperInfo->objectValueObject!=NULL,("GetObjectField() failed")); |
| if (wrapperInfo->objectValueObject==NULL) // Could not allocate JVM memory. |
| FUNCTION_RETURN_NUMERIC(FALSE,("setWrapperObject - JNI_GetObjectField() failed")); |
| } |
| } |
| JNI_SetObjectArrayElement(wrapperInfo->jenv,wrapperInfo->objectValueObject,paramNumber,value); |
| setWrapperDataType(wrapperInfo,paramNumber,data_type); |
| FUNCTION_RETURN_NUMERIC(TRUE,("%s",DebugBoolStr(TRUE))); |
| } |
| |
| static jbyte getWrapperByte(struct WrapperInfoStruct *wrapperInfo, jint paramNumber) |
| { |
| FUNCTION_ENTRY("getWrapperByte", |
| ("wrapper=0x%08x, paramNumber=%ld", |
| wrapperInfo->wrapper, |
| paramNumber)); |
| if (wrapperInfo->byteValueObject==NULL) |
| { |
| jboolean isCopy; |
| wrapperInfo->byteValueObject = (jbyteArray) JNI_GetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperByteFieldId); |
| DEBUG_ASSERT(wrapperInfo->byteValueObject!=NULL,("GetObjectField() failed")); |
| wrapperInfo->byteValue = JNI_GetByteArrayElements(wrapperInfo->jenv,wrapperInfo->byteValueObject, &isCopy); |
| DEBUG_ASSERT(wrapperInfo->byteValue!=NULL,("GetByteArrayElements() failed")); |
| } |
| FUNCTION_RETURN_NUMERIC(wrapperInfo->byteValue[paramNumber],(NULL)); |
| } |
| |
| static jshort getWrapperShort(struct WrapperInfoStruct *wrapperInfo, jint paramNumber) |
| { |
| FUNCTION_ENTRY("getWrapperShort", |
| ("wrapper=0x%08x, paramNumber=%ld", |
| wrapperInfo->wrapper, |
| paramNumber)); |
| if (wrapperInfo->shortValueObject==NULL) |
| { |
| jboolean isCopy; |
| wrapperInfo->shortValueObject = (jshortArray) JNI_GetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperShortFieldId); |
| DEBUG_ASSERT(wrapperInfo->shortValueObject!=NULL,("GetObjectField() failed")); |
| wrapperInfo->shortValue = JNI_GetShortArrayElements(wrapperInfo->jenv,wrapperInfo->shortValueObject, &isCopy); |
| DEBUG_ASSERT(wrapperInfo->shortValue!=NULL,("GetShortArrayElements() failed")); |
| } |
| FUNCTION_RETURN_NUMERIC(wrapperInfo->shortValue[paramNumber],(NULL)); |
| } |
| |
| static jint getWrapperInt(struct WrapperInfoStruct *wrapperInfo, jint paramNumber) |
| { |
| FUNCTION_ENTRY("getWrapperInt", |
| ("wrapper=0x%08x, paramNumber=%ld", |
| wrapperInfo->wrapper, |
| paramNumber)); |
| if (wrapperInfo->intValueObject==NULL) |
| { |
| jboolean isCopy; |
| wrapperInfo->intValueObject = (jintArray) JNI_GetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperIntFieldId); |
| DEBUG_ASSERT(wrapperInfo->intValueObject!=NULL,("GetObjectField() failed")); |
| wrapperInfo->intValue = JNI_GetIntArrayElements(wrapperInfo->jenv,wrapperInfo->intValueObject, &isCopy); |
| DEBUG_ASSERT(wrapperInfo->intValue!=NULL,("GetIntArrayElements() failed")); |
| } |
| FUNCTION_RETURN_NUMERIC(wrapperInfo->intValue[paramNumber],(NULL)); |
| } |
| |
| static jlong getWrapperLong(struct WrapperInfoStruct *wrapperInfo, jint paramNumber) |
| { |
| FUNCTION_ENTRY("getWrapperLong", |
| ("wrapper=0x%08x, paramNumber=%ld", |
| wrapperInfo->wrapper, |
| paramNumber)); |
| if (wrapperInfo->longValueObject==NULL) |
| { |
| jboolean isCopy; |
| wrapperInfo->longValueObject = (jlongArray) JNI_GetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperLongFieldId); |
| DEBUG_ASSERT(wrapperInfo->longValueObject!=NULL,("GetObjectField() failed")); |
| wrapperInfo->longValue = JNI_GetLongArrayElements(wrapperInfo->jenv,wrapperInfo->longValueObject, &isCopy); |
| DEBUG_ASSERT(wrapperInfo->longValue!=NULL,("GetLongArrayElements() failed")); |
| } |
| FUNCTION_RETURN_INT64(wrapperInfo->longValue[paramNumber],(NULL)); |
| } |
| |
| static void setWrapperLong(struct WrapperInfoStruct *wrapperInfo, jint paramNumber, jlong value) |
| { |
| FUNCTION_ENTRY("setWrapperLong", |
| ("wrapper=0x%08x, paramNumber=%ld, value=%Ld", |
| wrapperInfo->wrapper, |
| paramNumber, |
| value)); |
| if (wrapperInfo->longValueObject==NULL) |
| { |
| jboolean isCopy; |
| wrapperInfo->longValueObject = (jlongArray) JNI_GetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperLongFieldId); |
| DEBUG_ASSERT(wrapperInfo->longValueObject!=NULL,("GetObjectField() failed")); |
| wrapperInfo->longValue = JNI_GetLongArrayElements(wrapperInfo->jenv,wrapperInfo->longValueObject, &isCopy); |
| DEBUG_ASSERT(wrapperInfo->longValue!=NULL,("GetLongArrayElements() failed")); |
| } |
| wrapperInfo->longValue[paramNumber] = value; |
| setWrapperDataType(wrapperInfo,paramNumber,org_apache_trafodion_jdbc_t2_DataWrapper_LONG); |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| static jfloat getWrapperFloat(struct WrapperInfoStruct *wrapperInfo, jint paramNumber) |
| { |
| FUNCTION_ENTRY("getWrapperFloat", |
| ("wrapper=0x%08x, paramNumber=%ld", |
| wrapperInfo->wrapper, |
| paramNumber)); |
| if (wrapperInfo->floatValueObject==NULL) |
| { |
| jboolean isCopy; |
| wrapperInfo->floatValueObject = (jfloatArray) JNI_GetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperFloatFieldId); |
| DEBUG_ASSERT(wrapperInfo->floatValueObject!=NULL,("GetObjectField() failed")); |
| wrapperInfo->floatValue = JNI_GetFloatArrayElements(wrapperInfo->jenv,wrapperInfo->floatValueObject, &isCopy); |
| DEBUG_ASSERT(wrapperInfo->floatValue!=NULL,("GetFloatArrayElements() failed")); |
| } |
| FUNCTION_RETURN_FLOAT(wrapperInfo->floatValue[paramNumber],(NULL)); |
| } |
| |
| static void setWrapperFloat(struct WrapperInfoStruct *wrapperInfo, jint paramNumber, jfloat value) |
| { |
| FUNCTION_ENTRY("setWrapperFloat", |
| ("wrapper=0x%08x, paramNumber=%ld, value=%f", |
| wrapperInfo->wrapper, |
| paramNumber, |
| value)); |
| if (wrapperInfo->floatValueObject==NULL) |
| { |
| jboolean isCopy; |
| wrapperInfo->floatValueObject = (jfloatArray) JNI_GetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperFloatFieldId); |
| DEBUG_ASSERT(wrapperInfo->floatValueObject!=NULL,("GetObjectField() failed")); |
| wrapperInfo->floatValue = JNI_GetFloatArrayElements(wrapperInfo->jenv,wrapperInfo->floatValueObject, &isCopy); |
| DEBUG_ASSERT(wrapperInfo->floatValue!=NULL,("GetFloatArrayElements() failed")); |
| } |
| wrapperInfo->floatValue[paramNumber] = value; |
| setWrapperDataType(wrapperInfo,paramNumber,org_apache_trafodion_jdbc_t2_DataWrapper_FLOAT); |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| static jdouble getWrapperDouble(struct WrapperInfoStruct *wrapperInfo, jint paramNumber) |
| { |
| FUNCTION_ENTRY("getWrapperDouble", |
| ("wrapper=0x%08x, paramNumber=%ld", |
| wrapperInfo->wrapper, |
| paramNumber)); |
| if (wrapperInfo->doubleValueObject==NULL) |
| { |
| jboolean isCopy; |
| wrapperInfo->doubleValueObject = (jdoubleArray) JNI_GetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperDoubleFieldId); |
| DEBUG_ASSERT(wrapperInfo->doubleValueObject!=NULL,("GetObjectField() failed")); |
| wrapperInfo->doubleValue = JNI_GetDoubleArrayElements(wrapperInfo->jenv,wrapperInfo->doubleValueObject, &isCopy); |
| DEBUG_ASSERT(wrapperInfo->doubleValue!=NULL,("GetDoubleArrayElements() failed")); |
| } |
| FUNCTION_RETURN_DOUBLE(wrapperInfo->doubleValue[paramNumber],(NULL)); |
| } |
| |
| static void setWrapperDouble(struct WrapperInfoStruct *wrapperInfo, jint paramNumber, jdouble value) |
| { |
| FUNCTION_ENTRY("setWrapperDouble", |
| ("wrapper=0x%08x, paramNumber=%ld, value=%g", |
| wrapperInfo->wrapper, |
| paramNumber, |
| value)); |
| if (wrapperInfo->doubleValueObject==NULL) |
| { |
| jboolean isCopy; |
| wrapperInfo->doubleValueObject = (jdoubleArray) JNI_GetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperDoubleFieldId); |
| DEBUG_ASSERT(wrapperInfo->doubleValueObject!=NULL,("GetObjectField() failed")); |
| wrapperInfo->doubleValue = JNI_GetDoubleArrayElements(wrapperInfo->jenv,wrapperInfo->doubleValueObject, &isCopy); |
| DEBUG_ASSERT(wrapperInfo->doubleValue!=NULL,("GetDoubleArrayElements() failed")); |
| } |
| wrapperInfo->doubleValue[paramNumber] = value; |
| setWrapperDataType(wrapperInfo,paramNumber,org_apache_trafodion_jdbc_t2_DataWrapper_DOUBLE); |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| static jboolean getWrapperBoolean(struct WrapperInfoStruct *wrapperInfo, jint paramNumber) |
| { |
| FUNCTION_ENTRY("getWrapperBoolean", |
| ("wrapper=0x%08x, paramNumber=%ld", |
| wrapperInfo->wrapper, |
| paramNumber)); |
| if (wrapperInfo->booleanValueObject==NULL) |
| { |
| jboolean isCopy; |
| wrapperInfo->booleanValueObject = (jbooleanArray) JNI_GetObjectField(wrapperInfo->jenv,wrapperInfo->wrapper,gJNICache.wrapperBooleanFieldId); |
| DEBUG_ASSERT(wrapperInfo->booleanValueObject!=NULL,("GetObjectField() failed")); |
| wrapperInfo->booleanValue = JNI_GetBooleanArrayElements(wrapperInfo->jenv,wrapperInfo->booleanValueObject, &isCopy); |
| DEBUG_ASSERT(wrapperInfo->booleanValue!=NULL,("GetBooleanArrayElements() failed")); |
| } |
| FUNCTION_RETURN_NUMERIC(wrapperInfo->booleanValue[paramNumber],(NULL)); |
| } |
| |
| static void cleanupWrapperBytesArray(struct WrapperInfoStruct *wrapperInfo) |
| { |
| FUNCTION_ENTRY("cleanupWrapperBytesArray", |
| ("wrapper=0x%08x", |
| wrapperInfo->wrapper)); |
| if (wrapperInfo->bytesArrayObject) |
| { |
| JNI_ReleaseByteArrayElements(wrapperInfo->jenv,wrapperInfo->bytesArrayObject,wrapperInfo->bytesArray,JNI_ABORT); |
| wrapperInfo->bytesArrayObject = NULL; |
| wrapperInfo->bytesArray = NULL; |
| } |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| static void cleanupWrapperSQLBytesArray(struct WrapperInfoStruct *wrapperInfo) |
| { |
| FUNCTION_ENTRY("cleanupWrapperSQLBytesArray", |
| ("wrapper=0x%08x", |
| wrapperInfo->wrapper)); |
| if (wrapperInfo->SQLbytesArrayObject) |
| { |
| JNI_ReleaseByteArrayElements(wrapperInfo->jenv,wrapperInfo->SQLbytesArrayObject,wrapperInfo->SQLbytesArray,JNI_ABORT); |
| wrapperInfo->SQLbytesArrayObject = NULL; |
| wrapperInfo->SQLbytesArray = NULL; |
| } |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| //============== |
| static void cleanupWrapperInfo(struct WrapperInfoStruct *wrapperInfo) |
| { |
| FUNCTION_ENTRY("cleanupWrapperInfo", |
| ("wrapper=0x%08x", |
| wrapperInfo->wrapper)); |
| if (wrapperInfo->dataTypeObject) |
| { |
| JNI_ReleaseByteArrayElements(wrapperInfo->jenv,wrapperInfo->dataTypeObject,wrapperInfo->dataType,JNI_ABORT); |
| wrapperInfo->dataTypeObject = NULL; |
| wrapperInfo->dataType = NULL; |
| } |
| if (wrapperInfo->setNeededObject) |
| { |
| JNI_ReleaseBooleanArrayElements(wrapperInfo->jenv,wrapperInfo->setNeededObject,wrapperInfo->setNeeded,JNI_ABORT); |
| wrapperInfo->setNeededObject = NULL; |
| wrapperInfo->setNeeded = NULL; |
| } |
| if (wrapperInfo->isNullObject) |
| { |
| JNI_ReleaseBooleanArrayElements(wrapperInfo->jenv,wrapperInfo->isNullObject,wrapperInfo->isNull,JNI_ABORT); |
| wrapperInfo->isNullObject = NULL; |
| wrapperInfo->isNull = NULL; |
| } |
| if (wrapperInfo->byteValueObject) |
| { |
| JNI_ReleaseByteArrayElements(wrapperInfo->jenv,wrapperInfo->byteValueObject,wrapperInfo->byteValue,JNI_ABORT); |
| wrapperInfo->byteValueObject = NULL; |
| wrapperInfo->byteValue = NULL; |
| } |
| if (wrapperInfo->shortValueObject) |
| { |
| JNI_ReleaseShortArrayElements(wrapperInfo->jenv,wrapperInfo->shortValueObject,wrapperInfo->shortValue,JNI_ABORT); |
| wrapperInfo->shortValueObject = NULL; |
| wrapperInfo->shortValue = NULL; |
| } |
| if (wrapperInfo->intValueObject) |
| { |
| JNI_ReleaseIntArrayElements(wrapperInfo->jenv,wrapperInfo->intValueObject,wrapperInfo->intValue,JNI_ABORT); |
| wrapperInfo->intValueObject = NULL; |
| wrapperInfo->intValue = NULL; |
| } |
| if (wrapperInfo->longValueObject) |
| { |
| JNI_ReleaseLongArrayElements(wrapperInfo->jenv,wrapperInfo->longValueObject,wrapperInfo->longValue,JNI_ABORT); |
| wrapperInfo->longValueObject = NULL; |
| wrapperInfo->longValue = NULL; |
| } |
| if (wrapperInfo->floatValueObject) |
| { |
| JNI_ReleaseFloatArrayElements(wrapperInfo->jenv,wrapperInfo->floatValueObject,wrapperInfo->floatValue,JNI_ABORT); |
| wrapperInfo->floatValueObject = NULL; |
| wrapperInfo->floatValue = NULL; |
| } |
| if (wrapperInfo->doubleValueObject) |
| { |
| JNI_ReleaseDoubleArrayElements(wrapperInfo->jenv,wrapperInfo->doubleValueObject,wrapperInfo->doubleValue,JNI_ABORT); |
| wrapperInfo->doubleValueObject = NULL; |
| wrapperInfo->doubleValue = NULL; |
| } |
| if (wrapperInfo->booleanValueObject) |
| { |
| JNI_ReleaseBooleanArrayElements(wrapperInfo->jenv,wrapperInfo->booleanValueObject,wrapperInfo->booleanValue,JNI_ABORT); |
| wrapperInfo->booleanValueObject = NULL; |
| wrapperInfo->booleanValue = NULL; |
| } |
| cleanupWrapperBytesArray(wrapperInfo); |
| wrapperInfo->bytesValueObject = NULL; |
| |
| cleanupWrapperSQLBytesArray(wrapperInfo); |
| wrapperInfo->SQLbytesValueObject = NULL; |
| |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| BOOL dataLengthNotExceeded(jint charSet, jint dataLen, jint allocLen) |
| { |
| FUNCTION_ENTRY("dataLengthNotExceeded", |
| ("charset=%s, dataLen=%ld, allocLen=%ld", |
| getCharsetEncoding(charSet), |
| dataLen, |
| allocLen)); |
| |
| bool lengthOK = TRUE; |
| switch (charSet) |
| { |
| case SQLCHARSETCODE_ISO88591: |
| if (dataLen >= allocLen) |
| lengthOK = FALSE; |
| break; |
| case SQLCHARSETCODE_KANJI: |
| case SQLCHARSETCODE_KSC5601: |
| case SQLCHARSETCODE_UCS2: |
| if (dataLen > allocLen) |
| lengthOK = FALSE; |
| break; |
| } |
| FUNCTION_RETURN_NUMERIC(lengthOK,(NULL)); |
| } |
| |
| void throwSQLException(JNIEnv *jenv, const odbc_SQLSvc_SQLError *SQLError) |
| { |
| FUNCTION_ENTRY_LEVEL(DEBUG_LEVEL_ERROR,"throwSQLException",("jenv=0x%08x, SQLError=0x%08x", |
| jenv, |
| SQLError)); |
| jthrowable sqlException; |
| jthrowable sqlExceptionHead; |
| jstring sqlMessage; |
| jstring sqlState; |
| unsigned long curErrorNo; |
| ERROR_DESC_def *error_desc_def; |
| |
| // Clear any pending exceptions |
| // Otherwise, unexpected behaviour |
| JNI_ExceptionClear(jenv); |
| |
| if (SQLError->errorList._length == 0) |
| { |
| throwSQLException(jenv, NO_ERROR_MESSAGE_ERROR, NULL, "HY000"); |
| FUNCTION_RETURN_VOID(("NO_ERROR_MESSAGE_ERROR")); |
| } |
| |
| for (curErrorNo = 0, error_desc_def = SQLError->errorList._buffer; |
| curErrorNo < SQLError->errorList._length ; curErrorNo++, error_desc_def++) |
| |
| { |
| DEBUG_OUT(DEBUG_LEVEL_ERROR,("sqlstate=%s, errorText=%s", |
| DebugString(error_desc_def->sqlstate), |
| DebugString(error_desc_def->errorText))); |
| |
| sqlMessage = jenv->NewStringUTF(error_desc_def->errorText); |
| sqlState = jenv->NewStringUTF(error_desc_def->sqlstate); |
| sqlException = (jthrowable)jenv->NewObject(gJNICache.sqlExceptionClass, |
| gJNICache.sqlExceptionConstructorId, sqlMessage,sqlState, |
| error_desc_def->sqlcode); |
| if(curErrorNo == 0) |
| sqlExceptionHead = sqlException; |
| else |
| jenv->CallVoidMethod(sqlExceptionHead, gJNICache.setNextExceptionMethodId, |
| sqlException); |
| } |
| JNI_Throw(jenv,sqlExceptionHead); |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| void throwSQLException(JNIEnv *jenv, short errorNumber, const char *errorMessage, |
| const char *errorSqlState, int nativeCode) |
| { |
| FUNCTION_ENTRY_LEVEL(DEBUG_LEVEL_ERROR,"throwSQLException",("jenv=0x%08x, errorNumber=%d, errorMessage=%s, errorSqlState=%s, nativeCode=%d", |
| jenv, |
| errorNumber, |
| DebugString(errorMessage), |
| DebugString(errorSqlState), |
| nativeCode)); |
| jthrowable sqlException; |
| jstring sqlMessage; |
| jstring sqlState; |
| jint sqlcode; |
| char lcErrorMessage[2048]; |
| |
| // Clear any pending exceptions |
| // Otherwise, unexpected behaviour |
| JNI_ExceptionClear(jenv); |
| if (errorNumber>=0) |
| { |
| strcpy(lcErrorMessage, gJNILayerErrorMsgs[errorNumber]); |
| DEBUG_OUT(DEBUG_LEVEL_ERROR,("gJNILayerErrorMsgs[%d]=%s", |
| errorNumber, |
| gJNILayerErrorMsgs[errorNumber])); |
| } else lcErrorMessage[0] = 0; |
| if (errorMessage != NULL) |
| strcat(lcErrorMessage, errorMessage); |
| sqlMessage = jenv->NewStringUTF(lcErrorMessage); |
| sqlState = jenv->NewStringUTF(errorSqlState); |
| if (nativeCode == 0) |
| sqlcode = -(29250+errorNumber); |
| else |
| sqlcode = nativeCode; |
| sqlException = (jthrowable)jenv->NewObject(gJNICache.sqlExceptionClass, |
| gJNICache.sqlExceptionConstructorId, sqlMessage, sqlState, |
| sqlcode); |
| JNI_Throw(jenv,sqlException); |
| FUNCTION_RETURN_VOID(("lcErrorMessage=%s",lcErrorMessage)); |
| } |
| |
| void throwSQLException(JNIEnv *jenv, const ERROR_DESC_LIST_def *SQLError) |
| { |
| FUNCTION_ENTRY_LEVEL(DEBUG_LEVEL_ERROR,"throwSQLException",("jenv=0x%08x, SQLError[]=0x%08x", |
| jenv, |
| SQLError)); |
| jthrowable sqlException; |
| jthrowable sqlExceptionHead; |
| jstring sqlMessage; |
| jstring sqlState; |
| unsigned long curErrorNo; |
| ERROR_DESC_def *error_desc_def; |
| |
| // Clear any pending exceptions |
| // Otherwise, unexpected behaviour |
| JNI_ExceptionClear(jenv); |
| |
| if (SQLError->_length == 0) |
| { |
| throwSQLException(jenv, NO_ERROR_MESSAGE_ERROR, NULL, "HY000"); |
| FUNCTION_RETURN_VOID(("NO_ERROR_MESSAGE_ERROR")); |
| } |
| for (curErrorNo = 0, error_desc_def = SQLError->_buffer; |
| curErrorNo < SQLError->_length ; curErrorNo++, error_desc_def++) |
| { |
| DEBUG_OUT(DEBUG_LEVEL_ERROR,("sqlstate=%s, errorText=%s", |
| DebugString(error_desc_def->sqlstate), |
| DebugString(error_desc_def->errorText))); |
| sqlMessage = jenv->NewStringUTF(error_desc_def->errorText); |
| sqlState = jenv->NewStringUTF(error_desc_def->sqlstate); |
| sqlException = (jthrowable)jenv->NewObject(gJNICache.sqlExceptionClass, |
| gJNICache.sqlExceptionConstructorId, sqlMessage,sqlState, |
| error_desc_def->sqlcode); |
| if(curErrorNo == 0) |
| sqlExceptionHead = sqlException; |
| else |
| jenv->CallVoidMethod(sqlExceptionHead, gJNICache.setNextExceptionMethodId, |
| sqlException); |
| } |
| JNI_Throw(jenv,sqlExceptionHead); |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| void setSQLWarning(JNIEnv *jenv, jobject jobj, ERROR_DESC_LIST_def *sqlWarning) |
| { |
| FUNCTION_ENTRY("setSQLWarning",("jenv=0x%08x, jobj=0x%08x", |
| jenv, |
| jobj)); |
| |
| unsigned long curErrorNo; |
| ERROR_DESC_def *error_desc_def; |
| jobject sqlWarningLeaf; |
| jobject sqlWarningHead; |
| jstring sqlMessage; |
| jstring sqlState; |
| |
| if (sqlWarning->_length == 0) |
| { |
| setSQLWarning(jenv, jobj, NO_ERROR_MESSAGE_ERROR, NULL, "01000"); |
| FUNCTION_RETURN_VOID(("NO_ERROR_MESSAGE_ERROR")); |
| } |
| |
| for (curErrorNo = 0, error_desc_def = sqlWarning->_buffer; |
| curErrorNo < sqlWarning->_length ; curErrorNo++, error_desc_def++) |
| { |
| sqlMessage = jenv->NewStringUTF(error_desc_def->errorText); |
| sqlState = jenv->NewStringUTF(error_desc_def->sqlstate); |
| sqlWarningLeaf = jenv->NewObject(gJNICache.sqlWarningClass, |
| gJNICache.sqlWarningConstructorId, sqlMessage, sqlState, |
| error_desc_def->sqlcode); |
| if(curErrorNo == 0) |
| sqlWarningHead = sqlWarningLeaf; |
| else |
| jenv->CallVoidMethod(sqlWarningHead, gJNICache.setNextWarningMethodId, |
| sqlWarningLeaf); |
| } |
| jenv->CallVoidMethod(jobj, gJNICache.sqlWarningMethodId, sqlWarningHead); |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| void setSQLWarning(JNIEnv *jenv, jobject jobj, short errorNumber, const char *errorMessage, |
| const char *errorSqlState, int nativeCode) |
| { |
| FUNCTION_ENTRY("setSQLWarning",("jenv=0x%08x, jobj=0x%08x, errorNumber=%d, errorMessage=%s, errorSqlState=%s, nativeCode=%d", |
| jenv, |
| jobj, |
| errorNumber, |
| DebugString(errorMessage), |
| DebugString(errorSqlState), |
| nativeCode)); |
| jstring sqlMessage; |
| jstring sqlState; |
| char lcErrorMessage[2048]; |
| jobject sqlWarning; |
| jint sqlcode; |
| |
| strcpy(lcErrorMessage, gJNILayerErrorMsgs[errorNumber]); |
| if (errorMessage != NULL) |
| strcat(lcErrorMessage, errorMessage); |
| sqlMessage = jenv->NewStringUTF(lcErrorMessage); |
| sqlState = jenv->NewStringUTF(errorSqlState); |
| if (nativeCode == 0) |
| sqlcode = 29250+errorNumber; |
| else |
| sqlcode = nativeCode; |
| sqlWarning = jenv->NewObject(gJNICache.sqlWarningClass, |
| gJNICache.sqlWarningConstructorId, sqlMessage, sqlState, |
| sqlcode); |
| jenv->CallVoidMethod(jobj, gJNICache.sqlWarningMethodId, sqlWarning); |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| jobjectArray NewDescArray(JNIEnv *jenv, jobject jobj, SQLItemDescList_def *desc, jint offset) |
| { |
| FUNCTION_ENTRY("NewDescArray",("jenv=0x%08x, jobj=0x%08x, desc=0x%08x, offset=%ld", |
| jenv, |
| jobj, |
| desc, |
| offset)); |
| unsigned long index; |
| SQLItemDesc_def *SQLDesc; |
| jstring colName; |
| jstring colLabel; |
| jstring catalogName; |
| jstring schemaName; |
| jstring tableName; |
| jobjectArray SQLMXDescArray = NULL; |
| jobject SQLMXDesc = NULL; |
| |
| if ((desc->_length-offset )<= 0) |
| FUNCTION_RETURN_PTR(NULL,("(desc->_length(%ld) - offset(%ld))<= 0", |
| desc->_length, offset)); |
| |
| SQLMXDescArray = JNI_NewObjectArray(jenv,desc->_length-offset, gJNICache.SQLMXDescClass, NULL); |
| |
| for (index = offset; index < desc->_length ; index++) |
| { |
| SQLDesc = (SQLItemDesc_def *)desc->_buffer + index; |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("Adding descriptor. Column Name='%s' Column Heading='%s'", |
| DebugString(SQLDesc->colNm), DebugString(SQLDesc->colLabel))); |
| colName = jenv->NewStringUTF(SQLDesc->colNm); |
| catalogName = jenv->NewStringUTF(SQLDesc->catalogNm); |
| schemaName = jenv->NewStringUTF(SQLDesc->schemaNm); |
| tableName = jenv->NewStringUTF(SQLDesc->tableNm); |
| colLabel = jenv->NewStringUTF(SQLDesc->colLabel); |
| SQLMXDesc = jenv->NewObject(gJNICache.SQLMXDescClass, gJNICache.SQLMXDescConstructorId, |
| SQLDesc->dataType, SQLDesc->datetimeCode, SQLDesc->maxLen, |
| SQLDesc->precision, SQLDesc->scale, SQLDesc->nullInfo, colName, SQLDesc->signType, |
| SQLDesc->ODBCDataType, SQLDesc->ODBCPrecision, SQLDesc->SQLCharset, |
| SQLDesc->ODBCCharset, catalogName, schemaName, tableName, SQLDesc->fsDataType, |
| SQLDesc->intLeadPrec, |
| SQLDesc->paramMode, |
| colLabel); |
| JNI_SetObjectArrayElement(jenv,SQLMXDescArray, index-offset, SQLMXDesc); |
| } |
| FUNCTION_RETURN_PTR(SQLMXDescArray,("desc->_length = %ld",desc->_length)); |
| } |
| |
| void setPrepareOutputs(JNIEnv *jenv, jobject jobj, SQLItemDescList_def *inputDesc, |
| SQLItemDescList_def *outputDesc, jint txid, jlong stmtId, |
| jint inputParamOffset) |
| { |
| FUNCTION_ENTRY("setPrepareOutputs",("inputDesc=0x%08x, outputDesc=0x%08x, txid=0x%08x, stmtId=0x%08x, inputParamOffset=%ld", |
| inputDesc, |
| outputDesc, |
| txid, |
| stmtId, |
| inputParamOffset)); |
| |
| jobjectArray SQLMXOutputDescArray = NULL; |
| jobjectArray SQLMXInputDescArray = NULL; |
| SQLMXOutputDescArray = NewDescArray(jenv, jobj, outputDesc, 0); |
| SQLMXInputDescArray = NewDescArray(jenv, jobj, inputDesc, inputParamOffset); |
| jenv->CallVoidMethod(jobj, gJNICache.prepareOutputsMethodId, SQLMXInputDescArray, |
| SQLMXOutputDescArray, txid, inputDesc->_length-inputParamOffset, 0, stmtId); |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| void setExecuteDirectOutputs(JNIEnv *jenv, jobject jobj, SQLItemDescList_def *outputDesc, |
| long rowsAffected, jint txid, jlong stmtId) |
| { |
| FUNCTION_ENTRY_LEVEL(DEBUG_LEVEL_STMT,"setExecuteDirectOutputs",("jenv=0x%08x, jobj==0x%08x, outputDesc=0x%08x, rowsAffected=%ld, txid=0x%08x, stmtId=0x%08x", |
| jenv, |
| jobj, |
| outputDesc, |
| rowsAffected, |
| txid, |
| stmtId)); |
| jobjectArray SQLMXOuputDescArray = NULL; |
| |
| SQLMXOuputDescArray = NewDescArray(jenv, jobj, outputDesc, 0); |
| jobject fetchedRows = NULL; |
| jint fetchedRowCount = 0; |
| |
| jint stmtType = INVALID_SQL_QUERY_STMT_TYPE; // Initialize to invalid type |
| |
| SRVR_STMT_HDL *pSrvrStmt = (SRVR_STMT_HDL *) stmtId; |
| |
| if (pSrvrStmt != NULL) |
| { |
| { |
| stmtType = pSrvrStmt->getSqlQueryStatementType(); |
| DEBUG_OUT(DEBUG_LEVEL_CLI|DEBUG_LEVEL_STMT,("SQL Query Statement Type=%s", |
| CliDebugSqlQueryStatementType(stmtType))); |
| |
| if(stmtType == SQL_SELECT_UNIQUE) |
| { |
| // For unique selects, the endOfData flag indicates if |
| // the select returned a row or not |
| if(pSrvrStmt->endOfData) fetchedRowCount = 0; |
| else fetchedRowCount = 1; |
| |
| // Go get the Row[] object to return to the Java layer |
| fetchedRows = setFetchOutputs(jenv, pSrvrStmt->resultSetObject, pSrvrStmt, |
| &pSrvrStmt->outputValueList, fetchedRowCount, |
| TRUE, FALSE, txid); |
| } |
| } |
| } |
| // Return the execute results and any result set |
| // information that may have been generated |
| jenv->CallVoidMethod(jobj, gJNICache.execDirectOutputsMethodId, SQLMXOuputDescArray, rowsAffected, |
| fetchedRows, fetchedRowCount, txid, stmtId, stmtType); |
| |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| void setExecuteRSOutputs(JNIEnv *jenv, jobject jobj, SQLItemDescList_def *outputDesc, |
| jint txid, jlong rsStmtId, jint rsIndex) |
| { |
| FUNCTION_ENTRY_LEVEL(DEBUG_LEVEL_STMT,"setExecuteRSOutputs", |
| ("jenv=0x%08x, jobj=0x%08x, outputDesc=0x%08x, txid=0x%08x, rsStmtId=0x%08x, rsIndex=%ld", |
| jenv, |
| jobj, |
| outputDesc, |
| txid, |
| rsStmtId, |
| rsIndex)); |
| |
| jobjectArray SQLMXOuputDescArray = NULL; |
| |
| SQLMXOuputDescArray = NewDescArray(jenv, jobj, outputDesc, 0); |
| |
| jint stmtType = INVALID_SQL_QUERY_STMT_TYPE; // Initialize to invalid type |
| |
| SRVR_STMT_HDL *pSrvrStmt = (SRVR_STMT_HDL *) rsStmtId; |
| |
| stmtType = pSrvrStmt->getSqlQueryStatementType(); |
| DEBUG_OUT(DEBUG_LEVEL_CLI,("SQL Query Statement Type=%s", |
| CliDebugSqlQueryStatementType(stmtType))); |
| |
| // Return the execute open spjrs results and any result set |
| // information that may have been generated |
| jenv->CallVoidMethod(jobj, gJNICache.execRSOutputsMethodId, SQLMXOuputDescArray, |
| txid, rsStmtId, rsIndex); |
| |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| |
| void setExecuteOutputs(JNIEnv *jenv, jobject jobj, SRVR_STMT_HDL *pSrvrStmt, |
| ROWS_COUNT_LIST_def *rowCount, jint totalRowCount, jint txid) |
| { |
| FUNCTION_ENTRY("setExecuteOutputs",("... pSrvrStmt=0x%08x, rowCount=0x%08x, totalRowCount=%ld, txid=0x%08x", |
| pSrvrStmt, |
| rowCount, |
| totalRowCount, |
| txid)); |
| |
| jintArray rowCountArray = NULL; |
| jint i; |
| jint fetchedRowCount = 0; |
| jobject fetchedRows=NULL; |
| |
| if (rowCount) |
| { |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("rowCount->_length = %ld", rowCount->_length)); |
| rowCountArray = JNI_NewIntArray(jenv,rowCount->_length); |
| if (rowCount->_length) |
| JNI_SetIntArrayRegion(jenv,rowCountArray, 0, rowCount->_length, (jint *)rowCount->_buffer); |
| } |
| { |
| if(pSrvrStmt->getSqlQueryStatementType() == SQL_SELECT_UNIQUE) |
| { |
| if(pSrvrStmt->endOfData) fetchedRowCount = 0; |
| else fetchedRowCount = 1; |
| fetchedRows = setFetchOutputs(jenv, pSrvrStmt->resultSetObject, pSrvrStmt, |
| &pSrvrStmt->outputValueList, fetchedRowCount, |
| TRUE, FALSE, txid); |
| } |
| } |
| jenv->CallVoidMethod(jobj, gJNICache.executeOutputsMethodId, rowCountArray, totalRowCount, |
| fetchedRows, fetchedRowCount, txid); |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| jobject setFetchOutputs(JNIEnv *jenv, jobject jobj, SRVR_STMT_HDL *pSrvrStmt, |
| SQLValueList_def *outputValueList, |
| long rowsAffected, BOOL endOfData, |
| BOOL doCallBack, jint txid) |
| { |
| FUNCTION_ENTRY_LEVEL(DEBUG_LEVEL_STMT,"setFetchOutputs",("pSrvrStmt=0x%08x, outputValueList=0x%08x, rowsAffected=%ld, endOfData=%d, doCallBack=%d, txid=0x%08x", |
| pSrvrStmt, |
| outputValueList, |
| rowsAffected, |
| endOfData, |
| doCallBack, |
| txid)); |
| |
| jobjectArray rowArray; |
| |
| long columnCount; |
| long rowIndex; |
| long columnIndex; |
| SQLValue_def *SQLValue; |
| |
| rowArray = JNI_NewObjectArray(jenv,rowsAffected, gJNICache.wrapperClass, NULL); |
| if (rowsAffected != 0) columnCount = outputValueList->_length / rowsAffected; |
| else columnCount = 0; |
| |
| DEBUG_OUT(DEBUG_LEVEL_STMT,("columnCount=%ld, rowsAffected=%ld",columnCount,rowsAffected)); |
| |
| for (rowIndex = 0; rowIndex < rowsAffected ; rowIndex++) |
| { |
| struct WrapperInfoStruct wrapperInfo; |
| |
| if (!createWrapper(&wrapperInfo,jenv,columnCount,true)) |
| { |
| throwSQLException(jenv, JVM_MEM_ALLOC_ERROR, NULL, "HY000"); |
| cleanupWrapperInfo(&wrapperInfo); |
| FUNCTION_RETURN_PTR(NULL,("setFetchOutputs - JVM_MEM_ALLOC_ERROR")); |
| } |
| |
| for (columnIndex = 0 ; columnIndex < columnCount ; columnIndex++) |
| { |
| SQLValue = (SQLValue_def *)outputValueList->_buffer + |
| (rowIndex * columnCount) + columnIndex; |
| |
| if (SQLValue->dataInd != -1) |
| { |
| if (!setWrapper(&wrapperInfo, jobj, pSrvrStmt, columnIndex, SQLValue)) |
| { |
| cleanupWrapperInfo(&wrapperInfo); |
| FUNCTION_RETURN_PTR(NULL,("setWrapper returned error")); |
| } |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("Column index %ld wrapper is 0x%08x", |
| columnIndex, wrapperInfo.wrapper)); |
| } |
| } |
| updateWrapperElements(&wrapperInfo); |
| |
| JNI_SetObjectArrayElement(jenv,rowArray, rowIndex, wrapperInfo.wrapper); |
| |
| cleanupWrapperInfo(&wrapperInfo); |
| } |
| |
| // If requested, do the callback to Java. |
| // If not, they just wanted the Row[] created. |
| if(doCallBack) |
| { |
| jenv->CallVoidMethod(jobj, gJNICache.fetchOutputsMethodId, rowArray, |
| rowsAffected, endOfData, txid); |
| } |
| FUNCTION_RETURN_PTR(rowArray, (NULL)); |
| } |
| |
| |
| jobject setGetSQLCatalogOutputs(JNIEnv *jenv, jobject jobj, SRVR_STMT_HDL *pSrvrStmt, |
| SQLItemDescList_def *outputDesc, |
| char *catStmtLabel, jint txid, |
| long rowsAffected, BOOL endOfData, SQLValueList_def *outputValueList, |
| jlong stmtId) |
| |
| { |
| FUNCTION_ENTRY("setGetSQLCatalogOutputs",("jenv=0x%08x, jobj=0x%08x, pSrvrStmt=0x%08x, outputDesc=0x%08x, catStmtLabel=%s, txid=0x%08x, rowsAffected=%ld, endOfData=%d, outputValueList=0x%08x, stmtId=0x%08x", |
| jenv, |
| jobj, |
| pSrvrStmt, |
| outputDesc, |
| DebugString(catStmtLabel), |
| txid, |
| rowsAffected, |
| endOfData, |
| outputValueList, |
| stmtId)); |
| jobjectArray SQLMXOutputDescArray = NULL; |
| jstring stmtLabel; |
| jobject SQLMXResultSet = NULL; |
| SQLValueList_def CopyOutputValueList; |
| SQLValue_def *SQLValue1; |
| SQLValue_def *SQLValue2; |
| unsigned long ValueBufferLen; |
| BYTE *ValueBuffer; |
| BYTE *CopyValueBuffer; |
| unsigned long index; |
| |
| SQLMXOutputDescArray = NewDescArray(jenv, jobj, outputDesc, 0); |
| stmtLabel = jenv->NewStringUTF(catStmtLabel); |
| SQLMXResultSet = jenv->NewObject(gJNICache.SQLMXResultSetClass, gJNICache.SQLMXResultSetConstructorId, |
| jobj, SQLMXOutputDescArray, txid, stmtId); |
| setFetchOutputs(jenv, SQLMXResultSet, pSrvrStmt, outputValueList, rowsAffected, endOfData, TRUE, txid); |
| |
| FUNCTION_RETURN_PTR(SQLMXResultSet,("SQLMXResultSet=0x%08x",SQLMXResultSet)); |
| } |
| |
| |
| void setExecuteCallOutputs(JNIEnv *jenv, jobject jobj, |
| SRVR_STMT_HDL *pSrvrStmt, |
| short returnResultSet, jint txid) |
| { |
| FUNCTION_ENTRY("setExecuteCallOutputs",("... pSrvrStmt=0x%08x, returnResultSet=%d, txid=0x%08x", |
| pSrvrStmt, |
| returnResultSet, |
| txid)); |
| unsigned long i; |
| SQLValue_def sqlValue; |
| SRVR_DESC_HDL *IRD; |
| BYTE *dataPtr; |
| short *indPtr; |
| struct WrapperInfoStruct wrapperInfo; |
| |
| IRD = pSrvrStmt->IRD; |
| |
| DEBUG_OUT(DEBUG_LEVEL_STMT,("pSrvrStmt->IRD=0x%08x, pSrvrStmt->columnCount=%ld", |
| pSrvrStmt->IRD, pSrvrStmt->columnCount)); |
| |
| |
| if(!createWrapper(&wrapperInfo,jenv,pSrvrStmt->columnCount,true)) |
| { |
| throwSQLException(jenv, JVM_MEM_ALLOC_ERROR, NULL, "HY000"); |
| cleanupWrapperInfo(&wrapperInfo); |
| FUNCTION_RETURN_VOID(("setExecuteCallOutputs - JVM_MEM_ALLOC_ERROR")); |
| } |
| |
| if (pSrvrStmt->columnCount > 0) |
| { |
| for (i = 0 ; i < pSrvrStmt->columnCount ; i++) |
| { |
| if (IRD[i].paramMode == PARAMETER_MODE_INOUT || |
| IRD[i].paramMode == PARAMETER_MODE_OUT) |
| { |
| indPtr = (short *)IRD[i].indPtr; |
| dataPtr = IRD[i].varPtr; |
| sqlValue.dataType = IRD[i].dataType; |
| if (indPtr != NULL) |
| sqlValue.dataInd = *indPtr; |
| else |
| sqlValue.dataInd = 0; |
| sqlValue.dataValue._buffer = dataPtr; |
| getMemoryAllocInfo(sqlValue.dataType, sqlValue.dataCharset, IRD[i].length, IRD[i].vc_ind_length, 0, |
| NULL, (int *)&sqlValue.dataValue._length, NULL); |
| if (sqlValue.dataInd != -1) |
| { |
| if (!setWrapper(&wrapperInfo, jobj, pSrvrStmt, i, &sqlValue, TRUE)) |
| { |
| cleanupWrapperInfo(&wrapperInfo); |
| FUNCTION_RETURN_VOID(("setWrapper returned error")); |
| } |
| } |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("IRD[%ld] - sqlValue: dataType=%ld, dataInd=0x%08x, dataValue._buffer=0x%08x, dataValue._length=%ld wrapper=0x%08x", |
| i, |
| sqlValue.dataType, |
| sqlValue.dataInd, |
| sqlValue.dataValue._buffer, |
| sqlValue.dataValue._length, |
| wrapperInfo.wrapper)); |
| } |
| else |
| { |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("IRD[%ld].paramMode(%ld) is not PARAMETER_MODE_INOUT or PARAMETER_MODE_OUT", |
| i, |
| IRD[i].paramMode)); |
| } |
| } |
| } |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("Calling Java SQLMXCallableStatement.setExecuteCallOutputs() method")); |
| updateWrapperElements(&wrapperInfo); |
| jenv->CallVoidMethod(jobj, gJNICache.executeCallOutputsMethodId, wrapperInfo.wrapper, returnResultSet, txid, |
| pSrvrStmt->RSMax, pSrvrStmt->RSIndex, pSrvrStmt->isSPJRS); |
| cleanupWrapperInfo(&wrapperInfo); |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| char *convertInt64toAscii(Int64 n, short scale, char *buff) |
| { |
| FUNCTION_ENTRY("convertInt64toAscii",("n=%ld, scale=%d, buff=0x%08x", |
| n, |
| scale, |
| buff)); |
| char t[100], *c=t, *f=buff; |
| int d; |
| int s = 0; |
| BOOL fixRightMost = FALSE; |
| |
| if (n < 0) |
| { |
| if (n == LLONG_MIN) |
| { |
| n = n+1; |
| fixRightMost = TRUE; |
| } |
| *(f++) = '-'; |
| n = -n; |
| } |
| |
| if (scale > 0) |
| { |
| while (s < scale) |
| { |
| d = (int)(n % 10); |
| *(c++) = d + '0'; |
| n = n / 10; |
| s++; |
| } |
| *(c++) = '.'; |
| } |
| |
| do |
| { |
| d = (int)(n % 10); |
| *(c++) = d + '0'; |
| n = n / 10; |
| } while (n > 0) ; |
| |
| c--; |
| |
| |
| while (c >= t) *(f++) = *(c--); |
| if (fixRightMost) |
| { |
| *(--f) = '8'; |
| f++; |
| } |
| *f = '\0'; |
| FUNCTION_RETURN_PTR(buff,("buff=%s",DebugString(buff))); |
| } |
| |
| |
| short ConvertDecimalToChar(jint sqlDataType, void *srcDataPtr, jint srcLength, |
| jshort srcScale, char *cTmpBuf) |
| { |
| FUNCTION_ENTRY("ConvertDecimalToChar",("sqlDataType=%s, srcDataPtr=0x%08x, srcLength=%ld, srcScale=%d, cTmpBuf=0x%08x", |
| CliDebugSqlTypeCode(sqlDataType), |
| srcDataPtr, |
| srcLength, |
| srcScale, |
| cTmpBuf)); |
| |
| char *destTempPtr; |
| short i; |
| BOOL leadZero; |
| BOOL valByteCopied; |
| BYTE valByte; // Sign Bit + first digit |
| |
| |
| destTempPtr = cTmpBuf; |
| |
| switch(sqlDataType) |
| { |
| case 151: |
| leadZero = TRUE; |
| valByteCopied = TRUE; |
| *destTempPtr == ((char*)srcDataPtr)[0]; |
| i = 1; |
| break; |
| case SQLTYPECODE_DECIMAL_UNSIGNED: |
| leadZero = TRUE; |
| valByteCopied = TRUE; |
| i = 0; |
| break; |
| case SQLTYPECODE_DECIMAL: |
| valByte = (BYTE)(*(BYTE *)srcDataPtr & (BYTE)0x80); |
| if (valByte) |
| *destTempPtr++ = '-'; |
| valByte = (BYTE)(*(BYTE *)srcDataPtr & (BYTE) 0x7F); |
| if (valByte != '0') |
| { |
| valByteCopied = FALSE; |
| leadZero = FALSE; |
| } |
| else |
| { |
| leadZero = TRUE; |
| valByteCopied = TRUE; |
| } |
| i = 1; |
| break; |
| default: |
| FUNCTION_RETURN_NUMERIC(1,("Data Type Default")); |
| } |
| for ( ; i < (srcLength-srcScale) ; i++) |
| { |
| if (!(leadZero && ((char *)srcDataPtr)[i] == '0')) |
| { |
| if (! valByteCopied) |
| { |
| *destTempPtr++ = valByte; |
| valByteCopied = TRUE; |
| } |
| *destTempPtr++ = ((char *)srcDataPtr)[i]; |
| leadZero = FALSE; |
| } |
| } |
| if (leadZero) |
| *destTempPtr++ = '0'; |
| if (srcScale > 0) |
| { |
| if (valByteCopied) |
| *destTempPtr++ = '.'; |
| for (i = (short)(srcLength-srcScale) ; i < srcLength ; i++) |
| { |
| if (! valByteCopied) |
| { |
| valByteCopied = TRUE; |
| if (srcLength == srcScale) |
| { |
| *destTempPtr++ = '.'; |
| *destTempPtr++ = valByte; |
| if (++i >= srcLength) |
| break; |
| } |
| else |
| { |
| *destTempPtr++ = valByte; |
| *destTempPtr++ = '.'; |
| } |
| } |
| *destTempPtr++ = ((char *)srcDataPtr)[i]; |
| } |
| } |
| else |
| if (! valByteCopied) |
| { |
| *destTempPtr++ = valByte; |
| valByteCopied = TRUE; |
| } |
| *destTempPtr = '\0'; |
| FUNCTION_RETURN_NUMERIC(0,(NULL)); |
| } |
| |
| short ConvertSoftDecimalToDouble(jint sqlDataType, void *srcDataPtr, jint srcLength, |
| jint srcScale, char *cTmpBuf) |
| { |
| // SQLTYPECODE_DECIMAL_LARGE and SQLTYPECODE_DECIMAL_LARGE_UNSIGNED are actually not |
| // supported by SQL, so the datatypes processing is not really required. Since they |
| // are not supported, I have no way of verifying this routines functionality. I have corrected |
| // an unititalized variable in this routine, but in looking at the code I think there is |
| // an error in the logic. If someone does support these types later, you should look at the |
| // handling of the signed values. For standard signed numeric types, the first byte is a |
| // valid digit in the value with the high bit being the sign. In this routines handling, the |
| // first byte is skipped in the processing for signed values. I think this is incorrect. |
| // R Harlow 1/27/2004 |
| FUNCTION_ENTRY_LEVEL(DEBUG_LEVEL_DATA,"ConvertSoftDecimalToDouble",("sqlDataType=%s, srcDataPtr/srcLength=Below, srcScale=%ld, cTmpBuf=0x%08x)", |
| CliDebugSqlTypeCode(sqlDataType), |
| srcScale, |
| cTmpBuf)); |
| MEMORY_DUMP(DEBUG_LEVEL_DATA,srcDataPtr,srcLength); |
| char *destTempPtr; |
| short i=0; |
| BOOL leadZero = TRUE; |
| |
| destTempPtr = cTmpBuf; |
| |
| switch(sqlDataType) |
| { |
| case SQLTYPECODE_DECIMAL_LARGE: |
| i = 1; |
| break; |
| case SQLTYPECODE_DECIMAL_LARGE_UNSIGNED: |
| break; |
| default: |
| FUNCTION_RETURN_NUMERIC(1,("Not SQLTYPECODE_DECIMAL_LARGE or SQLTYPECODE_DECIMAL_LARGE_UNSIGNED")); |
| } |
| for (; i < (srcLength-srcScale) ; i++) |
| { |
| if (!(leadZero && ((char *)srcDataPtr)[i] == 0)) |
| { |
| *destTempPtr++ = ((char *)srcDataPtr)[i]+'0'; |
| leadZero = FALSE; |
| } |
| } |
| if (srcScale > 0) |
| { |
| *destTempPtr++ = '.'; |
| for (i = (short)(srcLength-srcScale) ; i < srcLength ; i++) |
| *destTempPtr++ = ((char *)srcDataPtr)[i]+'0'; |
| } |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("Returning string %s",cTmpBuf)); |
| FUNCTION_RETURN_NUMERIC(0,(NULL)); |
| } |
| |
| char *rTrim(char *string) |
| { |
| FUNCTION_ENTRY("rTrim",("string=0x%08x", |
| string)); |
| char *strPtr; |
| |
| for (strPtr = string + strlen(string) - 1; |
| strPtr >= string && (*strPtr == ' ' || *strPtr == '\t') ; |
| *(strPtr--) = '\0'); |
| FUNCTION_RETURN_PTR(string,("string=%s",DebugString(string))); |
| } |
| |
| |
| jint fillInSQLValues(JNIEnv *jenv, jobject jobj, SRVR_STMT_HDL *pSrvrStmt, |
| jint paramRowNumber, jint paramRowCount, jint paramCount, |
| jobject paramValues, jstring iso88591Encoding) |
| { |
| jint dataType; |
| jint octetLength; |
| jint charSet; |
| jint dataLen; |
| BYTE *dataPtr; |
| BYTE *indPtr; |
| jint allocLength; |
| |
| FUNCTION_ENTRY("fillInSQLValues", |
| ("... pSrvrStmt=0x%08x, paramRowNumber=%ld, paramRowCount=%ld, paramCount=%ld, iso88591Encoding=%s ...", |
| pSrvrStmt, |
| paramRowNumber, |
| paramRowCount, |
| paramCount, |
| DebugJString(jenv,iso88591Encoding))); |
| |
| jint row; |
| jint paramOffset = pSrvrStmt->inputDescParamOffset; |
| |
| SRVR_DESC_HDL *IPD = pSrvrStmt->IPD; |
| if (paramCount && paramOffset) |
| { |
| // First desc is rowset size |
| DEBUG_ASSERT(IPD[0].dataType==SQLTYPECODE_INTEGER, |
| ("IPD[0].dataType(%s)!=SQLTYPECODE_INTEGER", |
| CliDebugSqlTypeCode(IPD[0].dataType))); |
| *((long *)IPD[0].varPtr) = pSrvrStmt->batchRowsetSize; |
| IPD[0].indPtr = NULL; |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_ROWSET,("First descriptor (varPtr=0x%08x) set to batch rowset size (%ld)", |
| IPD[0].varPtr, |
| pSrvrStmt->batchRowsetSize)); |
| } |
| |
| for (row=0; row<paramRowCount; row++) |
| { |
| jint paramNumber; |
| struct WrapperInfoStruct wrapperInfo; |
| createWrapper(&wrapperInfo,jenv,paramCount,false); |
| |
| // Get the data wrapper object |
| if (JNI_IsInstanceOf(wrapperInfo.jenv,paramValues,gJNICache.wrapperClass)) |
| { |
| wrapperInfo.wrapper = paramValues; |
| } |
| else |
| { |
| // If more than one, it is an array of data wrappers |
| wrapperInfo.wrapper = (jobject) JNI_GetObjectArrayElement(jenv,(jobjectArray)paramValues, paramRowNumber+row); |
| } |
| |
| for (paramNumber = 0; paramNumber < paramCount; paramNumber++) |
| { |
| jint paramMode = IPD[paramNumber+paramOffset].paramMode; |
| jboolean isNull = getWrapperIsNull(&wrapperInfo,paramNumber); |
| |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,("Param %ld ParamMode=%ld DataType=%s IPD[%ld]", |
| paramNumber, |
| paramMode, |
| CliDebugSqlTypeCode(IPD[paramNumber+paramOffset].dataType), |
| paramNumber+paramOffset)); |
| |
| if (paramMode == PARAMETER_MODE_OUT) |
| continue; |
| if (IPD[paramNumber+paramOffset].indPtr) |
| { |
| indPtr = IPD[paramNumber+paramOffset].indPtr + row * sizeof(short); |
| if (!isNull) |
| *((short *)indPtr) = 0; |
| else |
| *((short *)indPtr) = -1; |
| DEBUG_OUT(DEBUG_LEVEL_DATA,(" indPtr=0x%08x *indPtr=%d", |
| indPtr, |
| *((short *)indPtr))); |
| } else { |
| indPtr = NULL; |
| DEBUG_OUT(DEBUG_LEVEL_DATA,(" indPtr=NULL")); |
| } |
| |
| if (isNull && (indPtr==NULL)) |
| { |
| // Value is null in a NOT NULL column |
| throwSQLException(jenv, CUSTOM_ERROR, |
| "*** ERROR[8421] NULL cannot be assigned to a NOT NULL column.", |
| "23000", |
| -8421); |
| cleanupWrapperInfo(&wrapperInfo); |
| FUNCTION_RETURN_NUMERIC((row+1),("Value in row %ld is null in a NOT NULL column",row+1)); |
| } |
| |
| if (!isNull) |
| { |
| dataType = IPD[paramNumber+paramOffset].dataType; |
| octetLength = IPD[paramNumber+paramOffset].length; |
| charSet = IPD[paramNumber+paramOffset].charSet; |
| getMemoryAllocInfo(dataType, charSet, octetLength, IPD[paramNumber + paramOffset].vc_ind_length, 0, |
| NULL, &allocLength, NULL); |
| dataPtr = IPD[paramNumber+paramOffset].varPtr + row*allocLength; |
| |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,(" dataPtr=0x%08x", dataPtr)); |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,(" dataType=%s",CliDebugSqlTypeCode(dataType))); |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,(" octetLength=%ld", octetLength)); |
| |
| if (getWrapperDataType(&wrapperInfo,paramNumber)!=org_apache_trafodion_jdbc_t2_DataWrapper_BYTES) |
| { |
| // Non byte array value |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE, |
| ("Non byte array wrapper (%s). IPD[paramNumber(%ld)+paramOffset(%ld)]", |
| DebugJavaObjectInfo(jenv,wrapperInfo.wrapper), |
| paramNumber, |
| paramOffset)); |
| jint precision = IPD[paramNumber+paramOffset].precision; |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,("precision=%ld",precision)); |
| |
| jint scale = IPD[paramNumber+paramOffset].scale; |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,("scale=%ld",scale)); |
| |
| jint sqlDatetimeCode = IPD[paramNumber+paramOffset].sqlDatetimeCode; |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,("sqlDatetimeCode=%ld",sqlDatetimeCode)); |
| |
| jint FSDataType = IPD[paramNumber+paramOffset].FSDataType; |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,("FSDataType=%ld",FSDataType)); |
| |
| jint charSet = IPD[paramNumber+paramOffset].charSet; |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,("charSet=%ld",charSet)); |
| |
| jint vcIndLength = IPD[paramNumber+paramOffset].vc_ind_length; |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,("charSet=%ld",charSet)); |
| |
| // do the data Conversion |
| if (!convertJavaToSQL(jobj, paramNumber, &wrapperInfo, dataType, sqlDatetimeCode, |
| dataPtr, allocLength, precision, scale, FALSE, |
| FSDataType, charSet, iso88591Encoding, vcIndLength)) |
| { |
| cleanupWrapperInfo(&wrapperInfo); |
| FUNCTION_RETURN_NUMERIC(row+1,("convertJavaToSQL() failed in row %ld",row+1)); |
| } |
| } |
| else |
| { |
| // Process byte array |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("Byte array wrapper (%s) paramNumber=%ld", |
| DebugJavaObjectInfo(jenv,wrapperInfo.wrapper), |
| paramNumber)); |
| jbyte *byteValue = getWrapperBytes(&wrapperInfo,paramNumber); |
| |
| dataLen = JNI_GetArrayLength(wrapperInfo.jenv,wrapperInfo.bytesArrayObject); |
| DEBUG_OUT(DEBUG_LEVEL_JAVA|DEBUG_LEVEL_DATA,("Byte array length = %ld",dataLen)); |
| MEMORY_DUMP(DEBUG_LEVEL_JAVA|DEBUG_LEVEL_DATA,byteValue,dataLen); |
| |
| switch (dataType) |
| { |
| case SQLTYPECODE_CHAR: |
| // if (allocLength > dataLen) |
| if (dataLengthNotExceeded(charSet, dataLen, allocLength)) |
| { |
| memcpy(dataPtr, (const void *)byteValue, dataLen); |
| memset(dataPtr + (dataLen), ' ', allocLength - (dataLen)); |
| if (charSet == SQLCHARSETCODE_UCS2) |
| { |
| // Back fill target buffer with double byte 'space' characters (i.e. 0x00 0x20) |
| for (int i = (dataLen+1); i < allocLength-dataLen; i+=2) |
| { |
| *(dataPtr+i) = 0; |
| } |
| } |
| } |
| else |
| { |
| throwSQLException(jenv, STRING_DATA_TRUNCATED_ERROR, NULL, "22001"); |
| cleanupWrapperInfo(&wrapperInfo); |
| FUNCTION_RETURN_NUMERIC(row+1,("fillInSQLValues() failed in row %ld",row+1)); |
| } |
| break; |
| case SQLTYPECODE_VARCHAR: |
| if (allocLength > dataLen) |
| { |
| memcpy(dataPtr, (const void *)byteValue, dataLen); |
| *(dataPtr+dataLen) = '\0'; |
| } |
| else |
| { |
| throwSQLException(jenv, STRING_DATA_TRUNCATED_ERROR, NULL, "22001"); |
| cleanupWrapperInfo(&wrapperInfo); |
| FUNCTION_RETURN_NUMERIC(row+1,("fillInSQLValues() failed in row %ld",row+1)); |
| } |
| break; |
| case SQLTYPECODE_VARCHAR_WITH_LENGTH: |
| case SQLTYPECODE_VARCHAR_LONG: |
| case SQLTYPECODE_DATETIME: |
| case SQLTYPECODE_INTERVAL: |
| case SQLTYPECODE_CLOB: |
| case SQLTYPECODE_BLOB: |
| if ((IPD[paramNumber + paramOffset].vc_ind_length == 4) && (allocLength > dataLen + sizeof(int))) |
| { |
| *(unsigned int *)dataPtr = (int)dataLen; |
| memcpy(dataPtr + sizeof(int), (const void *)byteValue, dataLen); |
| } |
| else if (allocLength > dataLen + sizeof(short)) |
| { |
| *(unsigned short *)dataPtr = (short)dataLen; |
| memcpy(dataPtr+sizeof(short), (const void *)byteValue, dataLen); |
| } |
| else |
| { |
| throwSQLException(jenv, STRING_DATA_TRUNCATED_ERROR, NULL, "22001"); |
| cleanupWrapperInfo(&wrapperInfo); |
| FUNCTION_RETURN_NUMERIC(row+1,("fillInSQLValues() failed in row %ld",row+1)); |
| } |
| break; |
| default: |
| throwSQLException(jenv, PROGRAMMING_ERROR, gJNILayerErrorMsgs[PROGRAMMING_ERROR], |
| "HY000"); |
| cleanupWrapperInfo(&wrapperInfo); |
| FUNCTION_RETURN_NUMERIC(row+1,("fillInSQLValues() failed in row %ld",row+1)); |
| } |
| cleanupWrapperBytesArray(&wrapperInfo); |
| } |
| //---------------------------------------------------dataPtr-------- |
| |
| } else DEBUG_OUT(DEBUG_LEVEL_DATA,(" Parameter is NULL")); |
| } |
| cleanupWrapperInfo(&wrapperInfo); |
| } |
| FUNCTION_RETURN_NUMERIC(0,(NULL)); |
| } |
| |
| long jGetDigitCount(Int64 value) |
| { |
| FUNCTION_ENTRY("jGetDigitCount",("value=%ld", |
| value)); |
| static Int64 decValue[] = {0, |
| 9, |
| 99, |
| 999, |
| 9999, |
| 99999, |
| 999999, |
| 9999999, |
| 99999999, |
| 999999999, |
| 9999999999, |
| 99999999999, |
| 999999999999, |
| 9999999999999, |
| 99999999999999, |
| 999999999999999, |
| 9999999999999999, |
| 99999999999999999, |
| 999999999999999999}; |
| Int64 value1; |
| |
| if (value < 0) |
| value1 = -value; |
| else |
| value1 = value; |
| |
| for (int i = 4; i <= 16; i += 4) |
| { |
| if (value1 <= decValue[i]) |
| { |
| if (value1 <= decValue[i-3]) |
| FUNCTION_RETURN_NUMERIC((i-3),("i-3")); |
| if (value1 <= decValue[i-2]) |
| FUNCTION_RETURN_NUMERIC((i-2),("i-2")); |
| if (value1 <= decValue[i-1]) |
| FUNCTION_RETURN_NUMERIC((i-1),("i-1")); |
| FUNCTION_RETURN_NUMERIC(i,("i")); |
| } |
| } |
| if (value1 <= decValue[17]) |
| FUNCTION_RETURN_NUMERIC(17,("value1 <= decValue[17]")); |
| if (value1 <= decValue[18]) |
| FUNCTION_RETURN_NUMERIC(18,("value1 <= decValue[18]")); |
| FUNCTION_RETURN_NUMERIC(19,("value1 > decValue[18]")); |
| } |
| |
| BOOL convertJavaToSQL(jobject jobj, jint paramNumber, struct WrapperInfoStruct *wrapperInfo, jint sqlDataType, |
| jint sqlDatetimeCode, |
| BYTE *targetDataPtr, jint targetLength, jint precision, jint scale, |
| jboolean isSigned, jint FSDataType, jint charSet, jstring iso88591Encoding, jint vcIndLength) |
| { |
| FUNCTION_ENTRY("convertJavaToSQL", |
| ("... paramNumber=%ld, wrapper=0x%08x, sqlDataType=%s, charSet=%s, targetLength=%ld, precision=%ld, iso88591Encoding=%s ...", |
| paramNumber, |
| wrapperInfo->wrapper, |
| CliDebugSqlTypeCode(sqlDataType), |
| getCharsetEncoding(charSet), |
| targetLength, |
| precision, |
| DebugJString(wrapperInfo->jenv,iso88591Encoding))); |
| |
| long dataLen = 0; |
| Int64 integralPart; |
| Int64 decimalPart; |
| Int64 tempVal64; |
| long i; |
| BOOL negative; |
| double dTmp; // Used to store the converted floating point string to double |
| char *errorCharPtr; |
| long decimalDigits; |
| long integralDigits; |
| long scaleOffset; |
| Int64 tempScaleVal64; |
| short decLeadingZeros; |
| BOOL retcode = FALSE; |
| char *charptr = NULL; // Big Num Changes |
| jbyteArray stringByteArray; |
| jboolean isCopy = FALSE; |
| char tmpBuf[100]; |
| char fmtBuf[50]; |
| jstring encoding; |
| const char *nParamValue = NULL; |
| |
| if (getWrapperIsNull(wrapperInfo,paramNumber)) |
| { |
| throwSQLException(wrapperInfo->jenv, PARAMETER_NOT_SET_ERROR, NULL, "07002", 0); |
| FUNCTION_RETURN_NUMERIC(FALSE,("parameter is NULL")); |
| } |
| |
| // Linux port- moving here from case block because of compile errors |
| jbyteArray bigNumAsBytes; |
| jint bytesLength; |
| BYTE *pB; |
| |
| switch(sqlDataType) |
| { |
| case SQLTYPECODE_CHAR: |
| case SQLTYPECODE_VARCHAR: |
| case SQLTYPECODE_VARCHAR_LONG: |
| case SQLTYPECODE_VARCHAR_WITH_LENGTH: |
| case SQLTYPECODE_CLOB: |
| case SQLTYPECODE_BLOB: |
| if ( useDefaultCharsetEncoding(wrapperInfo->jenv, jobj, charSet, iso88591Encoding) ) |
| { |
| encoding = NULL; |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,("Using default encoding instead of '%s'", |
| getCharsetEncoding(charSet))); |
| } |
| else |
| { |
| encoding = getCharsetEncodingJava(wrapperInfo->jenv, charSet, iso88591Encoding); |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE, |
| ("encoding='%s' (from getCharsetEncodingJava)",DebugJString(wrapperInfo->jenv, encoding))); |
| } |
| |
| if (encoding) |
| stringByteArray = (jbyteArray)wrapperInfo->jenv->CallObjectMethod(getWrapperObject(wrapperInfo,paramNumber), |
| gJNICache.getBytesEncodedMethodId, encoding); |
| else |
| stringByteArray = (jbyteArray)wrapperInfo->jenv->CallObjectMethod(getWrapperObject(wrapperInfo,paramNumber), |
| gJNICache.getBytesMethodId); |
| if (stringByteArray==NULL) |
| { |
| throwSQLException(wrapperInfo->jenv, PARAMETER_NOT_SET_ERROR, NULL, "07002", 0); |
| FUNCTION_RETURN_NUMERIC(FALSE,("getBytesEncodedMethod failed")); |
| } |
| if ((nParamValue = (const char *)JNI_GetByteArrayElements(wrapperInfo->jenv,stringByteArray, &isCopy)) == NULL) |
| { |
| throwSQLException(wrapperInfo->jenv, PARAMETER_NOT_SET_ERROR, NULL, "07002", 0); |
| FUNCTION_RETURN_NUMERIC(FALSE,("GetByteArrayElements() failed")); |
| } |
| dataLen = JNI_GetArrayLength(wrapperInfo->jenv,stringByteArray); |
| |
| DEBUG_OUT(DEBUG_LEVEL_UNICODE,("Shift_JIS byte array dataLen ='%ld'", dataLen)); |
| MEMORY_DUMP(DEBUG_LEVEL_UNICODE,nParamValue,dataLen); |
| break; |
| |
| |
| case SQLTYPECODE_IEEE_REAL: |
| *(float *)targetDataPtr = getWrapperFloat(wrapperInfo,paramNumber); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_FLOAT: targetData = '%.8g'",*(float *)targetDataPtr)); |
| retcode = TRUE; |
| goto func_exit; |
| break; |
| case SQLTYPECODE_IEEE_FLOAT: |
| case SQLTYPECODE_IEEE_DOUBLE: |
| *(double *)targetDataPtr = getWrapperDouble(wrapperInfo,paramNumber); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_DOUBLE: targetData = '%.17g'",*(double *)targetDataPtr)); |
| retcode = TRUE; |
| goto func_exit; |
| break; |
| case SQLTYPECODE_INTEGER: |
| *(int *)targetDataPtr = getWrapperInt(wrapperInfo,paramNumber); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_INTEGER: targetData = '%d'",*(int *)targetDataPtr)); |
| retcode = TRUE; |
| goto func_exit; |
| break; |
| case SQLTYPECODE_INTEGER_UNSIGNED: |
| *(unsigned int *)targetDataPtr = getWrapperInt(wrapperInfo,paramNumber); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_INTEGER: targetData = '%d'",*(int *)targetDataPtr)); |
| retcode = TRUE; |
| goto func_exit; |
| break; |
| case SQLTYPECODE_LARGEINT: |
| *(long long *)targetDataPtr = getWrapperLong(wrapperInfo,paramNumber); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_LARGEINT: targetData = '%Ld'",*(long long *)targetDataPtr)); |
| retcode = TRUE; |
| goto func_exit; |
| break; |
| case SQLTYPECODE_SMALLINT: |
| *(short *)targetDataPtr = getWrapperShort(wrapperInfo,paramNumber); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_SMALLINT: targetData = '%hd'",*(short *)targetDataPtr)); |
| retcode = TRUE; |
| goto func_exit; |
| break; |
| case SQLTYPECODE_SMALLINT_UNSIGNED: |
| *(unsigned short *)targetDataPtr = getWrapperShort(wrapperInfo,paramNumber); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_SMALLINT: targetData = '%hd'",*(short *)targetDataPtr)); |
| retcode = TRUE; |
| goto func_exit; |
| break; |
| /* **************************************************************************************************************** |
| * NOTE: SQL/MX uses three different storage sizes to store the SQLTYPECODE_NUMERIC and SQLTYPECODE_NUMERIC_UNSIGNED |
| * column data types. Depending upon the precision used to create the column. The store size can be either a |
| * 16 bit, 32 bit or 64 bit number. Also remember that inorder to write the full range of number into a |
| * unsigned column type, the next larger setter method has to be used. For example, if I want to write data |
| * to a unsigned 16 bit column, I would have to use the setInteger method and not the setShort. Java does |
| * not have any unsigned data type and the max value for short is 32,767 were as the max value for an unsigned |
| * short would be 65,535. |
| * |
| * The Java code has be updated to allow using next larger setter method to write to an unsigned column type. |
| * ****************************************************************************************************************/ |
| case SQLTYPECODE_NUMERIC: |
| case SQLTYPECODE_NUMERIC_UNSIGNED: |
| switch (FSDataType) { //TYPE_FS descriptor fields |
| case _SQLDT_16BIT_S: |
| *(short *)targetDataPtr = (short) getWrapperLong(wrapperInfo,paramNumber); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_NUMERIC: _SQLDT_16BIT_S: targetData = '%hd', scale = '%ld'",*(short *)targetDataPtr, scale)); |
| retcode = TRUE; |
| goto func_exit; |
| break; |
| case _SQLDT_16BIT_U: |
| *(unsigned short *)targetDataPtr = (unsigned short) getWrapperLong(wrapperInfo,paramNumber); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_NUMERIC: _SQLDT_16BIT_U: targetData = '%hu', scale = '%ld'",*(unsigned short *)targetDataPtr, scale)); |
| retcode = TRUE; |
| goto func_exit; |
| break; |
| case _SQLDT_32BIT_S: |
| *(int *)targetDataPtr = (int) getWrapperLong(wrapperInfo,paramNumber); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_NUMERIC: _SQLDT_32BIT_S: targetData = '%d', scale = '%ld'",*(int *)targetDataPtr, scale)); |
| retcode = TRUE; |
| goto func_exit; |
| break; |
| case _SQLDT_32BIT_U: |
| *(unsigned int *)targetDataPtr = (unsigned int) getWrapperLong(wrapperInfo,paramNumber); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_NUMERIC: _SQLDT_32BIT_U: targetData = '%u', scale = '%ld'",*(unsigned int *)targetDataPtr, scale)); |
| retcode = TRUE; |
| goto func_exit; |
| break; |
| case _SQLDT_64BIT_S: |
| *(long long *)targetDataPtr = getWrapperLong(wrapperInfo,paramNumber); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_NUMERIC: _SQLDT_64BIT_S: targetData = '%Ld', scale = '%ld'",*(long long *)targetDataPtr, scale)); |
| retcode = TRUE; |
| goto func_exit; |
| break; |
| // Big Num Changes |
| case _SQLDT_NUM_BIG_U: |
| case _SQLDT_NUM_BIG_S: |
| bigNumAsBytes = convertBigDecimalToSQLBigNum(wrapperInfo,paramNumber,scale, targetLength); |
| bytesLength = wrapperInfo->jenv->GetArrayLength(bigNumAsBytes); |
| if (bytesLength <= 0) |
| { |
| throwSQLException(wrapperInfo->jenv, PARAMETER_NOT_SET_ERROR, NULL, "07002", 0); |
| FUNCTION_RETURN_NUMERIC(FALSE,("convertBigDecimalToSQLBigNum() failed")); |
| goto func_exit; |
| } |
| pB = new BYTE[bytesLength]; |
| wrapperInfo->jenv->GetByteArrayRegion(bigNumAsBytes, 0, bytesLength, (jbyte *)pB); |
| if(_SQLDT_NUM_BIG_S == FSDataType) |
| { |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("_SQLDT_NUM_BIG_S: precision(%ld)>targetLength(%ld)",precision,targetLength)); |
| } |
| else |
| { |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("_SQLDT_NUM_BIG_U: precision(%ld)>targetLength(%ld)",precision,targetLength)); |
| } |
| memcpy(targetDataPtr, pB, bytesLength); |
| delete [] pB; |
| pB = NULL; |
| if(_SQLDT_NUM_BIG_U == FSDataType) |
| { |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_NUMERIC: _SQLDT_NUM_BIG_U: targetData = '%Ld', scale = '%ld'",*(char *)targetDataPtr, scale)); |
| } |
| else if(_SQLDT_NUM_BIG_S == FSDataType) |
| { |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_NUMERIC: _SQLDT_NUM_BIG_S: targetData = '%Ld', scale = '%ld'",*(char *)targetDataPtr, scale)); |
| } |
| retcode = TRUE; |
| goto func_exit; |
| break; |
| // Big Num Changes |
| default: |
| break; |
| } |
| /* **************************************************************************************************************** |
| * NOTE: SQL/MX stores the SQLTYPECODE_DECIMAL and SQLTYPECODE_DECIMAL_UNSIGNED as numeric ASCII strings. The ASCII |
| * string must only contain numbers and it must be padded with ASCII zero (0x30). A negative number is denoted |
| * by orring a hex 0x80 with the first charater in the string. |
| * |
| * SQL/MX told us that we should never see SQLTYPECODE_DECIMAL_LARGE or SQLTYPECODE_DECIMAL_LARGE_UNSIGNED. |
| * These are software datatypes and are not externalized. |
| * |
| * The only TYPE_FS descriptor field that we will see is the _SQLDT_DEC_U which is used to denote that the |
| * column is unsigned. All of the other TYPE_FS descriptor fields for decimal, _SQLDT_DEC_LSS, _SQLDT_DEC_LSE |
| * _SQLDT_DEC_TSS, and _SQLDT_DEC_TSE, are for host variable declaration only. We should never see any of these |
| * in the JDBC driver. |
| * |
| * ****************************************************************************************************************/ |
| case SQLTYPECODE_DECIMAL: |
| case SQLTYPECODE_DECIMAL_UNSIGNED: |
| nParamValue = JNI_GetStringUTFChars(wrapperInfo->jenv,(jstring)getWrapperObject(wrapperInfo,paramNumber), NULL); |
| charptr = (char *) nParamValue; //Make a copy of the pointer we may need to update it |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_DECIMAL: nParamValue = '%s', precision = %ld",nParamValue, precision)); |
| |
| if (charptr == NULL) |
| { |
| throwSQLException(wrapperInfo->jenv, PARAMETER_NOT_SET_ERROR, NULL, "07002", 0); |
| FUNCTION_RETURN_NUMERIC(FALSE,("GetStringUTFChars() failed")); |
| goto func_exit; |
| } |
| if (*charptr == '-') //If the 1st char is a "-" then the number is negative |
| { //and we must remove the "-" before sending value to SQL/MX |
| charptr++; //Point to the next charater in the string. |
| *charptr |= 0x80; //SQL/MX uses high order bit of the 1st char to indicated negative number |
| } |
| dataLen = strlen(charptr); |
| |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_DECIMAL: precision(%ld)>targetLength(%ld)",precision,targetLength)); |
| |
| if (dataLen > targetLength) //Make sure that we do not over flow the strorage area in the descriptor |
| { |
| throwSQLException(wrapperInfo->jenv, NUMERIC_VALUE_OUT_OF_RANGE_ERROR, NULL, "22003"); |
| goto func_exit; |
| } |
| memcpy(targetDataPtr, charptr, dataLen); //Copy the data value to the SQL/MX descriptor |
| retcode = TRUE; |
| goto func_exit; |
| break; |
| |
| case SQLTYPECODE_DATETIME: |
| case SQLTYPECODE_INTERVAL: |
| nParamValue = JNI_GetStringUTFChars(wrapperInfo->jenv,(jstring)getWrapperObject(wrapperInfo,paramNumber), NULL); |
| if (nParamValue == NULL) |
| { |
| throwSQLException(wrapperInfo->jenv, PARAMETER_NOT_SET_ERROR, NULL, "07002", 0); |
| FUNCTION_RETURN_NUMERIC(FALSE,("GetStringUTFChars() failed")); |
| } |
| dataLen = strlen(nParamValue); |
| break; |
| default: |
| nParamValue = NULL; |
| dataLen = 0; |
| break; |
| } |
| |
| switch (sqlDataType) |
| { |
| case SQLTYPECODE_CHAR: |
| // targetLength includes extra byte for null (ISO88591 only) |
| if (dataLengthNotExceeded(charSet, dataLen, targetLength)) |
| { |
| memcpy(targetDataPtr, nParamValue, dataLen); |
| memset(targetDataPtr+dataLen, ' ', targetLength-dataLen); |
| |
| if (charSet == SQLCHARSETCODE_UCS2) |
| { |
| // Back fill target buffer with double byte 'space' characters (i.e. 0x00 0x20) |
| for (i = dataLen; i < targetLength; i+=2) |
| { |
| *(targetDataPtr+i) = 0; |
| } |
| } |
| } |
| else |
| { |
| throwSQLException(wrapperInfo->jenv, STRING_DATA_TRUNCATED_ERROR, NULL, "22001"); |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE, |
| ("dataLen(%ld) exceeds targetLength(%ld)", dataLen, targetLength)); |
| goto func_exit; |
| } |
| MEMORY_DUMP(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,targetDataPtr,targetLength); |
| break; |
| case SQLTYPECODE_VARCHAR: |
| if (targetLength > dataLen) |
| { |
| memcpy(targetDataPtr, nParamValue, dataLen); |
| // null terminate ascii strings |
| if (charSet == SQLCHARSETCODE_ISO88591) |
| { |
| *(targetDataPtr+dataLen) = 0; |
| } |
| } |
| else |
| { |
| throwSQLException(wrapperInfo->jenv, STRING_DATA_TRUNCATED_ERROR, NULL, "22001"); |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE, |
| ("targetLength(%ld)<=dataLen(%ld)", |
| targetLength, dataLen)); |
| goto func_exit; |
| } |
| MEMORY_DUMP(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,targetDataPtr,targetLength); |
| break; |
| case SQLTYPECODE_VARCHAR_WITH_LENGTH: |
| case SQLTYPECODE_VARCHAR_LONG: |
| case SQLTYPECODE_CLOB: |
| case SQLTYPECODE_BLOB: |
| case SQLTYPECODE_DATETIME: |
| case SQLTYPECODE_INTERVAL: |
| if (vcIndLength == 4 && targetLength > dataLen+sizeof(int)) |
| { |
| *(unsigned int *)targetDataPtr = (unsigned int)dataLen; |
| memcpy(targetDataPtr+sizeof(int), nParamValue, dataLen); |
| |
| switch(charSet) |
| { |
| case SQLCHARSETCODE_KANJI: |
| case SQLCHARSETCODE_KSC5601: |
| // Back fill target buffer with "special" double byte |
| // 'space' characters (i.e. 0x20 0x20) |
| // Note: This is a backward compatibility issue with SQL/MP Tables |
| memset(targetDataPtr+sizeof(int)+dataLen, ' ', targetLength-dataLen-sizeof(int)); |
| break; |
| |
| case SQLCHARSETCODE_UCS2: |
| // Back fill target buffer with double byte 'space' characters (i.e. 0x00 0x20) |
| // by first setting entire buffer to spaces (0x20), then backfilling with 0x00 |
| memset(targetDataPtr+sizeof(int)+dataLen, ' ', targetLength-dataLen-sizeof(int)); |
| for (i = dataLen+sizeof(int); i < targetLength; i+=2) |
| { |
| *(targetDataPtr+i) = 0; |
| } |
| break; |
| } |
| } |
| else if ( targetLength >= dataLen + sizeof(short)) |
| { |
| *(unsigned short *)targetDataPtr = (unsigned short) dataLen; |
| memcpy(targetDataPtr + sizeof(short), nParamValue, dataLen); |
| |
| switch(charSet) |
| { |
| case SQLCHARSETCODE_KANJI: |
| case SQLCHARSETCODE_KSC5601: |
| // Back fill target buffer with "special" double byte |
| // 'space' characters (i.e. 0x20 0x20) |
| // Note: This is a backward compatibility issue with SQL/MP Tables |
| memset(targetDataPtr + sizeof(short) + dataLen, ' ', targetLength - dataLen - sizeof(short)); |
| break; |
| |
| case SQLCHARSETCODE_UCS2: |
| // Back fill target buffer with double byte 'space' characters (i.e. 0x00 0x20) |
| // by first setting entire buffer to spaces (0x20), then backfilling with 0x00 |
| memset(targetDataPtr + sizeof(short) + dataLen, ' ', targetLength -dataLen - sizeof(short)); |
| for (i = dataLen + sizeof(short); i < targetLength; i += 2) |
| { |
| *(targetDataPtr + i) = 0; |
| } |
| break; |
| } |
| } |
| else |
| { |
| throwSQLException(wrapperInfo->jenv, STRING_DATA_TRUNCATED_ERROR, NULL, "22001"); |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE, |
| ("targetLength(%ld)<=dataLen(%ld)+sizeof(short)(%ld)", |
| targetLength, dataLen, sizeof(short))); |
| goto func_exit; |
| } |
| MEMORY_DUMP(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,targetDataPtr,targetLength); |
| break; |
| |
| default: |
| throwSQLException(wrapperInfo->jenv, PROGRAMMING_ERROR, gJNILayerErrorMsgs[RESTRICTED_DATATYPE_ERROR], |
| "HY000"); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("Data Type not supported. RESTRICTED_DATATYPE_ERROR thrown.")); |
| goto func_exit; |
| } |
| retcode = TRUE; |
| func_exit: |
| switch (sqlDataType) |
| { |
| case SQLTYPECODE_CHAR: |
| case SQLTYPECODE_VARCHAR: |
| case SQLTYPECODE_VARCHAR_LONG: |
| case SQLTYPECODE_VARCHAR_WITH_LENGTH: |
| case SQLTYPECODE_CLOB: |
| case SQLTYPECODE_BLOB: |
| if (nParamValue != NULL) |
| { |
| JNI_ReleaseByteArrayElements(wrapperInfo->jenv,stringByteArray, (jbyte *)nParamValue, JNI_ABORT); |
| } |
| break; |
| default: |
| if (nParamValue != NULL) |
| { |
| JNI_ReleaseStringUTFChars(wrapperInfo->jenv,(jstring)getWrapperObject(wrapperInfo,paramNumber), nParamValue); |
| } |
| break; |
| } |
| FUNCTION_RETURN_NUMERIC(retcode,(NULL)); |
| } |
| |
| |
| jobject getSQLCatalogsInfo(JNIEnv *jenv, jobject jobj, jstring server, jlong dialogueId, |
| jint txid, jboolean autoCommit, jint txnMode, |
| short catalogAPI, |
| jstring catalogNm, |
| jstring schemaNm, jstring tableNm, jstring tableTypeList, |
| jstring columnNm, jint columnType, jint rowIdScope, long nullable, |
| long uniqueness, jint accuracy, jshort sqlType, jint metadataId, |
| jstring fkcatalogNm, jstring fkschemaNm, jstring fktableNm) |
| { |
| FUNCTION_ENTRY("getSQLCatalogsInfo",("server=%s, dialogueId=0x%08x, txid=0x%08x, autoCommit=%s, txnMode=%ld, catalogAPI=%d ...", |
| DebugJString(jenv,server), |
| dialogueId, |
| txid, |
| DebugBoolStr(autoCommit), |
| txnMode, |
| catalogAPI)); |
| |
| |
| ExceptionStruct exception_; |
| SQLItemDescList_def outputDesc; |
| ERROR_DESC_LIST_def sqlWarning; |
| SQLValueList_def outputValueList; |
| long rowsAffected; |
| char catStmtLabel[50]; |
| jobject SQLMXResultSet = NULL; |
| jint currentTxid = txid; |
| jint externalTxid; |
| SRVR_STMT_HDL *pSrvrStmt; |
| long sqlcode; |
| short txn_status; |
| |
| //intialize exception_ structure, so that if catalog api run successfully, there is no exception |
| memset((void*)&exception_,0,sizeof(ExceptionStruct)); |
| |
| const char *nCatalogNm; |
| const char *nSchemaNm; |
| const char *nTableNm; |
| const char *nTableTypeList; |
| const char *nColumnNm; |
| const char *nfkCatalogNm; |
| const char *nfkSchemaNm; |
| const char *nfkTableNm; |
| long stmtId; |
| |
| if (catalogNm) |
| nCatalogNm = JNI_GetStringUTFChars(jenv,catalogNm, NULL); |
| else |
| nCatalogNm = ""; |
| |
| if (schemaNm) |
| nSchemaNm = JNI_GetStringUTFChars(jenv,schemaNm, NULL); |
| else |
| nSchemaNm = ""; |
| |
| if (tableNm) |
| nTableNm = JNI_GetStringUTFChars(jenv,tableNm, NULL); |
| else |
| nTableNm = ""; |
| |
| if (columnNm) |
| nColumnNm = JNI_GetStringUTFChars(jenv,columnNm, NULL); |
| else |
| nColumnNm = ""; |
| |
| if (tableTypeList) |
| nTableTypeList = JNI_GetStringUTFChars(jenv,tableTypeList, NULL); |
| else |
| nTableTypeList = ""; |
| |
| if (fkcatalogNm) |
| nfkCatalogNm = JNI_GetStringUTFChars(jenv,fkcatalogNm, NULL); |
| else |
| nfkCatalogNm = ""; |
| |
| if (fkschemaNm) |
| nfkSchemaNm = JNI_GetStringUTFChars(jenv,fkschemaNm, NULL); |
| else |
| nfkSchemaNm = ""; |
| |
| if (fktableNm) |
| nfkTableNm = JNI_GetStringUTFChars(jenv,fktableNm, NULL); |
| else |
| nfkTableNm = ""; |
| |
| if ((txn_status = beginTxnControl(jenv, currentTxid, externalTxid, txnMode, -1)) != 0) |
| { |
| jenv->CallVoidMethod(jobj, gJNICache.setCurrentTxidDBMMethodId, currentTxid); |
| throwTransactionException(jenv, txn_status); |
| FUNCTION_RETURN_PTR(NULL,("beginTxnControl() failed")); |
| } |
| |
| // Null out outputValueList before we pass it down |
| CLEAR_LIST(outputValueList); |
| |
| odbc_SQLSvc_GetSQLCatalogs_sme_(NULL, NULL, |
| &exception_, |
| dialogueId, |
| catalogAPI, |
| nCatalogNm, |
| nSchemaNm, |
| nTableNm, |
| nTableTypeList, |
| nColumnNm, |
| columnType, |
| rowIdScope, |
| nullable, |
| uniqueness, |
| accuracy, |
| sqlType, |
| metadataId, |
| catStmtLabel, |
| &outputDesc, |
| &sqlWarning, |
| &rowsAffected, |
| &outputValueList, |
| &stmtId, |
| nfkCatalogNm, |
| nfkSchemaNm, |
| nfkTableNm); |
| |
| if (catalogNm) |
| JNI_ReleaseStringUTFChars(jenv,catalogNm, nCatalogNm); |
| |
| if (schemaNm) |
| JNI_ReleaseStringUTFChars(jenv,schemaNm, nSchemaNm); |
| |
| if (tableNm) |
| JNI_ReleaseStringUTFChars(jenv,tableNm, nTableNm); |
| |
| if (columnNm) |
| JNI_ReleaseStringUTFChars(jenv,columnNm, nColumnNm); |
| |
| if (tableTypeList) |
| JNI_ReleaseStringUTFChars(jenv,tableTypeList, nTableTypeList); |
| |
| if (fkcatalogNm) |
| JNI_ReleaseStringUTFChars(jenv,fkcatalogNm, nfkCatalogNm); |
| |
| if (fkschemaNm) |
| JNI_ReleaseStringUTFChars(jenv,fkschemaNm, nfkSchemaNm); |
| |
| if (fktableNm) |
| JNI_ReleaseStringUTFChars(jenv,fktableNm, nfkTableNm); |
| if ((txn_status = endTxnControl(jenv, currentTxid, txid, autoCommit, |
| exception_.exception_nr, TRUE, txnMode, externalTxid)) != 0) |
| { |
| jenv->CallVoidMethod(jobj, gJNICache.setCurrentTxidDBMMethodId, currentTxid); |
| throwTransactionException(jenv, txn_status); |
| FUNCTION_RETURN_PTR(NULL,("endTxnControl() Failed")); |
| } |
| |
| switch (exception_.exception_nr) |
| { |
| case CEE_SUCCESS: |
| |
| if ((pSrvrStmt = getSrvrStmt(dialogueId, stmtId, &sqlcode)) == NULL) |
| { |
| throwSQLException(jenv, INVALID_HANDLE_ERROR, NULL, "HY000", sqlcode); |
| FUNCTION_RETURN_PTR(NULL,("getSrvrStmt() did not return a server statement")); |
| } |
| SQLMXResultSet = setGetSQLCatalogOutputs(jenv, jobj, pSrvrStmt, &outputDesc, catStmtLabel, currentTxid, |
| rowsAffected, TRUE, &outputValueList, stmtId); |
| |
| if (sqlWarning._length > 0) setSQLWarning(jenv, jobj, &sqlWarning); |
| break; |
| case odbc_SQLSvc_GetSQLCatalogs_ParamError_exn_: |
| jenv->CallVoidMethod(jobj, gJNICache.setCurrentTxidDBMMethodId, currentTxid); |
| throwSQLException(jenv, MODULE_ERROR, exception_.u.ParamError.ParamDesc, "HY000"); |
| break; |
| case odbc_SQLSvc_GetSQLCatalogs_SQLError_exn_: |
| jenv->CallVoidMethod(jobj, gJNICache.setCurrentTxidDBMMethodId, currentTxid); |
| throwSQLException(jenv, &exception_.u.SQLError); |
| break; |
| case odbc_SQLSvc_GetSQLCatalogs_SQLInvalidHandle_exn_: |
| jenv->CallVoidMethod(jobj, gJNICache.setCurrentTxidDBMMethodId, currentTxid); |
| throwSQLException(jenv, INVALID_HANDLE_ERROR, NULL, "HY000", exception_.u.SQLInvalidHandle.sqlcode); |
| break; |
| case odbc_SQLSvc_GetSQLCatalogs_InvalidConnection_exn_: |
| default: |
| // TFDS - These exceptions should not happen |
| jenv->CallVoidMethod(jobj, gJNICache.setCurrentTxidDBMMethodId, currentTxid); |
| throwSQLException(jenv, PROGRAMMING_ERROR, NULL, "HY000", exception_.exception_nr); |
| break; |
| } |
| FUNCTION_RETURN_PTR(SQLMXResultSet,(NULL)); |
| } |
| |
| void throwSetConnectionException(JNIEnv *jenv, ExceptionStruct *exception_) |
| { |
| switch (exception_->exception_nr) |
| { |
| case odbc_SQLSvc_SetConnectionOption_ParamError_exn_: |
| throwSQLException(jenv, PROGRAMMING_ERROR, exception_->u.ParamError.ParamDesc, "HY000"); |
| break; |
| case odbc_SQLSvc_SetConnectionOption_SQLError_exn_: |
| throwSQLException(jenv, &exception_->u.SQLError); |
| break; |
| case odbc_SQLSvc_SetConnectionOption_SQLInvalidHandle_exn_: |
| throwSQLException(jenv, INVALID_HANDLE_ERROR, NULL, "HY000", exception_->u.SQLInvalidHandle.sqlcode); |
| break; |
| case odbc_SQLSvc_SetConnectionOption_InvalidConnection_exn_: |
| default: |
| // TFDS - These exceptions should not happen |
| throwSQLException(jenv, PROGRAMMING_ERROR, NULL, "HY000", exception_->exception_nr); |
| break; |
| } |
| } |
| |
| short suspendExtTxn(jint &externalTxid) |
| { |
| /* |
| FUNCTION_ENTRY("suspendExtTxn", |
| ("externalTxid=0x%08x", |
| externalTxid)); |
| |
| short exttxnhandle[10]; |
| short status = 0; |
| |
| #ifndef NSK_PLATFORM // Linux port - ToDo txn related |
| return 0; |
| #else |
| // Get txn handle within current thread |
| status = TMF_GETTXHANDLE_((short *)&exttxnhandle); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("TMF_GETTXHANDLE_() returned %d", status)); |
| if (status != 0) |
| FUNCTION_RETURN_NUMERIC(status,("TMF_GETTXHANDLE_ returned error")); |
| |
| // Get "txn-begin-tag" from txn handle |
| #ifdef _LP64 |
| status = TMF_BEGINTAG_FROM_TXHANDLE_(exttxnhandle, ( __int32_t _ptr32 *) &externalTxid); //venu type casted this pointer |
| #else |
| status = TMF_BEGINTAG_FROM_TXHANDLE_(exttxnhandle, &externalTxid); |
| #endif |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("TMF_BEGINTAG_FROM_TXHANDLE_() returned %d; externalTxid = 0x%08x", status, (long *)externalTxid)); |
| if (status != 0) |
| FUNCTION_RETURN_NUMERIC(status,("TMF_BEGINTAG_FROM_TXHANDLE_ returned error")); |
| #endif |
| status = resumeTransaction(0); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("resumeTransaction(0x%08x) returned %d", externalTxid, status)); |
| |
| FUNCTION_RETURN_NUMERIC(status,(NULL)); |
| */ |
| return 0; |
| } |
| |
| short resumeOrBeginTxn(JNIEnv *jenv, jint ¤tTxid, jint &externalTxid, jint txnMode) |
| { |
| /* |
| FUNCTION_ENTRY("resumeOrBeginTxn",("jenv=0x%08x, currentTxid=0x%08x, externalTxid=0x%08x, txnMode=%ld,", |
| jenv, |
| currentTxid, |
| externalTxid, |
| txnMode)); |
| |
| short status; |
| |
| #ifndef NSK_PLATFORM // Linux port - ToDo txn related |
| return 0; |
| #else |
| short txid[4]; |
| long *txid_ptr;; |
| txid_ptr = (long *)&txid[0]; |
| |
| externalTxid = 0; |
| |
| status = GETTRANSID((short *)&txid); |
| txid[3]=0; |
| |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("GETTRANSID() returned %d ; trans-begin-tag = 0x%08x", status, *txid_ptr)); |
| |
| switch (status) |
| { |
| // Zero indicates that there is a TMF transaction on the current thread |
| case 0: |
| // Display internal and external form of the transaction tag for debug purposes |
| DEBUG_OUT(DEBUG_LEVEL_TXN, ("currentTxid = 0x%08x", currentTxid)); |
| DEBUG_TRANSTAG(); |
| |
| if (currentTxid != 0) |
| { |
| status = INVALID_TRANSACTION_STATE; |
| FUNCTION_RETURN_NUMERIC(status,("currentTxid != 0")); |
| } |
| // suspend external txn when in "internal" txn mode |
| if (txnMode == org_apache_trafodion_jdbc_t2_SQLMXConnection_TXN_MODE_INTERNAL) |
| { |
| if ((status = suspendExtTxn(externalTxid)) != 0) |
| FUNCTION_RETURN_NUMERIC(status, |
| ("Failed to suspend external txn -- ext txnId = 0x%08x", externalTxid)); |
| // continue processing to the next case to either begin a new txn or resume the current txn |
| } |
| else |
| { |
| // Set external txid to a non-zero value to indicate an external txn is in progress |
| // and break from switch |
| externalTxid = -1; |
| break; |
| } |
| |
| case 75: // Nil State Transaction |
| case 78: //Added for R3.0,incase of a invalid transaction also begin a transaction -senthil |
| if (currentTxid == 0) |
| { |
| status = beginTransaction((long *)¤tTxid); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("beginTransaction(0x%08x) returned %d", |
| currentTxid, |
| status)); |
| } |
| else |
| { |
| status = resumeTransaction(currentTxid); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("resumeTransaction(0x%08x) returned %d", |
| currentTxid, |
| status)); |
| switch (status) |
| { |
| case 0: |
| break; |
| // Note: Per TMF Application Programmer's Guide - Do not need call abortTransaction() or endTransaction() |
| // for the following three error codes. |
| case 31: // Unable to obtain file-system buffer space |
| case 36: // Unable to lock physical memory; not enough memory available |
| case 78: // Invalid txn id |
| currentTxid = 0; |
| break; |
| /*For 10-091005-5100, Just pass back the error 97*/ |
| /* |
| case 97: // CONTROL QUERY DEFAULT DOOM_USERTRANSACTION 'ON' |
| break; |
| default: |
| short rc = abortTransaction(); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("abortTransaction() returned %d (Not handled)", |
| rc)); |
| currentTxid = 0; |
| } |
| } |
| break; |
| default: |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("GETTRANSID() returned %d (default case)", status)); |
| } |
| #endif |
| FUNCTION_RETURN_NUMERIC(status,(NULL)); |
| */ |
| return 0; |
| } |
| |
| short resumeTxn(JNIEnv *jenv, jint ¤tTxid, jint &externalTxid, jint txnMode) |
| { |
| /* |
| FUNCTION_ENTRY("resumeTxn",("jenv=0x%08x, currentTxid=0x%08x, externalTxid=0x%08x", |
| jenv, |
| currentTxid, |
| externalTxid)); |
| |
| short status; |
| |
| #ifndef NSK_PLATFORM // Linux port - ToDo txn related |
| return 0; |
| #else |
| short txid[4]; |
| long *txid_ptr;; |
| txid_ptr = (long *)&txid[0]; |
| |
| externalTxid = 0; |
| |
| status = GETTRANSID((short *)&txid); |
| txid[3]=0; |
| |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("GETTRANSID() returned %d ; trans-begin-tag = 0x%08x", status, *txid_ptr)); |
| |
| switch (status) |
| { |
| case 0: |
| // Display internal and external form of the transaction tag for debug purposes |
| DEBUG_OUT(DEBUG_LEVEL_TXN, ("currentTxid = 0x%08x", currentTxid)); |
| DEBUG_TRANSTAG(); |
| |
| // If there is any txid in the Connection Context, throw error (mixed mode only) |
| if (currentTxid != 0) |
| { |
| status = INVALID_TRANSACTION_STATE; |
| FUNCTION_RETURN_NUMERIC(status,("Invalid transaction state -- currentTxid != 0 ")); |
| } |
| // suspend external txn when in "internal" txn mode |
| if (txnMode == org_apache_trafodion_jdbc_t2_SQLMXConnection_TXN_MODE_INTERNAL) |
| { |
| if ((status = suspendExtTxn(externalTxid)) != 0) |
| { |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("suspendExtTxn returned ext txn = 0x%08x", externalTxid)); |
| FUNCTION_RETURN_NUMERIC(status,("Failed to suspend external txn or get external txid.")); |
| } |
| } |
| else |
| { |
| // Set external txid to a non-zero value to indicate an external txn is in progress |
| // and break from switch |
| externalTxid = -1; |
| break; |
| } |
| case 75: // Nil State Transaction |
| case 78: //Added for R3.0,incase of a invalid transaction also begin a transaction -senthil |
| status = resumeTransaction(currentTxid); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("resumeTransaction(0x%08x) returned %d", |
| currentTxid, status)); |
| switch (status) |
| { |
| case 0: |
| break; |
| // Note: Per TMF Application Programmer's Guide - Do not need call abortTransaction() or endTransaction() |
| // for the following three error codes. |
| case 31: // Unable to obtain file-system buffer space |
| case 36: // Unable to lock physical memory; not enough memory available |
| case 78: // Invalid txn id |
| currentTxid = 0; |
| break; |
| default: |
| short rc = abortTransaction(); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("abortTransaction() returned %d (Not handled)", |
| rc)); |
| currentTxid = 0; |
| } |
| break; |
| default: |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("GETTRANSID() returned %d (default case)", status)); |
| } |
| #endif |
| FUNCTION_RETURN_NUMERIC(status,(NULL)); |
| */ |
| return 0; |
| } |
| |
| short suspendOrEndTxn(JNIEnv *jenv, jint ¤tTxid, |
| jboolean autoCommit, unsigned long exception_nr, |
| jboolean isSelect) |
| { |
| /* |
| FUNCTION_ENTRY("suspendOrEndTxn",("jenv=0x%08x, currentTxid=0x%08x, autoCommit=%s, exception_nr=%ld, isSelect=%s", |
| jenv, |
| currentTxid, |
| DebugBoolStr(autoCommit), |
| exception_nr, |
| DebugBoolStr(isSelect))); |
| |
| short status = 0; |
| |
| // Abort the transaction independent of autoCommit mode |
| // to ensure the database is consistent |
| // - Ask SQL folks to verify |
| if ((exception_nr != CEE_SUCCESS) && (! isSelect)) |
| { |
| short rc = abortTransaction(); |
| // Ignore any error from ABORT, since SQL might have also aborted |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("abortTransaction() returned %d (Ignored)", |
| rc)); |
| currentTxid = 0; |
| FUNCTION_RETURN_NUMERIC(status,(NULL)); |
| } |
| if (autoCommit) |
| { |
| if (! isSelect) |
| { |
| status = endTransaction(); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("endTransaction() returned %d", |
| status)); |
| currentTxid = 0; |
| } |
| else |
| { |
| status = resumeTransaction(0); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("resumeTransaction(0) returned %d", |
| status)); |
| } |
| } |
| else |
| { |
| status = resumeTransaction(0); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("resumeTransaction(0) returned %d", |
| status)); |
| } |
| FUNCTION_RETURN_NUMERIC(status,(NULL)); |
| */ |
| return 0; |
| } |
| |
| |
| |
| short suspendOrEndTxn(JNIEnv *jenv, jint ¤tTxid, |
| jint previousTxid, jboolean autoCommit, |
| unsigned long exception_nr, jboolean isSelect) |
| { |
| /* |
| FUNCTION_ENTRY("suspendOrEndTxn", |
| ("jenv=0x%08x, currentTxid=0x%08x, previousTxid=0x%08x, autoCommit=%s, exception_nr=%ld, isSelect=%s", |
| jenv, |
| currentTxid, |
| previousTxid, |
| DebugBoolStr(autoCommit), |
| exception_nr, |
| DebugBoolStr(isSelect))); |
| |
| short status = 0; |
| |
| /* |
| * Description: Type 2 driver now supports atomicity at statement level |
| */ |
| /* |
| if (previousTxid) // Transaction was already started by the previous SQL execution |
| { |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("previous txn (0x%08x) in progres",previousTxid)); |
| if (!autoCommit ) |
| { |
| if((STMT_ATOMICITY == true) || (exception_nr == CEE_SUCCESS) || (isSelect)) |
| { |
| //Always suspend the txn if STMT_ATOMICITY is true |
| status = resumeTransaction(0); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("resumeTransaction(0) returned %d", status)); |
| } |
| else |
| { |
| /*10-091005-5100: Whenever the user has started the txn |
| * dont abort it just resume it as above. |
| */ |
| /* |
| status = resumeTransaction(0); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("resumeTransaction(0) returned %d", status)); |
| /*Commented for 10-091005-5100*/ |
| //short rc = abortTransaction(); |
| // Ignore any error from ABORT, since SQL might have also aborted |
| //DEBUG_OUT(DEBUG_LEVEL_TXN,("abortTransaction() returned %d (Ignored)", rc)); |
| //currentTxid = 0; |
| /*Commented for 10-091005-5100*/ |
| /* |
| } |
| } |
| // Resume txn if cmd passed OR it failed and it is a select |
| else if ( (exception_nr == CEE_SUCCESS) || ((exception_nr != CEE_SUCCESS) && (isSelect)) ) |
| { |
| status = resumeTransaction(0); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("resumeTransaction(0) returned %d", status)); |
| } |
| // abort the txn if cmd failed and it is not a select |
| else // the only other possible option is ==> ((exception_nr != CEE_SUCCESS) && (!isSelect)) |
| { |
| // Abort the transaction (independent of autoCommit mode) |
| // just to make sure the database is consistent |
| // Note: Ask SQL folks to verify |
| short rc = abortTransaction(); |
| // Ignore any error from ABORT, since SQL might have also aborted |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("abortTransaction() returned %d (Ignored)", rc)); |
| currentTxid = 0; |
| } |
| } |
| else |
| { |
| status = suspendOrEndTxn(jenv, currentTxid, autoCommit, exception_nr, isSelect); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("suspendOrEndTxn returned %d : currentTxid = 0x%08x, autoCommit = %s ", |
| status, currentTxid, DebugBoolStr(autoCommit))); |
| } |
| FUNCTION_RETURN_NUMERIC(status,(NULL)); |
| */ |
| return 0; |
| } |
| |
| short beginTxnControl(JNIEnv *jenv, jint ¤tTxid, jint &externalTxid, jint txnMode, jint holdability) |
| { |
| /* |
| FUNCTION_ENTRY("beginTxnControl",("jenv=0x%08x, currentTxid=0x%08x, externalTxid=0x%08x, txnMode=%ld, holdability=%ld", |
| jenv, |
| currentTxid, |
| externalTxid, |
| txnMode, |
| holdability)); |
| |
| short status = 0; |
| |
| switch (txnMode) |
| { |
| case org_apache_trafodion_jdbc_t2_SQLMXConnection_TXN_MODE_INTERNAL: |
| case org_apache_trafodion_jdbc_t2_SQLMXConnection_TXN_MODE_MIXED: |
| if (holdability == CLOSE_CURSORS_AT_COMMIT) |
| { |
| status = resumeTxn(jenv, currentTxid, externalTxid, txnMode); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,( |
| "beginTxnControl -- resumeTxn returned %d currentTxid = 0x%08x", |
| status, currentTxid)); |
| } |
| else |
| { |
| status = resumeOrBeginTxn(jenv, currentTxid, externalTxid, txnMode); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,( |
| "beginTxnControl -- resumeOrBeginTxn returned %d currentTxid = 0x%08x", |
| status, currentTxid)); |
| } |
| break; |
| case org_apache_trafodion_jdbc_t2_SQLMXConnection_TXN_MODE_EXTERNAL: |
| break; |
| default: |
| // This is a programming error if it ever gets to hers |
| status = -2; |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("Invalid txn mode")); |
| } |
| FUNCTION_RETURN_NUMERIC(status,(NULL)); |
| */ |
| return 0; |
| } |
| |
| void throwTransactionException(JNIEnv *jenv, jint err_code) |
| { |
| FUNCTION_ENTRY("throwTransactionException",("jenv=0x%08x, err_code=%ld", |
| jenv, err_code)); |
| |
| char msg[100]; |
| |
| if (err_code > 0) |
| { |
| sprintf(msg,"error %d",err_code); |
| throwSQLException(jenv, TMF_ERROR, msg, "HY000", 0); |
| } |
| else |
| { |
| switch (err_code) |
| { |
| case INVALID_TRANSACTION_STATE: |
| throwSQLException(jenv, INCONSISTENT_TRANSACTION_ERROR, NULL, "25000", 0); |
| break; |
| // This exception should never be thrown |
| default: |
| throwSQLException(jenv, PROGRAMMING_ERROR, NULL, "HY000", 0); |
| break; |
| } |
| } |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| short endTxnControl(JNIEnv *jenv, jint ¤tTxid, jint txid, |
| jboolean autoCommit, unsigned long exception_nr, jboolean isSelect, |
| jint txnMode, jint &externalTxid) |
| { |
| /* |
| FUNCTION_ENTRY("endTxnControl",("jenv=0x%08x, currentTxid=0x%08x, txid=0x%08x, autoCommit=%s, exception_nr=%ld, isSelect=%s, txnMode=%ld, externalTxid=0x%08x", |
| jenv, |
| currentTxid, |
| txid, |
| DebugBoolStr(autoCommit), |
| exception_nr, |
| DebugBoolStr(isSelect), |
| txnMode, |
| externalTxid)); |
| |
| short status = 0; |
| switch (txnMode) |
| { |
| case org_apache_trafodion_jdbc_t2_SQLMXConnection_TXN_MODE_INTERNAL: |
| status = suspendOrEndTxn(jenv, currentTxid, txid, autoCommit, exception_nr, isSelect); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("suspendOrEndTxn returned %d for currentTxid 0x%08x , txid = 0x%08x", |
| status, currentTxid, txid)); |
| if (status != 0) |
| FUNCTION_RETURN_NUMERIC(status,("suspendOrEndTxn() failed")); |
| |
| // resume external txn if one existed |
| if (externalTxid != 0) |
| { |
| status = resumeTransaction(externalTxid); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("Resuming ext txn -- resumeTransaction(0x%08x) returned %d", |
| externalTxid, status)); |
| switch (status) |
| { |
| case 0: |
| break; |
| // Note: Per TMF Application Programmer's Guide - Do not need call abortTransaction() or endTransaction() |
| // for the following three error codes. |
| case 31: // Unable to obtain file-system buffer space |
| case 36: // Unable to lock physical memory; not enough memory available |
| case 78: // Invalid txn id |
| externalTxid = 0; |
| break; |
| default: |
| short rc = abortTransaction(); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("abortTransaction() returned %d (Not handled)", |
| rc)); |
| externalTxid = 0; |
| } |
| } |
| break; |
| case org_apache_trafodion_jdbc_t2_SQLMXConnection_TXN_MODE_MIXED: |
| if (externalTxid == 0) |
| { |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("Not an external txn: currentTxid = 0x%08x, txid = 0x%08x", currentTxid, txid)); |
| status = suspendOrEndTxn(jenv, currentTxid, txid, autoCommit, exception_nr, isSelect); |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("suspendOrEndTxn returned %d for currentTxid (0x%08x)", status, currentTxid)); |
| } |
| break; |
| case org_apache_trafodion_jdbc_t2_SQLMXConnection_TXN_MODE_EXTERNAL: |
| break; |
| default: |
| // This is a programming error if it ever gets to hers |
| status = -2; |
| DEBUG_OUT(DEBUG_LEVEL_TXN,("Invalid txn mode")); |
| } |
| FUNCTION_RETURN_NUMERIC(status,(NULL)); |
| */ |
| return 0; |
| } |
| |
| |
| BOOL cacheJNIObjects(JNIEnv *jenv) |
| { |
| FUNCTION_ENTRY("cacheJNIObjects",("jenv=0x%08x", |
| jenv)); |
| |
| if (jenv == gJEnv) |
| FUNCTION_RETURN_NUMERIC(TRUE,("%s",DebugBoolStr(TRUE))); |
| |
| //SQLException |
| jclass sqlExceptionClass = JNI_FindClass(jenv,"java/sql/SQLException"); |
| if (sqlExceptionClass == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - sqlExceptionClass == NULL")); |
| gJNICache.sqlExceptionClass = (jclass)JNI_NewGlobalRef(jenv,sqlExceptionClass); |
| |
| gJNICache.sqlExceptionConstructorId = JNI_GetMethodID(jenv,sqlExceptionClass, "<init>", |
| "(Ljava/lang/String;Ljava/lang/String;I)V"); |
| if (gJNICache.sqlExceptionConstructorId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.sqlExceptionConstructorId == NULL")); |
| gJNICache.setNextExceptionMethodId=JNI_GetMethodID(jenv,sqlExceptionClass,"setNextException", |
| "(Ljava/sql/SQLException;)V"); |
| if (gJNICache.setNextExceptionMethodId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.setNextExceptionMethodId == NULL")); |
| |
| //SQLWarning |
| jclass sqlWarningClass = JNI_FindClass(jenv,"java/sql/SQLWarning"); |
| if (sqlWarningClass == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - sqlWarningClass == NULL")); |
| gJNICache.sqlWarningClass = (jclass)JNI_NewGlobalRef(jenv,sqlWarningClass); |
| gJNICache.sqlWarningConstructorId = JNI_GetMethodID(jenv,sqlWarningClass, "<init>", |
| "(Ljava/lang/String;Ljava/lang/String;I)V"); |
| if (gJNICache.sqlWarningConstructorId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.sqlWarningConstructorId")); |
| gJNICache.setNextWarningMethodId=JNI_GetMethodID(jenv,sqlWarningClass,"setNextWarning", |
| "(Ljava/sql/SQLWarning;)V"); |
| if (gJNICache.setNextWarningMethodId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.setNextWarningMethodId == NULL")); |
| |
| //SQLMXHandle |
| jclass handleClass = JNI_FindClass(jenv,"org/apache/trafodion/jdbc/t2/SQLMXHandle"); |
| gJNICache.sqlWarningMethodId = JNI_GetMethodID(jenv,handleClass, "setSqlWarning", |
| "(Ljava/sql/SQLWarning;)V"); |
| if (gJNICache.sqlWarningMethodId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.sqlWarningMethodId == NULL")); |
| |
| //SQLMXDesc |
| jclass SQLMXDescClass = JNI_FindClass(jenv,"org/apache/trafodion/jdbc/t2/SQLMXDesc"); |
| if (SQLMXDescClass == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - SQLMXDescClass == NULL")); |
| gJNICache.SQLMXDescClass = (jclass)JNI_NewGlobalRef(jenv,SQLMXDescClass); |
| gJNICache.SQLMXDescConstructorId = JNI_GetMethodID(jenv,SQLMXDescClass, "<init>", |
| "(ISISSZLjava/lang/String;ZISIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IIILjava/lang/String;)V"); |
| if (gJNICache.SQLMXDescConstructorId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.SQLMXDescConstructorId == NULL")); |
| |
| // SQLMXPreparedStatement |
| jclass SQLMXPreparedStatementClass = JNI_FindClass(jenv,"org/apache/trafodion/jdbc/t2/SQLMXPreparedStatement"); |
| if (SQLMXPreparedStatementClass == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - SQLMXPreparedStatementClass == NULL")); |
| gJNICache.prepareOutputsMethodId = JNI_GetMethodID(jenv,SQLMXPreparedStatementClass, "setPrepareOutputs", |
| "([Lorg/apache/trafodion/jdbc/t2/SQLMXDesc;[Lorg/apache/trafodion/jdbc/t2/SQLMXDesc;IIIJ)V"); |
| if (gJNICache.prepareOutputsMethodId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.prepareOutputsMethodId == NULL")); |
| gJNICache.executeOutputsMethodId = JNI_GetMethodID(jenv,SQLMXPreparedStatementClass, "setExecuteOutputs", |
| "([II[Lorg/apache/trafodion/jdbc/t2/DataWrapper;II)V"); |
| if (gJNICache.executeOutputsMethodId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.executeOutputsMethodId == NULL")); |
| |
| // SQLMXStatement |
| jclass SQLMXStatementClass = JNI_FindClass(jenv,"org/apache/trafodion/jdbc/t2/SQLMXStatement"); |
| if (SQLMXStatementClass == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - SQLMXStatementClass == NULL")); |
| gJNICache.execDirectOutputsMethodId = JNI_GetMethodID(jenv,SQLMXStatementClass, "setExecDirectOutputs", |
| "([Lorg/apache/trafodion/jdbc/t2/SQLMXDesc;I[Lorg/apache/trafodion/jdbc/t2/DataWrapper;IIJI)V"); |
| if (gJNICache.execDirectOutputsMethodId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.execDirectOutputsMethodId == NULL")); |
| |
| gJNICache.execRSOutputsMethodId = JNI_GetMethodID(jenv,SQLMXStatementClass, "setExecRSOutputs", |
| "([Lorg/apache/trafodion/jdbc/t2/SQLMXDesc;IJI)V"); |
| if (gJNICache.execRSOutputsMethodId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.execRSOutputsMethodId == NULL")); |
| |
| gJNICache.execDirectBatchOutputsMethodId = JNI_GetMethodID(jenv,SQLMXStatementClass, "setExecDirectBatchOutputs", |
| "(III)V"); |
| if (gJNICache.execDirectBatchOutputsMethodId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.execDirectBatchOutputsMethodId == NULL")); |
| gJNICache.setCurrentTxidStmtMethodId = JNI_GetMethodID(jenv,SQLMXStatementClass, "setCurrentTxid", |
| "(I)V"); |
| if (gJNICache.setCurrentTxidStmtMethodId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.setCurrentTxidStmtMethodId == NULL")); |
| gJNICache.setCurrentStmtIdMethodId = JNI_GetMethodID(jenv,SQLMXStatementClass, "setCurrentStmtId", |
| "(J)V"); |
| if (gJNICache.setCurrentStmtIdMethodId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.setCurrentStmtIdMethodId == NULL")); |
| |
| // SQLMXResultSet |
| jclass SQLMXResultSetClass = JNI_FindClass(jenv,"org/apache/trafodion/jdbc/t2/SQLMXResultSet"); |
| if (SQLMXResultSetClass == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - SQLMXResultSetClass == NULL")); |
| gJNICache.SQLMXResultSetClass = (jclass) JNI_NewGlobalRef(jenv,SQLMXResultSetClass); |
| gJNICache.fetchOutputsMethodId = JNI_GetMethodID(jenv,SQLMXResultSetClass, "setFetchOutputs", |
| "([Lorg/apache/trafodion/jdbc/t2/DataWrapper;IZI)V"); |
| if (gJNICache.fetchOutputsMethodId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.fetchOutputsMethodId == NULL")); |
| gJNICache.SQLMXResultSetConstructorId = JNI_GetMethodID(jenv,SQLMXResultSetClass, "<init>", |
| "(Lorg/apache/trafodion/jdbc/t2/SQLMXDatabaseMetaData;[Lorg/apache/trafodion/jdbc/t2/SQLMXDesc;IJ)V"); |
| if (gJNICache.SQLMXResultSetConstructorId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.SQLMXResultSetConstructorId == NULL")); |
| gJNICache.setCurrentTxidRSMethodId = JNI_GetMethodID(jenv,SQLMXResultSetClass, "setCurrentTxid", |
| "(I)V"); |
| if (gJNICache.setCurrentTxidRSMethodId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.setCurrentTxidRSMethodId == NULL")); |
| |
| //SQLMXDatabaseMetaData |
| jclass SQLMXDatabaseMetaDataClass = JNI_FindClass(jenv,"org/apache/trafodion/jdbc/t2/SQLMXDatabaseMetaData"); |
| if (SQLMXDatabaseMetaDataClass == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - SQLMXDatabaseMetaDataClass == NULL")); |
| gJNICache.setCurrentTxidDBMMethodId = JNI_GetMethodID(jenv,SQLMXDatabaseMetaDataClass, "setCurrentTxid", |
| "(I)V"); |
| if (gJNICache.setCurrentTxidDBMMethodId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.setCurrentTxidDBMMethodId == NULL")); |
| |
| //SQLMXCallableStatement |
| jclass SQLMXCallableStatementClass = JNI_FindClass(jenv,"org/apache/trafodion/jdbc/t2/SQLMXCallableStatement"); |
| if (SQLMXCallableStatementClass == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - SQLMXCallableStatementClass == NULL")); |
| gJNICache.executeCallOutputsMethodId = JNI_GetMethodID(jenv,SQLMXCallableStatementClass, "setExecuteCallOutputs", |
| "(Lorg/apache/trafodion/jdbc/t2/DataWrapper;SIIIZ)V"); |
| |
| |
| if (gJNICache.executeCallOutputsMethodId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.executeCallOutputsMethodId == NULL")); |
| |
| gJNICache.SQLMXConnectionClass = JNI_FindClass(jenv,"org/apache/trafodion/jdbc/t2/SQLMXConnection"); |
| if (gJNICache.SQLMXConnectionClass == NULL) |
| { |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.SQLMXConnectionClass == NULL")); |
| } |
| gJNICache.getSqlStmtTypeMethodId = jenv->GetStaticMethodID(gJNICache.SQLMXConnectionClass, "getSqlStmtType2", "(Ljava/lang/String;)Z"); |
| if (gJNICache.getSqlStmtTypeMethodId == NULL) |
| { |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.getSqlStmtTypeMethodId == NULL")); |
| } |
| |
| //String |
| jclass stringClass = JNI_FindClass(jenv,"java/lang/String"); |
| if (stringClass == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - stringClass == NULL")); |
| gJNICache.stringClass = (jclass)JNI_NewGlobalRef(jenv,stringClass); |
| gJNICache.getBytesMethodId = JNI_GetMethodID(jenv,stringClass, "getBytes", |
| "()[B"); |
| if (gJNICache.getBytesMethodId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.getBytesMethodId == NULL")); |
| gJNICache.stringConstructorId = JNI_GetMethodID(jenv,stringClass, "<init>", |
| "([B)V"); |
| if (gJNICache.stringConstructorId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.stringConstructorId == NULL")); |
| gJNICache.getBytesEncodedMethodId = JNI_GetMethodID(jenv,stringClass, "getBytes", |
| "(Ljava/lang/String;)[B"); |
| if (gJNICache.getBytesEncodedMethodId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.getBytesEncodedMethodId == NULL")); |
| |
| // Create reference to the DataWrapper class |
| jclass wrapperClass = JNI_FindClass(jenv,"org/apache/trafodion/jdbc/t2/DataWrapper"); |
| if (wrapperClass == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - wrapperClass == NULL")); |
| gJNICache.wrapperClass = (jclass)JNI_NewGlobalRef(jenv,wrapperClass); |
| // Big Num Changes |
| gJNICache.wrapperconvertBigDecimalToSQLBigNum = JNI_GetMethodID(jenv, wrapperClass, |
| "convertBigDecimalToSQLBigNum" , "(III)[B"); |
| gJNICache.wrapperconvertSQLBigNumToBigDecimal2 = JNI_GetMethodID(jenv, wrapperClass, |
| "convertSQLBigNumToBigDecimal2", "([BI)Ljava/lang/String;"); |
| // Big Num Changes |
| |
| jclass byteArrayClass = JNI_FindClass(jenv,"[B"); |
| if (byteArrayClass == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - byteArrayClass == NULL")); |
| gJNICache.byteArrayClass = (jclass)JNI_NewGlobalRef(jenv,byteArrayClass); |
| |
| jclass SQLbyteArrayClass = JNI_FindClass(jenv,"[B"); |
| if (SQLbyteArrayClass == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - SQLbyteArrayClass == NULL")); |
| gJNICache.SQLbyteArrayClass = (jclass)JNI_NewGlobalRef(jenv,SQLbyteArrayClass); |
| //------------ |
| // SPJRS |
| // Create reference to the ResultSetInfo class |
| jclass ResultSetInfoClass = JNI_FindClass(jenv,"org/apache/trafodion/jdbc/t2/ResultSetInfo"); |
| if (ResultSetInfoClass == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - ResultSetInfoClass == NULL")); |
| gJNICache.ResultSetInfoClass = (jclass)JNI_NewGlobalRef(jenv,ResultSetInfoClass); |
| |
| // ** ctxHandle - JNI method used to fetch the int field |
| gJNICache.SPJRS_ctxHandleFieldID = JNI_GetFieldID(jenv, ResultSetInfoClass, "ctxHandle", "I"); |
| if (gJNICache.SPJRS_ctxHandleFieldID == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.SPJRS_ctxHandleFieldID == NULL")); |
| |
| // ** stmtID - JNI method used to fetch the int field |
| gJNICache.SPJRS_stmtIDFieldID = JNI_GetFieldID(jenv, ResultSetInfoClass, "stmtID", "I"); |
| if (gJNICache.SPJRS_stmtIDFieldID == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.SPJRS_stmtIDFieldID == NULL")); |
| |
| //10-060831-8723 - stmtClosed - JNI method to fetch the boolean field |
| gJNICache.SPJRS_stmtClosedFieldID = JNI_GetFieldID(jenv, ResultSetInfoClass, "stmtClosed", "Z"); |
| if (gJNICache.SPJRS_stmtClosedFieldID == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.SPJRS_stmtClosedFieldID == NULL")); |
| |
| // SPJRS |
| |
| // Constructor |
| gJNICache.wrapperConstructorId = JNI_GetMethodID(jenv,wrapperClass, "<init>", "(I)V"); |
| if (gJNICache.wrapperConstructorId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.wrapperConstructorId == NULL")); |
| |
| // ** DataType - These are the JNI medthods used to fetch the data type field |
| gJNICache.wrapperDataTypeFieldId = JNI_GetFieldID(jenv,wrapperClass, "dataType", "[B"); |
| if (gJNICache.wrapperDataTypeFieldId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.wrapperDataTypeFieldId == NULL")); |
| |
| // ** setNeeded - These are the JNI medthods used to fetch the setNeeded field |
| gJNICache.wrapperSetNeededFieldId = JNI_GetFieldID(jenv,wrapperClass, "setNeeded", "[Z"); |
| if (gJNICache.wrapperSetNeededFieldId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.wrapperSetNeededFieldId == NULL")); |
| |
| // ** isNull - These are the JNI medthods used to fetch the isNull field |
| gJNICache.wrapperIsNullFieldId = JNI_GetFieldID(jenv,wrapperClass, "isNullValue", "[Z"); |
| if (gJNICache.wrapperIsNullFieldId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.wrapperIsNullFieldId == NULL")); |
| |
| gJNICache.wrapperSetupObjectsMethodId = JNI_GetMethodID(jenv,wrapperClass, "setupObjects","()V"); |
| if (gJNICache.wrapperSetupObjectsMethodId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.wrapperSetupObjectsMethodId == NULL")); |
| |
| // ** Object - These are the JNI medthods used to fetch the object field |
| gJNICache.wrapperObjectFieldId = JNI_GetFieldID(jenv,wrapperClass, "objectValue", "[Ljava/lang/Object;"); |
| if (gJNICache.wrapperObjectFieldId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.wrapperObjectFieldId == NULL")); |
| |
| // ** Bytes - These are the JNI medthods used to fetch the byte array field |
| gJNICache.wrapperBytesFieldId = JNI_GetFieldID(jenv,wrapperClass, "bytesValue", "[[B"); |
| if (gJNICache.wrapperBytesFieldId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.wrapperBytesFieldId == NULL")); |
| |
| // ** SQLBytes - These are the JNI medthods used to fetch the sql byte array field |
| gJNICache.wrapperSQLBytesFieldId = JNI_GetFieldID(jenv,wrapperClass, "SQLbytesValue", "[[B"); |
| if (gJNICache.wrapperSQLBytesFieldId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.wrapperSQLBytesFieldId == NULL")); |
| //------------ |
| // ** Byte - These are the JNI medthods used to fetch the byte field |
| gJNICache.wrapperByteFieldId = JNI_GetFieldID(jenv,wrapperClass, "byteValue", "[B"); |
| if (gJNICache.wrapperByteFieldId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.wrapperByteFieldId == NULL")); |
| |
| // ** Short - These are the JNI medthods used to fetch the short field |
| gJNICache.wrapperShortFieldId = JNI_GetFieldID(jenv,wrapperClass, "shortValue", "[S"); |
| if (gJNICache.wrapperShortFieldId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.wrapperShortFieldId == NULL")); |
| |
| // ** Int - These are the JNI medthods used to fetch the int field |
| gJNICache.wrapperIntFieldId = JNI_GetFieldID(jenv,wrapperClass, "intValue", "[I"); |
| if (gJNICache.wrapperIntFieldId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.wrapperIntFieldId == NULL")); |
| |
| // ** Long - These are the JNI medthods used to fetch the long field |
| gJNICache.wrapperLongFieldId = JNI_GetFieldID(jenv,wrapperClass, "longValue", "[J"); |
| if (gJNICache.wrapperLongFieldId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.wrapperLongFieldId == NULL")); |
| |
| // ** Float - These are the JNI medthods used to fetch the float field |
| gJNICache.wrapperFloatFieldId = JNI_GetFieldID(jenv,wrapperClass, "floatValue", "[F"); |
| if (gJNICache.wrapperFloatFieldId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.wrapperFloatFieldId == NULL")); |
| |
| // ** Double - These are the JNI medthods used to fetch the double field |
| gJNICache.wrapperDoubleFieldId = JNI_GetFieldID(jenv,wrapperClass, "doubleValue", "[D"); |
| if (gJNICache.wrapperDoubleFieldId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.wrapperDoubleFieldId == NULL")); |
| |
| // ** Boolean - These are the JNI medthods used to fetch the boolean field |
| gJNICache.wrapperBooleanFieldId = JNI_GetFieldID(jenv,wrapperClass, "booleanValue", "[Z"); |
| if (gJNICache.wrapperBooleanFieldId == NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - gJNICache.wrapperBooleanFieldId == NULL")); |
| |
| // Allocate Charset structure |
| gJNICache.defaultCharset = SQLCHARSETCODE_UNKNOWN; |
| gJNICache.totalCharsets = 0; |
| while (CHARSET_INFORMATION[gJNICache.totalCharsets].encodingName) gJNICache.totalCharsets++; |
| MEMORY_ALLOC_PERM_ARRAY(gJNICache.charsetInfo,Charset_def,gJNICache.totalCharsets); |
| for (int idx=0; idx<gJNICache.totalCharsets; idx++) |
| { |
| gJNICache.charsetInfo[idx].charset = CHARSET_INFORMATION[idx].charset; |
| gJNICache.charsetInfo[idx].encodingName = CHARSET_INFORMATION[idx].encodingName; |
| jstring encoding = jenv->NewStringUTF(gJNICache.charsetInfo[idx].encodingName); |
| if (encoding==NULL) |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - Encoding NewStringUTF() == NULL")); |
| gJNICache.charsetInfo[idx].encodingNameJava = (jstring) JNI_NewGlobalRef(jenv,encoding); |
| if (gJNICache.charsetInfo[idx].encodingNameJava==NULL) { |
| jenv->DeleteLocalRef(encoding); |
| FUNCTION_RETURN_NUMERIC(FALSE,("FALSE - Encoding NewGlobalRef() == NULL")); |
| } |
| gJNICache.charsetInfo[idx].useDefaultEncoding = FALSE; |
| jenv->DeleteLocalRef(encoding); |
| } |
| if (setenv("MASTER_FAST_COMPLETION","0",1) != 0) |
| abort(); |
| gJEnv = jenv; |
| FUNCTION_RETURN_NUMERIC(TRUE,(NULL)); |
| } |
| |
| void convertInt64ToWrapper(struct WrapperInfoStruct *wrapperInfo, jint columnIndex, Int64 value, short scale) |
| { |
| FUNCTION_ENTRY("convertInt64ToWrapper",("columnIndex=%ld, value=%Ld, scale=%d", |
| columnIndex, |
| value, |
| scale)); |
| |
| if (scale>0) setWrapperDouble(wrapperInfo,columnIndex,value/pow((double)10,scale)); |
| else |
| setWrapperLong(wrapperInfo, columnIndex, value); |
| FUNCTION_RETURN_VOID((NULL)); |
| } |
| |
| BOOL setWrapper(struct WrapperInfoStruct *wrapperInfo, jobject jobj, SRVR_STMT_HDL *pSrvrStmt, jint columnIndex, SQLValue_def *SQLValue, |
| BOOL isIndexParam) |
| { |
| FUNCTION_ENTRY("setWrapper",("pSrvrStmt=0x%08x, columnIndex=%ld, SQLValue=0x%08x, isIndexParam=%d", |
| pSrvrStmt, |
| columnIndex, |
| SQLValue, |
| isIndexParam)); |
| |
| char *strDataPtr = NULL; |
| long DataLen; |
| Int64 source; |
| // Big Num Changes |
| char cTmpBuf[1024]; |
| memset(cTmpBuf, '\0', 1024); |
| // Big Num Changes |
| short currPos = 0; |
| DATE_TYPES *SQLDate; |
| TIME_TYPES *SQLTime; |
| unsigned long ulFraction; |
| short retCode; |
| BOOL usejchar = FALSE; |
| jchar *uStr; |
| size_t retLength; |
| char tmpString[32]; |
| jint precision; |
| jint scale; |
| jboolean isSigned; |
| jint sqlDatetimeCode; |
| jint FSDataType; |
| |
| char *strSQLDataPtr = (char*)SQLValue->dataValue._buffer; |
| long SQLDataLen = SQLValue->dataValue._length; |
| |
| if (strSQLDataPtr){ |
| jbyteArray stringSQLByteArray = JNI_NewByteArray(wrapperInfo->jenv,SQLDataLen); |
| if (stringSQLByteArray == NULL) |
| { |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE, ("stringSQLByteArray is NULL, returning NULL")); |
| } |
| else |
| { |
| JNI_SetByteArrayRegion(wrapperInfo->jenv,stringSQLByteArray,0, SQLDataLen, (jbyte *)strSQLDataPtr); |
| MEMORY_DUMP(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,strSQLDataPtr,SQLDataLen); |
| } |
| setWrapperSQLBytes(wrapperInfo,columnIndex,stringSQLByteArray); |
| } |
| //--------------------------------------- |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLValue: dataType=%s dataValue._buffer=0x%08x, dataValue._length=%ld", |
| CliDebugSqlTypeCode(SQLValue->dataType), |
| SQLValue->dataValue._buffer, |
| SQLValue->dataValue._length)); |
| |
| SRVR_DESC_HDL *IRD; |
| IRD = pSrvrStmt->IRD; |
| scale = IRD[columnIndex].scale; |
| |
| // Linux port- moving here from case block because of compile errors |
| const char *bigNum; |
| jstring bigNumAsString; |
| jbyteArray columnValue; |
| |
| switch (SQLValue->dataType) |
| { |
| case SQLTYPECODE_CHAR: |
| strDataPtr = (char *)SQLValue->dataValue._buffer; |
| |
| // Returns true if dataCharset is ISO88591 |
| if(nullRequired(SQLValue->dataCharset)) |
| { |
| DataLen = SQLValue->dataValue._length - 1; |
| *(strDataPtr + DataLen) = '\0'; |
| } |
| else |
| { |
| DataLen = SQLValue->dataValue._length; |
| } |
| usejchar = TRUE; |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,("char length = %ld", DataLen)); |
| break; |
| case SQLTYPECODE_VARCHAR: |
| strDataPtr = (char *)SQLValue->dataValue._buffer; |
| DataLen = strlen((const char *)SQLValue->dataValue._buffer); |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,("varchar length = %ld", DataLen)); |
| |
| // Null terminate only if ISO88591 |
| if(nullRequired(SQLValue->dataCharset)) |
| *(strDataPtr + DataLen) = '\0'; |
| usejchar = TRUE; |
| break; |
| case SQLTYPECODE_CLOB: |
| case SQLTYPECODE_BLOB: |
| strDataPtr = (char *)SQLValue->dataValue._buffer + sizeof(short); |
| DataLen = *(short *)SQLValue->dataValue._buffer; |
| // Null terminate only if ISO88591 |
| if(nullRequired(SQLValue->dataCharset)) |
| *(strDataPtr + DataLen) = '\0'; |
| usejchar = TRUE; |
| break; |
| case SQLTYPECODE_VARCHAR_WITH_LENGTH: |
| case SQLTYPECODE_VARCHAR_LONG: |
| case SQLTYPECODE_INTERVAL: |
| case SQLTYPECODE_DATETIME: |
| |
| FSDataType = IRD[columnIndex].FSDataType; |
| |
| if (FSDataType != 151) |
| { |
| if ( pSrvrStmt->IRD[columnIndex].vc_ind_length == 4) |
| { |
| strDataPtr = (char *)SQLValue->dataValue._buffer + sizeof(int); |
| DataLen = *(int *)SQLValue->dataValue._buffer; |
| } |
| else |
| { |
| strDataPtr = (char *)SQLValue->dataValue._buffer + sizeof(short); |
| DataLen = *(short *)SQLValue->dataValue._buffer; |
| } |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,("varchar with length = %ld", DataLen)); |
| usejchar = TRUE; |
| } |
| else |
| { |
| retCode = ConvertDecimalToChar(151, // REC_DECIMAL_LS |
| SQLValue->dataValue._buffer, SQLValue->dataValue._length, scale, cTmpBuf); |
| switch (retCode) |
| { |
| case 0: |
| break; |
| default: |
| throwSQLException(wrapperInfo->jenv, PROGRAMMING_ERROR, gJNILayerErrorMsgs[RESTRICTED_DATATYPE_ERROR], |
| "HY000"); |
| FUNCTION_RETURN_NUMERIC(FALSE,("ConvertDecimalToChar() returned %d. RESTRICTED_DATATYPE_ERROR thrown.",retCode)); |
| } |
| strDataPtr = cTmpBuf; |
| break; |
| } |
| break; |
| |
| case SQLTYPECODE_SMALLINT: |
| source = *(short *)SQLValue->dataValue._buffer; |
| convertInt64ToWrapper(wrapperInfo,columnIndex,source,scale); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_SMALLINT: SQL datavalue = %Ld, Scale = %d", |
| source, |
| scale)); |
| break; |
| case SQLTYPECODE_SMALLINT_UNSIGNED: |
| source = *(unsigned short *)SQLValue->dataValue._buffer; |
| convertInt64ToWrapper(wrapperInfo,columnIndex,source,scale); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_SMALLINT_UNSIGNED: SQL datavalue = %Ld, Scale = %d", |
| source, |
| scale)); |
| break; |
| case SQLTYPECODE_INTEGER: |
| source = *(int *)SQLValue->dataValue._buffer; |
| convertInt64ToWrapper(wrapperInfo,columnIndex,source,scale); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_INTEGER: SQL datavalue = %Ld, Scale = %d", |
| source, |
| scale)); |
| break; |
| case SQLTYPECODE_INTEGER_UNSIGNED: |
| source = *(unsigned int *)SQLValue->dataValue._buffer; |
| convertInt64ToWrapper(wrapperInfo,columnIndex,source,scale); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_INTEGER_UNSIGNED: SQL datavalue = %Ld, Scale = %d", |
| source, |
| scale)); |
| break; |
| case SQLTYPECODE_LARGEINT: |
| source = *(Int64 *)SQLValue->dataValue._buffer; |
| convertInt64ToWrapper(wrapperInfo,columnIndex,source,scale); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_LARGEINT: SQL datavalue = %Ld, Scale = %d", |
| source, |
| scale)); |
| break; |
| case SQLTYPECODE_NUMERIC: |
| case SQLTYPECODE_NUMERIC_UNSIGNED: |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_NUMERIC: isIndexParm = %ld", |
| isIndexParam)); |
| /*if (isIndexParam) |
| FSDataType = wrapperInfo->jenv->CallIntMethod(jobj, gJNICache.getOutFSDataTypeMethodId, columnIndex); |
| else |
| FSDataType = wrapperInfo->jenv->CallIntMethod(jobj, gJNICache.RSgetFSDataTypeMethodId, columnIndex); //Anitha --10-060329-5459 */ |
| /* |
| * Description: JDBC/MX no longer throws Restricted Data Type Exception |
| */ |
| |
| FSDataType = IRD[columnIndex].FSDataType; |
| |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_NUMERIC: FSDataType = %ld", |
| FSDataType)); |
| switch (FSDataType) |
| { |
| case _SQLDT_16BIT_S: |
| source = *(short *)SQLValue->dataValue._buffer; |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_NUMERIC: _SQLDT_16BIT_S: SQL datavalue = %Ld, Scale = %d", |
| source, |
| scale)); |
| break; |
| case _SQLDT_16BIT_U: |
| source = *(unsigned short *)SQLValue->dataValue._buffer; |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_NUMERIC: _SQLDT_16BIT_U: SQL datavalue = %Ld, Scale = %d", |
| source, |
| scale)); |
| break; |
| case _SQLDT_32BIT_S: |
| source = *(int *)SQLValue->dataValue._buffer; |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_NUMERIC: _SQLDT_32BIT_S: SQL datavalue = %Ld, Scale = %d", |
| source, |
| scale)); |
| break; |
| case _SQLDT_32BIT_U: |
| source = *(unsigned int *)SQLValue->dataValue._buffer; |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_NUMERIC: _SQLDT_32BIT_U: SQL datavalue = %Ld, Scale = %d", |
| source, |
| scale)); |
| break; |
| case _SQLDT_64BIT_S: |
| source = *(Int64 *)SQLValue->dataValue._buffer; |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_NUMERIC: _SQLDT_64BIT_S: SQL datavalue = %Ld, Scale = %d", |
| source, |
| scale)); |
| break; |
| // Big Num Changes |
| case _SQLDT_NUM_BIG_U: |
| case _SQLDT_NUM_BIG_S: |
| columnValue = wrapperInfo->jenv->NewByteArray(SQLValue->dataValue._length); |
| wrapperInfo->jenv->SetByteArrayRegion(columnValue, 0, SQLValue->dataValue._length, (jbyte *)SQLValue->dataValue._buffer); |
| bigNumAsString = convertSQLBigNumToBigDecimal2(wrapperInfo, columnValue, scale); |
| bigNum = wrapperInfo->jenv->GetStringUTFChars(bigNumAsString, NULL); |
| strcpy(cTmpBuf, bigNum); |
| wrapperInfo->jenv->ReleaseStringUTFChars(bigNumAsString, bigNum); |
| bigNum = NULL; |
| wrapperInfo->jenv->DeleteLocalRef(columnValue); |
| strDataPtr = cTmpBuf; |
| break; |
| // Big Num Changes |
| default: |
| throwSQLException(wrapperInfo->jenv, PROGRAMMING_ERROR, gJNILayerErrorMsgs[RESTRICTED_DATATYPE_ERROR], |
| "HY000"); |
| FUNCTION_RETURN_NUMERIC(FALSE,("wrapperInfo->jenv->CallIntMethod() returned %ld. RESTRICTED_DATATYPE_ERROR thrown.",FSDataType)); |
| } |
| if(_SQLDT_NUM_BIG_U != FSDataType && |
| _SQLDT_NUM_BIG_S != FSDataType) |
| { |
| strDataPtr = convertInt64toAscii(source, scale, cTmpBuf); |
| } |
| // Big Num Changes |
| break; |
| case SQLTYPECODE_DECIMAL: |
| case SQLTYPECODE_DECIMAL_UNSIGNED: |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_DECIMAL: SQL datavalue = %*s, scale = %ld", |
| SQLValue->dataValue._length, |
| SQLValue->dataValue._buffer, |
| scale)); |
| retCode = ConvertDecimalToChar(SQLValue->dataType, |
| SQLValue->dataValue._buffer, SQLValue->dataValue._length, scale, cTmpBuf); |
| if (retCode) |
| { |
| throwSQLException(wrapperInfo->jenv, PROGRAMMING_ERROR, gJNILayerErrorMsgs[RESTRICTED_DATATYPE_ERROR], |
| "HY000"); |
| FUNCTION_RETURN_NUMERIC(FALSE,("ConvertDecimalToChar() returned %d. RESTRICTED_DATATYPE_ERROR thrown.",retCode)); |
| } |
| strDataPtr = cTmpBuf; |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_DECIMAL: JDBC datavalue = %s", |
| strDataPtr)); |
| break; |
| case SQLTYPECODE_DECIMAL_LARGE: |
| case SQLTYPECODE_DECIMAL_LARGE_UNSIGNED: |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_DECIMAL_LARGE: SQL datavalue = %*s, scale = %ld", |
| SQLValue->dataValue._length, |
| SQLValue->dataValue._buffer, |
| scale)); |
| if ((retCode = ConvertSoftDecimalToDouble(SQLValue->dataType, SQLValue->dataValue._buffer, |
| SQLValue->dataValue._length, scale, cTmpBuf)) != 0) |
| { |
| throwSQLException(wrapperInfo->jenv, PROGRAMMING_ERROR, gJNILayerErrorMsgs[RESTRICTED_DATATYPE_ERROR], |
| "HY000"); |
| FUNCTION_RETURN_NUMERIC(FALSE,("ConvertSoftDecimalToDouble() returned %d. RESTRICTED_DATATYPE_ERROR thrown.",retCode)); |
| } |
| strDataPtr = cTmpBuf; |
| break; |
| case SQLTYPECODE_IEEE_REAL: |
| { |
| float fsource = *(float *)SQLValue->dataValue._buffer; |
| setWrapperFloat(wrapperInfo,columnIndex,fsource); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_IEEE_REAL: JDBC datavalue = %g", |
| fsource)); |
| } |
| break; |
| case SQLTYPECODE_IEEE_DOUBLE: |
| { |
| double dsource = *(double *)SQLValue->dataValue._buffer; |
| setWrapperDouble(wrapperInfo,columnIndex,dsource); |
| DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLTYPECODE_IEEE_DOUBLE: JDBC datavalue = %g", |
| dsource)); |
| } |
| break; |
| // The following datatypes should not be returned by SQL/MX. |
| case SQLTYPECODE_BIT: |
| case SQLTYPECODE_BITVAR: |
| case SQLTYPECODE_BPINT_UNSIGNED: |
| case SQLTYPECODE_FLOAT: |
| case SQLTYPECODE_REAL: |
| case SQLTYPECODE_DOUBLE: |
| case SQLTYPECODE_IEEE_FLOAT: |
| char msg[10]; |
| sprintf(msg,"%d",SQLValue->dataType); |
| throwSQLException(wrapperInfo->jenv, DATATYPE_NOT_SUPPPORTED_ERROR, msg, "HY000", 0); |
| FUNCTION_RETURN_NUMERIC(FALSE,("SQLValue->dataType=%s (unsupported). DATATYPE_NOT_SUPPPORTED_ERROR thrown.", |
| CliDebugSqlTypeCode(SQLValue->dataType))); |
| default: |
| throwSQLException(wrapperInfo->jenv, PROGRAMMING_ERROR, gJNILayerErrorMsgs[PROGRAMMING_ERROR], |
| "HY000"); |
| FUNCTION_RETURN_NUMERIC(FALSE,("SQLValue->dataType=%s (programming error). PROGRAMMING_ERROR thrown.", |
| CliDebugSqlTypeCode(SQLValue->dataType))); |
| } |
| if (strDataPtr) |
| { |
| if (usejchar) |
| { |
| jbyteArray stringByteArray = JNI_NewByteArray(wrapperInfo->jenv,DataLen); |
| if (stringByteArray == NULL) |
| { |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE, ("stringByteArray is NULL, returning NULL")); |
| } |
| else |
| { |
| JNI_SetByteArrayRegion(wrapperInfo->jenv,stringByteArray,0, DataLen, (jbyte *)strDataPtr); |
| MEMORY_DUMP(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,strDataPtr,DataLen); |
| } |
| setWrapperBytes(wrapperInfo,columnIndex,stringByteArray); |
| } |
| else |
| { |
| jstring jstr = wrapperInfo->jenv->NewStringUTF(strDataPtr); |
| if (!setWrapperObject(wrapperInfo,columnIndex,jstr,org_apache_trafodion_jdbc_t2_DataWrapper_STRING)) |
| { |
| throwSQLException(wrapperInfo->jenv, JVM_MEM_ALLOC_ERROR, NULL, "HY000"); |
| FUNCTION_RETURN_NUMERIC(FALSE,("setWrapper - JVM_MEM_ALLOC_ERROR")); |
| } |
| DEBUG_OUT(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE, ("String=%s",DebugJString(wrapperInfo->jenv, jstr))); |
| } |
| } |
| FUNCTION_RETURN_NUMERIC(TRUE,(NULL)); |
| } |
| |
| jstring getCharsetEncodingJava(JNIEnv *jenv, long charset, jstring iso88591Encoding) |
| { |
| FUNCTION_ENTRY("getCharsetEncodingJava",("jenv=0x%08x, charset=%ld, iso88591Encoding=%s", |
| jenv, |
| charset, |
| DebugJString(jenv,iso88591Encoding))); |
| |
| jstring rc = NULL; |
| |
| for (int idx=0; idx<gJNICache.totalCharsets; idx++) |
| { |
| if (charset == gJNICache.charsetInfo[idx].charset) |
| { |
| if (iso88591Encoding) |
| { |
| const char *nIso88591Encoding = JNI_GetStringUTFChars(jenv,iso88591Encoding, NULL); |
| if ( strcmp(nIso88591Encoding,defaultEncodingOption) == 0) |
| { |
| rc = NULL; |
| DEBUG_OUT(DEBUG_LEVEL_ENTRY|DEBUG_LEVEL_UNICODE, |
| ("iso88591Encoding is set to DEFAULT, returning null")); |
| } |
| else |
| { |
| rc = iso88591Encoding; |
| DEBUG_OUT(DEBUG_LEVEL_ENTRY|DEBUG_LEVEL_UNICODE, |
| ("Using iso88591Encoding (override)")); |
| } |
| JNI_ReleaseStringUTFChars(jenv,iso88591Encoding, nIso88591Encoding); |
| } |
| else if (charset==gJNICache.defaultCharset) |
| { |
| rc = NULL; |
| DEBUG_OUT(DEBUG_LEVEL_ENTRY|DEBUG_LEVEL_UNICODE, |
| ("charset is equal to the default charset encoding, returning NULL")); |
| } |
| else // Use normal encoding (not overriden and not default) |
| { |
| rc = gJNICache.charsetInfo[idx].encodingNameJava; |
| DEBUG_OUT(DEBUG_LEVEL_ENTRY|DEBUG_LEVEL_UNICODE, |
| ("Using normal charset encoding = %s", DebugJString(jenv,rc))); |
| } |
| } |
| } |
| FUNCTION_RETURN_PTR(rc,("%s",DebugJString(jenv,rc))); |
| } |
| |
| const char *getCharsetEncoding(jint charset) |
| { |
| FUNCTION_ENTRY("getCharsetEncoding",("charset=%ld",charset)); |
| static __thread const char *encoding_name = NULL; |
| static __thread jint last_charset = -9999; |
| if (charset!=last_charset) |
| { |
| int idx = 0; |
| while ((idx<gJNICache.totalCharsets) && |
| (charset!=gJNICache.charsetInfo[idx].charset)) idx++; |
| if (idx!=gJNICache.totalCharsets) encoding_name = gJNICache.charsetInfo[idx].encodingName; |
| else encoding_name = NULL; |
| last_charset = charset; |
| } |
| if (encoding_name) |
| FUNCTION_RETURN_PTR(encoding_name,("%s",encoding_name)); |
| FUNCTION_RETURN_PTR(NULL,("No match")); |
| } |
| |
| |
| jint getCharset(const char *encoding) |
| { |
| FUNCTION_ENTRY("getCharset",("encoding=%s",encoding)); |
| for (int idx=0; idx<gJNICache.totalCharsets; idx++) |
| if (strcmp(encoding,gJNICache.charsetInfo[idx].encodingName)==0) |
| FUNCTION_RETURN_NUMERIC(gJNICache.charsetInfo[idx].charset,("%s",gJNICache.charsetInfo[idx].encodingName)); |
| FUNCTION_RETURN_NUMERIC(SQLCHARSETCODE_UNKNOWN,("Unknown")); |
| } |
| |
| BOOL useDefaultCharsetEncoding(JNIEnv *jenv, jobject jobj, jint charset, jstring iso88591Encoding) |
| { |
| FUNCTION_ENTRY("useDefaultCharsetEncoding", |
| ("jenv=0x%08x, jobj=0x%08x, charset=%s", |
| jenv, |
| jobj, |
| getCharsetEncoding(charset), |
| DebugJString(jenv,iso88591Encoding))); |
| bool useDefaultEnc = FALSE; |
| // Potential change: |
| // Add logic to use default encoding only if iso88591Encoding |
| // is set to the same value as the default charset or NOT ? |
| // |
| if (iso88591Encoding) |
| useDefaultEnc = FALSE; |
| else if (charset==gJNICache.defaultCharset) |
| useDefaultEnc = TRUE; |
| else |
| { |
| for (int idx=0; idx<gJNICache.totalCharsets; idx++) |
| if (charset == gJNICache.charsetInfo[idx].charset) |
| useDefaultEnc = gJNICache.charsetInfo[idx].useDefaultEncoding; |
| } |
| FUNCTION_RETURN_NUMERIC(useDefaultEnc,(NULL)); |
| } |
| |
| |
| jboolean getSqlStmtType(unsigned char* sql) |
| { |
| char *p = new char[strlen((const char *)sql)+1]; |
| memset(p, '\0', strlen((const char *)sql)+1); |
| strncpy(p, (const char *)sql, strlen((const char *)sql)+1); |
| /* |
| jstring jstrSQL = gJEnv->NewStringUTF(p); |
| jboolean result = gJEnv->CallStaticBooleanMethod(gJNICache.SQLMXConnectionClass, gJNICache.getSqlStmtTypeMethodId, jstrSQL); |
| */ |
| jboolean result; |
| std::string s = p; |
| int x = (s.find_first_of("INSERT") || s.find_first_of("UPDATE") || s.find_first_of("DELETE")); |
| int y = (s.find_first_of("insert") || s.find_first_of("update") || s.find_first_of("delete")); |
| if(x == 0 || y == 0) |
| { |
| result = JNI_TRUE; |
| } |
| else |
| { |
| result = JNI_FALSE; |
| } |
| delete [] p; |
| p = NULL; |
| return result; |
| |
| } |