Github user Weixin-Xu commented on a diff in the pull request: https://github.com/apache/trafodion/pull/1310#discussion_r166211434 --- Diff: core/conn/unixodbc/odbc/odbcclient/unixcli/cli/ctosqlconv.cpp --- @@ -157,852 +157,982 @@ unsigned long ODBC::Ascii_To_Interval_Helper(char *source, unsigned long ODBC::ConvertCToSQL(SQLINTEGER ODBCAppVersion, - SQLSMALLINT CDataType, - SQLPOINTER srcDataPtr, - SQLINTEGER srcLength, - SQLSMALLINT ODBCDataType, - SQLSMALLINT SQLDataType, - SQLSMALLINT SQLDatetimeCode, - SQLPOINTER targetDataPtr, - SQLINTEGER targetLength, - SQLINTEGER targetPrecision, - SQLSMALLINT targetScale, - SQLSMALLINT targetUnsigned, - SQLINTEGER targetCharSet, - BOOL byteSwap, -// FPSQLDriverToDataSource fpSQLDriverToDataSource, -// DWORD translateOption, - ICUConverter* iconv, - UCHAR *errorMsg, - SWORD errorMsgMax, - SQLINTEGER EnvironmentType, - BOOL RWRSFormat, - SQLINTEGER datetimeIntervalPrecision) + SQLSMALLINT CDataType, + SQLPOINTER srcDataPtr, + SQLINTEGER srcLength, + SQLPOINTER targetDataPtr, + CDescRec *targetDescPtr, + BOOL byteSwap, +#ifdef unixcli + ICUConverter* iconv, +#else + FPSQLDriverToDataSource fpSQLDriverToDataSource, + DWORD translateOption, +#endif + UCHAR *errorMsg, + SWORD errorMsgMax, + SQLINTEGER EnvironmentType, + BOOL RWRSFormat, + SQLINTEGER datetimeIntervalPrecision) { - unsigned long retCode = SQL_SUCCESS; - SQLPOINTER DataPtr = NULL; - SQLPOINTER outDataPtr = targetDataPtr; - SQLINTEGER DataLen = DRVR_PENDING; - short Offset = 0; // Used for VARCHAR fields - SQLINTEGER OutLen = targetLength; - short targetType = 0; //for bignum datatype + unsigned long retCode = SQL_SUCCESS; + if(pdwGlobalTraceVariable && *pdwGlobalTraceVariable){ + TraceOut(TR_ODBC_DEBUG,"ConvertCToSQL(%d, %d, %#x, %d, %d, %d, %d, %#x, %d, %d, %d, %d, %d, %d, %#x, %d, %d, %d)", + ODBCAppVersion, + CDataType, + srcDataPtr, + srcLength, + targetDescPtr->m_ODBCDataType, + targetDescPtr->m_SQLDataType, + targetDescPtr->m_SQLDatetimeCode, + targetDataPtr, + targetDescPtr->m_SQLOctetLength, + targetDescPtr->m_ODBCPrecision, + targetDescPtr->m_ODBCScale, + targetDescPtr->m_SQLUnsigned, + targetDescPtr->m_SQLCharset, + byteSwap, + errorMsg, + errorMsgMax, + EnvironmentType, + RWRSFormat); + } + else + RESET_TRACE(); + if (CDataType == SQL_C_DEFAULT) + { + retCode = getCDefault(targetDescPtr->m_ODBCDataType, ODBCAppVersion, targetDescPtr->m_SQLCharset, CDataType); + if (retCode != SQL_SUCCESS) + return retCode; + } - int dec; - int sign; - int tempLen; - int tempLen1; - int temp; + if (errorMsg) + *errorMsg = '\0'; + + switch (targetDescPtr->m_ODBCDataType) + { + case SQL_VARCHAR: + case SQL_LONGVARCHAR: + case SQL_WVARCHAR: + case SQL_CHAR: + if( targetDescPtr->m_SQLDataType == SQLTYPECODE_BOOLEAN ) + { + retCode = convToSQLBool(srcDataPtr,srcLength, CDataType, targetDataPtr); + break; + } + case SQL_WCHAR: + retCode = ConvertToCharTypes(ODBCAppVersion, + CDataType, + srcDataPtr, + srcLength, + targetDescPtr, + iconv, + targetDataPtr, + errorMsg); + break; - short i; - short datetime_parts[8]; - char *tempPtr; - double dTmp; - double dTmp1; - double scaleOffset; - SCHAR tTmp; - UCHAR utTmp; - SSHORT sTmp; - USHORT usTmp; - SLONG_P lTmp; - ULONG_P ulTmp; - CHAR cTmpBuf[256]; - CHAR cTmpBuf2[256]; - CHAR cTmpBufInterval[256]; - CHAR cTmpFraction[10]; - __int64 tempVal64; - __int64 integralPart; - __int64 decimalPart; - __int64 tempScaleVal64; - unsigned __int64 integralMax; - unsigned __int64 decimalMax; - float fltTmp; - BOOL useDouble = TRUE; - BOOL negative = FALSE; - long decimalDigits; - long leadZeros; - SQLUINTEGER ulFraction; - SQLSMALLINT cTmpDataType; - - DATE_STRUCT *dateTmp; - TIME_STRUCT *timeTmp; - TIMESTAMP_STRUCT *timestampTmp; - SQL_INTERVAL_STRUCT *intervalTmp; - DATE_TYPES SQLDate; - TIME_TYPES SQLTime; - TIMESTAMP_TYPES SQLTimestamp; - DATE_TYPES *pSQLDate; - TIME_TYPES *pSQLTime; - TIMESTAMP_TYPES *pSQLTimestamp; - SQLINTEGER translateLength; - SQLSMALLINT tODBCDataType; - BOOL signedInteger = FALSE; - BOOL unsignedInteger = FALSE; - BOOL dataTruncatedWarning = FALSE; - int AdjustedLength = 0; - char srcDataLocale[256]; - - if(pdwGlobalTraceVariable && *pdwGlobalTraceVariable){ - TraceOut(TR_ODBC_DEBUG,"ConvertCToSQL(%d, %d, %#x, %d, %d, %d, %d, %#x, %d, %d, %d, %d, %d, %d, %#x, %d, %d, %d)", - ODBCAppVersion, - CDataType, - srcDataPtr, - srcLength, - ODBCDataType, - SQLDataType, - SQLDatetimeCode, - targetDataPtr, - targetLength, - targetPrecision, - targetScale, - targetUnsigned, - targetCharSet, - byteSwap, - errorMsg, - errorMsgMax, - EnvironmentType, - RWRSFormat); - } - else - RESET_TRACE(); -/* -1. Because MS programs do not support BIGINT type, the server has to convert it to NUMERIC: - ODBCDataType = SQL_NUMERIC; - ODBCPrecision = 19; - SignType = TRUE; - Before conversion we have to change it back to: - ODBCDataType = SQL_BIGINT; - -2. Because ODBC does not support unsigned types for SMALLINT and INTEGER, - the server has to convert it to: - a)SQLTYPECODE_SMALLINT_UNSIGNED: - ODBCPrecision = 10; - ODBCDataType = SQL_INTEGER; - SignType = TRUE; - b)SQLTYPECODE_INTEGER_UNSIGNED: - ODBCPrecision = 19; - ODBCDataType = SQL_NUMERIC; - SignType = TRUE; - - Before conversion we have to change it back to datatype, precision and sign described by SQL: - a) - ODBCPrecision = 5; - ODBCDataType = SQL_SMALLINT; - SignType = FALSE; - b) - ODBCPrecision = 10; - ODBCDataType = SQL_INTEGER; - SignType = FALSE; -*/ - tODBCDataType = ODBCDataType; - if (ODBCDataType == SQL_NUMERIC && SQLDataType == SQLTYPECODE_LARGEINT && - targetPrecision == 19 && targetScale==0) - { - ODBCDataType = SQL_BIGINT; - } + case SQL_TINYINT: + case SQL_SMALLINT: + case SQL_INTEGER: + case SQL_FLOAT: + case SQL_REAL: + case SQL_DOUBLE: + case SQL_DECIMAL: + retCode = ConvertToNumberSimple(CDataType, + srcDataPtr, + srcLength, + targetDescPtr, + iconv, + targetDataPtr, + errorMsg); + break; - if (ODBCDataType == SQL_INTEGER && SQLDataType == SQLTYPECODE_SMALLINT_UNSIGNED && - targetPrecision == 10 && targetScale==0) - { - targetPrecision = 5; - ODBCDataType = SQL_SMALLINT; - targetUnsigned = true; - } + case SQL_BIGINT: + retCode = ConvertToBigint(ODBCAppVersion, + CDataType, + srcDataPtr, + srcLength, + targetDescPtr, + iconv, + targetDataPtr, + errorMsg); + break; - if (ODBCDataType == SQL_NUMERIC && SQLDataType == SQLTYPECODE_INTEGER_UNSIGNED && - targetPrecision == 19 && targetScale==0) - { - targetPrecision = 10; - ODBCDataType = SQL_INTEGER; - targetUnsigned = true; - } + case SQL_NUMERIC: + retCode = ConvertToNumeric(ODBCAppVersion, + CDataType, + srcDataPtr, + srcLength, + targetDescPtr, + iconv, + targetDataPtr, + errorMsg); + break; - if (ODBCDataType == SQL_BIGINT && SQLDataType == SQLTYPECODE_INTEGER_UNSIGNED && - targetPrecision == 19 && targetScale==0) - { - targetPrecision = 10; - ODBCDataType = SQL_INTEGER; - targetUnsigned = true; - } + case SQL_DATE: + case SQL_TYPE_DATE: + retCode = ConvertToDateType(ODBCAppVersion, + CDataType, + srcDataPtr, + srcLength, + targetDescPtr, + iconv, + targetDataPtr, + RWRSFormat, + errorMsg); + break; - if (CDataType == SQL_C_DEFAULT) - { - getCDefault(tODBCDataType, ODBCAppVersion, targetCharSet, CDataType); - if (ODBCAppVersion >= 3 && targetUnsigned) - { - switch(CDataType) - { - case SQL_C_SHORT: - case SQL_C_SSHORT: - CDataType = SQL_C_USHORT; - break; - case SQL_C_TINYINT: - case SQL_C_STINYINT: - CDataType = SQL_C_UTINYINT; - break; - case SQL_C_LONG: - case SQL_C_SLONG: - CDataType = SQL_C_ULONG; - break; - } - } - } + case SQL_TIME: + case SQL_TYPE_TIME: + retCode = ConvertToTimeType(ODBCAppVersion, + CDataType, + srcDataPtr, + srcLength, + targetDescPtr, + iconv, + targetDataPtr, + RWRSFormat, + errorMsg); + break; -//-------------------------------------------------------------------------------------- + case SQL_TIMESTAMP: + case SQL_TYPE_TIMESTAMP: + retCode = ConvertToTimeStampType(ODBCAppVersion, + CDataType, + srcDataPtr, + srcLength, + targetDescPtr, + iconv, + targetDataPtr, + RWRSFormat, + errorMsg); + break; - if (errorMsg) - *errorMsg = '\0'; - //if (targetPrecision < 19) - if( !(((SQLDataType == SQLTYPECODE_NUMERIC) && (targetPrecision > 18)) || - ((SQLDataType == SQLTYPECODE_NUMERIC_UNSIGNED) && (targetPrecision > 9)))) - getMaxNum(targetPrecision, targetScale, integralMax, decimalMax); + case SQL_INTERVAL_MONTH: + case SQL_INTERVAL_YEAR: + case SQL_INTERVAL_YEAR_TO_MONTH: + case SQL_INTERVAL_DAY: + case SQL_INTERVAL_HOUR: + case SQL_INTERVAL_MINUTE: + case SQL_INTERVAL_SECOND: + case SQL_INTERVAL_DAY_TO_HOUR: + case SQL_INTERVAL_DAY_TO_MINUTE: + case SQL_INTERVAL_DAY_TO_SECOND: + case SQL_INTERVAL_HOUR_TO_MINUTE: + case SQL_INTERVAL_HOUR_TO_SECOND: + case SQL_INTERVAL_MINUTE_TO_SECOND: + retCode = ConvertToTimeIntervalType(ODBCAppVersion, + CDataType, + srcDataPtr, + srcLength, + targetDescPtr, + iconv, + targetDataPtr, + RWRSFormat, + errorMsg, + datetimeIntervalPrecision); + break; - switch (ODBCDataType) - { - case SQL_VARCHAR: - case SQL_LONGVARCHAR: - case SQL_WVARCHAR: - { - if(targetPrecision > SHRT_MAX) - { - Offset = sizeof(UINT); - } - else - { - Offset = sizeof(USHORT); - } - } - case SQL_CHAR: - if( SQLDataType == SQLTYPECODE_BOOLEAN ) + default: + return IDS_07_006; + } + + return retCode; +} + +unsigned long ODBC::convToSQLBool(SQLPOINTER srcDataPtr,SQLINTEGER srcLength, SQLSMALLINT CDataType, SQLPOINTER targetDataPtr) +{ + + CHAR cTmpBuf[TMPLEN] = {0}; + double dTmp = 0; + char temptarget = 0; + unsigned long retCode = SQL_SUCCESS; + errno = 0; + + switch (CDataType) + { + case SQL_C_CHAR: + case SQL_C_WCHAR: + temptarget = strtol((char*)srcDataPtr,NULL,10); + if (errno == ERANGE) + return IDS_22_003; + break; + + case SQL_C_TINYINT: + case SQL_C_STINYINT: + temptarget = *(SCHAR *)srcDataPtr; + break; + + case SQL_C_BIT: + case SQL_C_UTINYINT: + temptarget = *(UCHAR *)srcDataPtr; + break; + + case SQL_C_SHORT: + case SQL_C_SSHORT: + temptarget = *(SSHORT *)srcDataPtr; + break; + + case SQL_C_USHORT: + temptarget = *(USHORT *)srcDataPtr; + break; + + case SQL_C_LONG: + case SQL_C_SLONG: + temptarget = *(SLONG_P *)srcDataPtr; + break; + case SQL_C_ULONG: + temptarget = *(ULONG_P *)srcDataPtr; + break; + + case SQL_C_SBIGINT: + temptarget = *(__int64 *)srcDataPtr; + break; + + case SQL_C_UBIGINT: + temptarget = *(unsigned __int64 *)srcDataPtr; + break; + + case SQL_C_NUMERIC: + retCode = ConvertCNumericToChar((SQL_NUMERIC_STRUCT*)srcDataPtr, cTmpBuf); + if (retCode != SQL_SUCCESS) + return retCode; + retCode = ConvertCharToNumeric((char*)cTmpBuf, srcLength, dTmp); + if (retCode != SQL_SUCCESS) + return retCode; + temptarget = dTmp; + break; + + default: + return IDS_07_006; + } + + if (temptarget < 0) + return IDS_22_003_02; + if (temptarget > 1) + return IDS_22_003; + + memcpy(targetDataPtr, &temptarget, sizeof(SCHAR)); + + return SQL_SUCCESS; +} + + + +unsigned long ODBC::MemcpyToNumeric(SQLPOINTER DataPtr, + SQLINTEGER & DataLen, + CDescRec* targetDescPtr, + SQLSMALLINT CDataType, + BOOL useDouble, + double dTmp, + BOOL negative, + __int64 decimalPart, + __int64 integralPart, + long leadZeros, + ICUConverter* iconv, + SQLPOINTER & outDataPtr, + unsigned long retTmp + ) +{ + + SQLSMALLINT targetUnsigned = targetDescPtr->m_SQLUnsigned; + SQLSMALLINT targetScale = targetDescPtr->m_ODBCScale; + SQLSMALLINT SQLDataType = targetDescPtr->m_SQLDataType; + SQLINTEGER targetPrecision = targetDescPtr->m_ODBCPrecision; + double dTmp1 = 0; + double scaleOffset = 0; + CHAR tTmp = 0; + USHORT usTmp = 0; + UCHAR utTmp = 0; + SHORT sTmp = 0; + ULONG_P ulTmp = 0; + SLONG_P lTmp = 0; + __int64 tempVal64 = 0; + __int64 tempScaleVal64 = 0; + unsigned __int64 uVal64 = 0; + short i = 0; + long decimalDigits = 0; + unsigned long retCode = retTmp; + + if (DataPtr == NULL) + { + if (useDouble) { - switch (CDataType) + if( targetUnsigned && ( dTmp < 0 || negative )) + return IDS_22_003_02; //negValue in unsigned column + + dTmp1 = pow((double)10, targetPrecision - targetScale + 1); + if (dTmp < -dTmp1 || dTmp > dTmp1) + return IDS_22_003; + scaleOffset = pow(10, targetScale); // This value always multplied to srcValue + // since SQL stores it as a implied decimal point + // 1.0 for NUMERIC (4,2) value is stored as 100 + dTmp *= scaleOffset; + switch (SQLDataType) + { + case SQLTYPECODE_TINYINT_UNSIGNED: + utTmp = (UCHAR)dTmp; + DataPtr = &utTmp; + DataLen = sizeof(UCHAR); + break; + case SQLTYPECODE_TINYINT: + tTmp = (SCHAR)dTmp; + DataPtr = &tTmp; + DataLen = sizeof(SCHAR); + break; + + case SQLTYPECODE_SMALLINT_UNSIGNED: + usTmp = (USHORT)dTmp; + DataPtr = &usTmp; + DataLen = sizeof(USHORT); + break; + case SQLTYPECODE_SMALLINT: + sTmp = (SHORT)dTmp; + DataPtr = &sTmp; + DataLen = sizeof(SHORT); + break; + + case SQLTYPECODE_INTEGER_UNSIGNED: + ulTmp = (ULONG_P)dTmp; + DataPtr = &ulTmp; + DataLen = sizeof(ULONG_P); + break; + case SQLTYPECODE_INTEGER: + lTmp = (LONG)dTmp; + DataPtr = &lTmp; + DataLen = sizeof(LONG); + break; + + case SQLTYPECODE_LARGEINT_UNSIGNED: + tempVal64 = (unsigned __int64)dTmp; + DataPtr = &tempVal64; + DataLen = sizeof(unsigned __int64); + break; + case SQLTYPECODE_LARGEINT: + tempVal64 = (__int64)dTmp; + DataPtr = &tempVal64; + DataLen = sizeof(__int64); + break; + + default: + return IDS_07_006; + } + } + else + { + if( targetUnsigned && negative ) + return IDS_22_003_02; //negValue in unsigned column + + if (targetScale) + { + for (i = 0,tempVal64 = 1; i < targetScale ; i++) + tempVal64 *= 10; + tempVal64 = tempVal64 * integralPart; + decimalDigits = 0; + if (decimalPart > 0) + decimalDigits = getDigitCount(decimalPart); + scaleOffset = 0; + if (leadZeros < targetScale) + scaleOffset = targetScale - decimalDigits - leadZeros; + if (scaleOffset < 0) + { + //NUMERIC_VALUE_OUT_OF_RANGE_ERROR + return IDS_22_003; + } + + for (i =0, tempScaleVal64 = decimalPart ; i < scaleOffset ; i++) + tempScaleVal64 *= 10; + tempVal64 += tempScaleVal64; + } + else + { + //NUMERIC_DATA_TRUNCATED_ERROR + if (decimalPart != 0) + retCode = IDS_01_S07; + tempVal64 = integralPart; + } + if (negative) + tempVal64 = -tempVal64; + + switch( SQLDataType ) { + case SQLTYPECODE_TINYINT_UNSIGNED: + if (tempVal64 < 0) + return IDS_22_003_02; + if ((UCHAR)tempVal64 > UCHAR_MAX) + return IDS_22_003; + utTmp = (UCHAR)tempVal64; + if (tempVal64 != utTmp) + retCode = IDS_01_S07; + DataPtr = &utTmp; + DataLen = sizeof(UCHAR); + break; + case SQLTYPECODE_TINYINT: + if (tempVal64 < CHAR_MIN || tempVal64 > CHAR_MAX) + return IDS_22_003; + tTmp = (SCHAR)tempVal64; + if (tempVal64 != tTmp) + retCode = IDS_01_S07; + DataPtr = &tTmp; + DataLen = sizeof(SCHAR); + break; + + case SQLTYPECODE_SMALLINT_UNSIGNED: + if (tempVal64 < 0) + return IDS_22_003_02; + if ((USHORT)tempVal64 > USHRT_MAX) + return IDS_22_003; + usTmp = (USHORT)tempVal64; + if (tempVal64 != usTmp) + retCode = IDS_01_S07; + DataPtr = &usTmp; + DataLen = sizeof(USHORT); + break; + case SQLTYPECODE_SMALLINT: + if (tempVal64 < SHRT_MIN || tempVal64 > SHRT_MAX) + return IDS_22_003; + sTmp = (SHORT)tempVal64; + if (tempVal64 != sTmp) + retCode = IDS_01_S07; + DataPtr = &sTmp; + DataLen = sizeof(SHORT); + break; + + case SQLTYPECODE_INTEGER_UNSIGNED: + // solution 10-080804-4996 + // for 64 bit Solaris/AIX (with XlC cplr), + // tempVal64 is a signed LONG LONG, + // ULONG_MAX is unsigned LONG of 'FFFFFFF....', + // somehow it will evaluate tempVal64 GT ULONG_MAX + // so cast the tempVal64 to (ULONG) + if (tempVal64 < 0) + return IDS_22_003_02; + if ((ULONG_P)tempVal64 > ULONG_MAX) + return IDS_22_003; + ulTmp = (ULONG_P)tempVal64; + if (tempVal64 != ulTmp) + retCode = IDS_01_S07; + DataPtr = &ulTmp; + DataLen = sizeof(ULONG_P); + break; + case SQLTYPECODE_INTEGER: + if (tempVal64 < LONG_MIN || tempVal64 > LONG_MAX) + return IDS_22_003; + lTmp = (LONG)tempVal64; + if (tempVal64 != lTmp) + retCode = IDS_01_S07; + DataPtr = &lTmp; + DataLen = sizeof(LONG); + break; + + case SQLTYPECODE_LARGEINT_UNSIGNED: + if(tempVal64 < 0) + return IDS_22_003_02; + if((unsigned __int64)tempVal64 > ULLONG_MAX) + return IDS_22_003; + uVal64 = (unsigned __int64)tempVal64; + if(tempVal64 != uVal64) + retCode = IDS_01_S07; + DataPtr = &uVal64; + DataLen = sizeof(unsigned __int64); + break; + case SQLTYPECODE_LARGEINT: + DataPtr = &tempVal64; + DataLen = sizeof(__int64); + break; + + default: + return IDS_07_006; + break; + } + + } + } + + memcpy(outDataPtr, DataPtr, DataLen); + + return retCode; +} + +unsigned long ODBC::ConvertToNumeric(SQLINTEGER ODBCAppVersion, + SQLSMALLINT CDataType, + SQLPOINTER srcDataPtr, + SQLINTEGER srcLength, + CDescRec* targetDescPtr, + ICUConverter* iconv, + SQLPOINTER targetDataPtr, + UCHAR *errorMsg) +{ + SQLSMALLINT ODBCDataType = targetDescPtr->m_ODBCDataType; + SQLSMALLINT SQLDataType = targetDescPtr->m_SQLDataType; + SQLSMALLINT targetScale = targetDescPtr->m_ODBCScale; + SQLSMALLINT targetUnsigned = targetDescPtr->m_SQLUnsigned; + SQLINTEGER targetPrecision = targetDescPtr->m_ODBCPrecision; + SQLINTEGER targetCharSet = targetDescPtr->m_SQLCharset; + SQLINTEGER translateLength = 0; + SQLINTEGER targetLength = targetDescPtr->m_SQLOctetLength; + SQL_INTERVAL_STRUCT *intervalTmp = NULL; + char srcDataLocale[CHARTMPLEN] = {0}; + int tempLen = 0; + int numberLen = 0; + CHAR cTmpBuf[CHARTMPLEN] = {0}; + CHAR cTmpBuf2[CHARTMPLEN] = {0}; + BOOL dataTruncatedWarning = FALSE; + unsigned long retCode = SQL_SUCCESS; + double dTmp = 0; + __int64 integralPart = 0; + __int64 decimalPart = 0; + SQLINTEGER DataLen = DRVR_PENDING; + SQLPOINTER DataPtr = NULL; + BOOL useDouble = TRUE; + long leadZeros = 0; + unsigned __int64 integralMax = 0; + unsigned __int64 decimalMax = 0; + BOOL negative = FALSE; + long decimalDigits = 0; + + + if(SQLDataType == SQLTYPECODE_NUMERIC || SQLDataType == SQLTYPECODE_NUMERIC_UNSIGNED)//for bignum support + { //Bignum + switch (CDataType) + { + case SQL_C_DEFAULT: + if (ODBCAppVersion >= SQL_OV_ODBC3) + { + + } // Want it fall thru and treat it like SQL_C_CHAR case SQL_C_WCHAR: if (iconv->isAppUTF16()) { if (srcLength != SQL_NTS) srcLength = srcLength/2; + // translate from UTF16 if (iconv->WCharToUTF8((UChar*)srcDataPtr, srcLength, srcDataLocale, sizeof(srcDataLocale), (int*)&translateLength, (char*)errorMsg) != SQL_SUCCESS) return IDS_193_DRVTODS_ERROR; srcDataPtr = srcDataLocale; srcLength = translateLength; } + case SQL_C_BINARY: case SQL_C_CHAR: - retCode = ConvertCharToNumeric(srcDataPtr, srcLength, dTmp); - if (retCode != SQL_SUCCESS) - return retCode; + if (srcLength == SQL_NTS) + tempLen = strlen((const char *)srcDataPtr); + else + tempLen = srcLength; + if (tempLen > CHARTMPLEN - 1) + strncpy(cTmpBuf, (char *)srcDataPtr, CHARTMPLEN - 1); --- End diff -- Do you mean that tempLen should be set 0 after use?
---