| /********************************************************************** |
| // @@@ 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 @@@ |
| ********************************************************************/ |
| /************************************************************************** |
| **************************************************************************/ |
| // |
| // |
| #include "ctosqlconv.h" |
| #include <stdio.h> |
| #include <float.h> |
| #include <limits.h> |
| #include <time.h> |
| #include <errno.h> |
| #include "sqlcli.h" |
| #include "DrvrSrvr.h" |
| #ifndef unixcli |
| #include "tdm_odbcdrvmsg.h" |
| #endif |
| |
| #include "drvrglobal.h" |
| #include "nskieee.h" |
| #include "diagfunctions.h" |
| #include "csconvert.h" |
| |
| extern short convDoItMxcs(char * source, |
| long sourceLen, |
| short sourceType, |
| long sourcePrecision, |
| long sourceScale, |
| char * target, |
| long targetLen, |
| short targetType, |
| long targetPrecision, |
| long targetScale, |
| long flags, |
| BOOL *truncation); |
| using namespace ODBC; |
| |
| unsigned long ODBC::Ascii_To_Bignum_Helper(char *source, |
| long sourceLen, |
| char *target, |
| long targetLength, |
| long targetPrecision, |
| long targetScale, |
| SQLSMALLINT SQLDataType, |
| BOOL *truncation) |
| |
| { |
| short targetType; |
| SQLRETURN retCode; |
| |
| if (SQLDataType == SQLTYPECODE_NUMERIC_UNSIGNED) |
| targetType = BIGNUM_UNSIGNED; |
| else |
| targetType = BIGNUM_SIGNED; |
| |
| retCode = convDoItMxcs(source,sourceLen, 0, 0, 0, (char*)target, targetLength, |
| targetType, targetPrecision, targetScale, 0, truncation); |
| |
| if (retCode != 0) |
| return IDS_22_003; |
| |
| |
| return SQL_SUCCESS; |
| |
| }; // Ascii_To_Bignum_Helper() |
| |
| unsigned long ODBC::Ascii_To_Interval_Helper(char *source, |
| long sourceLen, |
| char *target, |
| long targetLength, |
| long targetPrecision, |
| long targetScale, |
| SQLSMALLINT SQLDataType, |
| BOOL *truncation) |
| |
| { |
| short targetType; |
| SQLRETURN retCode; |
| |
| switch(SQLDataType) |
| { |
| case SQLINTCODE_YEAR: |
| targetType = REC_INT_YEAR; |
| break; |
| case SQLINTCODE_MONTH: |
| targetType = REC_INT_MONTH; |
| break; |
| case SQLINTCODE_DAY: |
| targetType = REC_INT_DAY; |
| break; |
| case SQLINTCODE_HOUR: |
| targetType = REC_INT_HOUR; |
| break; |
| case SQLINTCODE_MINUTE: |
| targetType = REC_INT_MINUTE; |
| break; |
| case SQLINTCODE_SECOND: |
| targetType = REC_INT_SECOND; |
| break; |
| case SQLINTCODE_YEAR_MONTH: |
| targetType = REC_INT_YEAR_MONTH; |
| break; |
| case SQLINTCODE_DAY_HOUR: |
| targetType = REC_INT_DAY_HOUR; |
| break; |
| case SQLINTCODE_DAY_MINUTE: |
| targetType = REC_INT_DAY_MINUTE; |
| break; |
| case SQLINTCODE_DAY_SECOND: |
| targetType = REC_INT_DAY_SECOND; |
| break; |
| case SQLINTCODE_HOUR_MINUTE: |
| targetType = REC_INT_HOUR_MINUTE; |
| break; |
| case SQLINTCODE_HOUR_SECOND: |
| targetType = REC_INT_HOUR_SECOND; |
| break; |
| case SQLINTCODE_MINUTE_SECOND: |
| targetType = REC_INT_MINUTE_SECOND; |
| break; |
| default: |
| return IDS_22_003; |
| break; |
| } |
| |
| retCode = convDoItMxcs(source,sourceLen, 0, 0, 0, (char*)target, targetLength, |
| targetType, targetPrecision, targetScale, 0, truncation); |
| |
| if (retCode != 0) |
| return IDS_22_003; |
| |
| |
| return SQL_SUCCESS; |
| |
| }; // Ascii_To_Interval_Helper() |
| |
| |
| |
| 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) |
| { |
| |
| 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 |
| |
| |
| int dec; |
| int sign; |
| int tempLen; |
| int tempLen1; |
| int temp; |
| |
| 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; |
| } |
| |
| if (ODBCDataType == SQL_INTEGER && SQLDataType == SQLTYPECODE_SMALLINT_UNSIGNED && |
| targetPrecision == 10 && targetScale==0) |
| { |
| targetPrecision = 5; |
| ODBCDataType = SQL_SMALLINT; |
| targetUnsigned = true; |
| } |
| |
| if (ODBCDataType == SQL_NUMERIC && SQLDataType == SQLTYPECODE_INTEGER_UNSIGNED && |
| targetPrecision == 19 && targetScale==0) |
| { |
| targetPrecision = 10; |
| ODBCDataType = SQL_INTEGER; |
| targetUnsigned = true; |
| } |
| |
| if (ODBCDataType == SQL_BIGINT && SQLDataType == SQLTYPECODE_INTEGER_UNSIGNED && |
| targetPrecision == 19 && targetScale==0) |
| { |
| targetPrecision = 10; |
| ODBCDataType = SQL_INTEGER; |
| targetUnsigned = true; |
| } |
| |
| 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; |
| } |
| } |
| } |
| |
| //-------------------------------------------------------------------------------------- |
| |
| if (errorMsg) |
| *errorMsg = '\0'; |
| //if (targetPrecision < 19) |
| if(((SQLDataType == SQLTYPECODE_NUMERIC) && (targetPrecision <= 18)) || |
| ((SQLDataType == SQLTYPECODE_NUMERIC_UNSIGNED) && (targetPrecision <= 9))) |
| getMaxNum(targetPrecision, targetScale, integralMax, decimalMax); |
| |
| 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 ) |
| { |
| switch (CDataType) |
| { |
| case SQL_C_WCHAR: |
| if (iconv->isAppUTF16()) |
| { |
| if (srcLength != SQL_NTS) |
| srcLength = srcLength/2; |
| 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_CHAR: |
| retCode = ConvertCharToNumeric(srcDataPtr, srcLength, dTmp); |
| if (retCode != SQL_SUCCESS) |
| return retCode; |
| break; |
| case SQL_C_SHORT: |
| case SQL_C_SSHORT: |
| dTmp = *(SSHORT *)srcDataPtr; |
| break; |
| case SQL_C_USHORT: |
| dTmp = *(USHORT *)srcDataPtr; |
| break; |
| case SQL_C_TINYINT: |
| case SQL_C_STINYINT: |
| dTmp = *(SCHAR *)srcDataPtr; |
| break; |
| case SQL_C_UTINYINT: |
| case SQL_C_BIT: |
| dTmp = *(UCHAR *)srcDataPtr; |
| break; |
| case SQL_C_SLONG: |
| case SQL_C_LONG: |
| dTmp = *(SLONG_P *)srcDataPtr; |
| break; |
| case SQL_C_ULONG: |
| dTmp = *(ULONG_P *)srcDataPtr; |
| break; |
| case SQL_C_FLOAT: |
| dTmp = *(SFLOAT *)srcDataPtr; |
| break; |
| case SQL_C_DOUBLE: |
| dTmp = *(DOUBLE *)srcDataPtr; |
| break; |
| case SQL_C_BINARY: |
| DataPtr = srcDataPtr; |
| break; |
| case SQL_C_DEFAULT: |
| if (ODBCAppVersion >= SQL_OV_ODBC3) |
| DataPtr = srcDataPtr; |
| else |
| { |
| retCode = ConvertCharToNumeric(srcDataPtr, srcLength, dTmp); |
| if (retCode!= SQL_SUCCESS) |
| return retCode; |
| } |
| break; |
| case SQL_C_SBIGINT: |
| dTmp = *(__int64 *)srcDataPtr; |
| break; |
| case SQL_C_NUMERIC: |
| ConvertCNumericToChar((SQL_NUMERIC_STRUCT*)srcDataPtr, cTmpBuf); |
| srcLength = strlen(cTmpBuf); |
| retCode = ConvertCharToNumeric((char*)cTmpBuf, srcLength, dTmp); |
| if (retCode != SQL_SUCCESS) |
| return retCode; |
| break; |
| default: |
| return IDS_07_006; |
| } |
| if (DataPtr == NULL) |
| { |
| if(dTmp < 0) |
| return IDS_22_003_02; |
| if(dTmp > 1) |
| return IDS_22_003; |
| tTmp = (SCHAR)dTmp; |
| if(dTmp != tTmp) |
| retCode = IDS_01_S07; |
| DataPtr = &tTmp; |
| DataLen = sizeof(SCHAR); |
| } |
| break; |
| } |
| case SQL_WCHAR: |
| switch (CDataType) |
| { |
| case SQL_C_CHAR: |
| case SQL_C_DEFAULT: |
| case SQL_C_BINARY: |
| case SQL_C_WCHAR: |
| { |
| if (srcLength == SQL_NTS) |
| { |
| if ((CDataType == SQL_C_WCHAR) && iconv->isAppUTF16()) |
| DataLen = u_strlen((const UChar *)srcDataPtr); |
| else |
| DataLen = strlen((const char *)srcDataPtr); |
| } |
| else |
| { |
| if ((CDataType == SQL_C_WCHAR) && iconv->isAppUTF16()) |
| DataLen = srcLength/2; |
| else |
| DataLen = srcLength; |
| } |
| if (CDataType == SQL_C_BINARY && DataLen > targetLength-Offset-1) |
| { |
| DataLen = targetLength-Offset-1; |
| return IDS_22_001; |
| } |
| DataPtr = srcDataPtr; |
| } |
| break; |
| case SQL_C_SHORT: |
| case SQL_C_SSHORT: |
| sTmp = *(SSHORT *)srcDataPtr; |
| _ltoa(sTmp, cTmpBuf, 10); |
| break; |
| case SQL_C_USHORT: |
| usTmp = *(USHORT *)srcDataPtr; |
| _ultoa(usTmp, cTmpBuf, 10); |
| break; |
| case SQL_C_TINYINT: |
| case SQL_C_STINYINT: |
| sTmp = *(SCHAR *)srcDataPtr; |
| _ltoa(sTmp, cTmpBuf, 10); |
| break; |
| case SQL_C_UTINYINT: |
| case SQL_C_BIT: |
| usTmp = *(UCHAR *)srcDataPtr; |
| _ultoa(usTmp, cTmpBuf, 10); |
| break; |
| case SQL_C_SLONG: |
| case SQL_C_LONG: |
| lTmp = *(SLONG_P *)srcDataPtr; |
| _ltoa(lTmp, cTmpBuf, 10); |
| break; |
| case SQL_C_ULONG: |
| ulTmp = *(ULONG_P *)srcDataPtr; |
| _ultoa(ulTmp, cTmpBuf, 10); |
| break; |
| case SQL_C_FLOAT: |
| dTmp = *(float *)srcDataPtr; |
| // _gcvt(dTmp, FLT_DIG, cTmpBuf); |
| if (!double_to_char (dTmp, FLT_DIG, cTmpBuf, sizeof(cTmpBuf))) |
| return IDS_22_001; |
| break; |
| case SQL_C_DOUBLE: |
| dTmp = *(double *)srcDataPtr; |
| // _gcvt(dTmp, DBL_DIG, cTmpBuf); |
| if (!double_to_char (dTmp, DBL_DIG, cTmpBuf, sizeof(cTmpBuf))) |
| return IDS_22_001; |
| break; |
| case SQL_C_DATE: |
| case SQL_C_TYPE_DATE: |
| dateTmp = (DATE_STRUCT *)srcDataPtr; |
| |
| for (i = 0 ; i < 8 ; i++) |
| datetime_parts[i] = 0; |
| datetime_parts[0] = dateTmp->year; |
| datetime_parts[1] = dateTmp->month; |
| datetime_parts[2] = dateTmp->day; |
| if (!checkDatetimeValue(datetime_parts)) |
| return IDS_22_008; |
| |
| sprintf(cTmpBuf, "%04d-%02d-%02d", dateTmp->year, dateTmp->month, dateTmp->day); |
| break; |
| case SQL_C_TIME: |
| case SQL_C_TYPE_TIME: |
| timeTmp = (TIME_STRUCT *)srcDataPtr; |
| |
| for (i = 0 ; i < 8 ; i++) |
| datetime_parts[i] = 0; |
| datetime_parts[0] = 1; |
| datetime_parts[1] = 1; |
| datetime_parts[2] = 1; |
| datetime_parts[3] = timeTmp->hour; |
| datetime_parts[4] = timeTmp->minute; |
| datetime_parts[5] = timeTmp->second; |
| if (!checkDatetimeValue(datetime_parts)) |
| return IDS_22_008; |
| |
| sprintf(cTmpBuf, "%02d:%02d:%02d", timeTmp->hour, timeTmp->minute, timeTmp->second); |
| break; |
| case SQL_C_TIMESTAMP: |
| case SQL_C_TYPE_TIMESTAMP: |
| timestampTmp = (TIMESTAMP_STRUCT *)srcDataPtr; |
| // SQL/MX fraction precision is max 6 digits but ODBC accepts max precision 9 digits |
| // conversion from nano to micro fraction of second |
| ulFraction = (UDWORD_P)timestampTmp->fraction; |
| ulFraction /= 1000; |
| |
| for (i = 0 ; i < 8 ; i++) |
| datetime_parts[i] = 0; |
| datetime_parts[0] = timestampTmp->year; |
| datetime_parts[1] = timestampTmp->month; |
| datetime_parts[2] = timestampTmp->day; |
| datetime_parts[3] = timestampTmp->hour; |
| datetime_parts[4] = timestampTmp->minute; |
| datetime_parts[5] = timestampTmp->second; |
| datetime_parts[6] = (short)(ulFraction/1000); |
| datetime_parts[7] = (short)(ulFraction%1000); |
| if (!checkDatetimeValue(datetime_parts)) |
| return IDS_22_008; |
| |
| sprintf(cTmpBuf, "%04d-%02d-%02d %02d:%02d:%02d.%06u", |
| timestampTmp->year, timestampTmp->month, |
| timestampTmp->day, timestampTmp->hour, |
| timestampTmp->minute, timestampTmp->second, |
| ulFraction); |
| |
| break; |
| case SQL_C_NUMERIC: |
| ConvertCNumericToChar((SQL_NUMERIC_STRUCT*)srcDataPtr, cTmpBuf); |
| break; |
| case SQL_C_SBIGINT: |
| #if !defined unixcli |
| sprintf(cTmpBuf, "%I64d", *(__int64*)srcDataPtr); |
| #elif defined MXHPUX || defined MXOSS || MXAIX || MXSUNSPARC || MXSUNSPARC |
| sprintf(cTmpBuf, "%lld", *(__int64*)srcDataPtr); |
| #else |
| sprintf(cTmpBuf, "%Ld", *(__int64*)srcDataPtr); |
| #endif |
| break; |
| case SQL_C_INTERVAL_MONTH: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.year_month.month); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.year_month.month); |
| break; |
| case SQL_C_INTERVAL_YEAR: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.year_month.year); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.year_month.year); |
| break; |
| case SQL_C_INTERVAL_YEAR_TO_MONTH: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld-%ld",intervalTmp->intval.year_month.year, intervalTmp->intval.year_month.month); |
| else |
| sprintf(cTmpBuf,"%ld-%ld",intervalTmp->intval.year_month.year, intervalTmp->intval.year_month.month); |
| break; |
| case SQL_C_INTERVAL_DAY: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.day); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.day); |
| break; |
| case SQL_C_INTERVAL_HOUR: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_C_INTERVAL_MINUTE: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_C_INTERVAL_SECOND: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"-%ld.%ld",intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| else |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"%ld.%ld",intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| break; |
| case SQL_C_INTERVAL_DAY_TO_HOUR: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld %ld",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"%ld %ld",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_C_INTERVAL_DAY_TO_MINUTE: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld %ld:%ld",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld %ld:%ld",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_C_INTERVAL_DAY_TO_SECOND: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"-%ld %ld:%ld:%ld",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"-%ld %ld:%ld:%ld.%ld",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| else |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"%ld %ld:%ld:%ld",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"%ld %ld:%ld:%ld.%ld",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| break; |
| case SQL_C_INTERVAL_HOUR_TO_MINUTE: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_C_INTERVAL_HOUR_TO_SECOND: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"-%ld:%ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"-%ld:%ld:%ld.%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| else |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"%ld:%ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"%ld:%ld:%ld.%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| break; |
| case SQL_C_INTERVAL_MINUTE_TO_SECOND: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"-%ld:%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"-%ld:%ld.%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| else |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"%ld:%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"%ld:%ld.%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| break; |
| default: |
| return IDS_07_006; |
| } |
| if (DataPtr == NULL) |
| { |
| DataPtr = cTmpBuf; |
| DataLen = strlen(cTmpBuf); |
| } |
| if (Offset != 0) |
| { |
| //#ifndef MXSUN |
| if(targetPrecision > SHRT_MAX){ |
| outDataPtr = (unsigned char *)targetDataPtr + sizeof(int); |
| } |
| else{ |
| outDataPtr = (unsigned char *)targetDataPtr + sizeof(USHORT); |
| } |
| //#else |
| // |
| // temp = DataLen; |
| // DataLen <<=16; |
| // memcpy(targetDataPtr, &DataLen, sizeof(SQLINTEGER)); |
| // DataLen = temp; |
| // outDataPtr = (unsigned char *)targetDataPtr + sizeof(USHORT); |
| //#endif |
| //outDataPtr = (unsigned char *)targetDataPtr + sizeof(USHORT); |
| } |
| if (targetCharSet == SQLCHARSETCODE_UCS2) |
| OutLen = targetLength - Offset -2 ; // Remove for Null Pointer; |
| else |
| OutLen = targetLength - Offset -1 ; // Remove for Null Pointer |
| break; |
| case SQL_REAL: |
| if(CDataType == SQL_C_NUMERIC){ |
| ConvertCNumericToChar((SQL_NUMERIC_STRUCT*)srcDataPtr, cTmpBuf); |
| srcLength = strlen(cTmpBuf); |
| if ((retCode = ConvertCharToNumeric(cTmpBuf, srcLength, dTmp)) != SQL_SUCCESS) |
| return retCode; |
| if (dTmp < -FLT_MAX || dTmp > FLT_MAX) |
| return IDS_22_003; |
| fltTmp = (SFLOAT)dTmp; |
| DataPtr = &fltTmp; |
| DataLen = sizeof(fltTmp); |
| break; |
| } |
| case SQL_TINYINT: |
| case SQL_SMALLINT: |
| case SQL_INTEGER: |
| case SQL_FLOAT: |
| case SQL_DOUBLE: |
| case SQL_DECIMAL: |
| switch (CDataType) |
| { |
| case SQL_C_INTERVAL_MONTH: |
| case SQL_C_INTERVAL_YEAR: |
| case SQL_C_INTERVAL_YEAR_TO_MONTH: |
| case SQL_C_INTERVAL_DAY: |
| case SQL_C_INTERVAL_HOUR: |
| case SQL_C_INTERVAL_MINUTE: |
| case SQL_C_INTERVAL_SECOND: |
| case SQL_C_INTERVAL_DAY_TO_HOUR: |
| case SQL_C_INTERVAL_DAY_TO_MINUTE: |
| case SQL_C_INTERVAL_DAY_TO_SECOND: |
| case SQL_C_INTERVAL_HOUR_TO_MINUTE: |
| case SQL_C_INTERVAL_HOUR_TO_SECOND: |
| case SQL_C_INTERVAL_MINUTE_TO_SECOND: |
| if(ODBCDataType == SQL_REAL || ODBCDataType == SQL_FLOAT ||ODBCDataType == SQL_DOUBLE) |
| return IDS_07_006; |
| default: |
| break; |
| } |
| signedInteger = FALSE; |
| unsignedInteger = FALSE; |
| switch (CDataType) |
| { |
| 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_CHAR: |
| if (ODBCDataType != SQL_DECIMAL) |
| { |
| if ((retCode = ConvertCharToNumeric(srcDataPtr, srcLength, dTmp)) != SQL_SUCCESS) |
| return retCode; |
| } |
| else // this is a patch should remove dTmp (double) and change it to tempVal64 (__int64) like in SQL_BIGINT. |
| { |
| if (srcLength == SQL_NTS) |
| tempLen = strlen((const char *)srcDataPtr); |
| else |
| tempLen = srcLength; |
| |
| if( tempLen > sizeof( cTmpBuf ) - 1) |
| return IDS_22_003; |
| strncpy(cTmpBuf,(char*)srcDataPtr, tempLen); |
| cTmpBuf[ tempLen ] = 0; |
| rTrim(cTmpBuf); |
| |
| if ((retCode = ConvertCharToInt64Num((char*)cTmpBuf, integralPart, |
| decimalPart, negative, leadZeros)) != 0) |
| { |
| // Return values -1 - Out of Range |
| // -2 - Illegal numeric value |
| if (retCode == -1) |
| return IDS_22_003; |
| if (retCode == -2) |
| return IDS_22_005; |
| } |
| if(negative && targetUnsigned) |
| return IDS_22_003_02; |
| if ((integralPart < 0) || (integralPart > integralMax)) |
| return IDS_22_003; |
| decimalDigits = 0; |
| if (decimalPart > 0) |
| decimalDigits = getDigitCount(decimalPart); |
| if ((decimalPart > decimalMax) || ((decimalDigits + leadZeros) > targetScale)) |
| { |
| retCode = IDS_01_S07; // Since SQL does not give truncation warning, we fake it |
| // sol 10-080603-3635 |
| // trim the decimalPart based one the scale |
| // the number of digits in the decimal portion needs to be adjusted if it contain |
| // leading zero(s) |
| decimalPart=decimalPart/pow((double)10, (int)(getDigitCount(decimalPart) + leadZeros - targetScale)); |
| } |
| useDouble = FALSE; |
| } |
| break; |
| case SQL_C_SHORT: |
| case SQL_C_SSHORT: |
| dTmp = *(SSHORT *)srcDataPtr; |
| signedInteger = TRUE; |
| break; |
| case SQL_C_USHORT: |
| dTmp = *(USHORT *)srcDataPtr; |
| unsignedInteger = TRUE; |
| break; |
| case SQL_C_TINYINT: |
| case SQL_C_STINYINT: |
| dTmp = *(SCHAR *)srcDataPtr; |
| signedInteger = TRUE; |
| break; |
| case SQL_C_UTINYINT: |
| case SQL_C_BIT: |
| dTmp = *(UCHAR *)srcDataPtr; |
| break; |
| case SQL_C_SLONG: |
| case SQL_C_LONG: |
| dTmp = *(SLONG_P *)srcDataPtr; |
| signedInteger = TRUE; |
| break; |
| case SQL_C_ULONG: |
| dTmp = *(ULONG_P *)srcDataPtr; |
| unsignedInteger = TRUE; |
| break; |
| case SQL_C_SBIGINT: |
| if (ODBCDataType != SQL_DECIMAL) |
| { |
| dTmp = *(__int64 *)srcDataPtr; |
| } |
| else // this is a patch should remove dTmp (double) and change it to tempVal64 (__int64) like in SQL_BIGINT. |
| { |
| leadZeros = 0; |
| decimalPart = 0; |
| integralPart = 0; |
| negative = FALSE; |
| integralPart = *(__int64 *)srcDataPtr; |
| if (integralPart < 0) |
| { |
| integralPart = -integralPart; |
| negative = TRUE; |
| } |
| useDouble = FALSE; |
| } |
| signedInteger = TRUE; |
| break; |
| case SQL_C_FLOAT: |
| dTmp = *(SFLOAT *)srcDataPtr; |
| break; |
| case SQL_C_DOUBLE: |
| dTmp = *(DOUBLE *)srcDataPtr; |
| break; |
| case SQL_C_BINARY: |
| DataPtr = srcDataPtr; |
| break; |
| case SQL_C_DEFAULT: |
| DataPtr = srcDataPtr; |
| break; |
| case SQL_C_NUMERIC: |
| ConvertCNumericToChar((SQL_NUMERIC_STRUCT*)srcDataPtr, cTmpBuf); |
| |
| if ((retCode = ConvertCharToInt64Num((char*)cTmpBuf, integralPart, |
| decimalPart, negative, leadZeros)) != 0) |
| { |
| // Return values -1 - Out of Range |
| // -2 - Illegal numeric value |
| |
| if (retCode == -1) |
| return IDS_22_003; |
| if (retCode == -2) |
| return IDS_22_005; |
| } |
| if(negative && targetUnsigned) |
| return IDS_22_003_02; |
| if ((integralPart < 0) || (integralPart > integralMax)) |
| return IDS_22_003; |
| decimalDigits = 0; |
| if (decimalPart > 0) |
| decimalDigits = getDigitCount(decimalPart); |
| if ((decimalPart > decimalMax) || ((decimalDigits + leadZeros) > targetScale)) |
| { |
| retCode = IDS_01_S07; |
| // sol 10-080603-3635 |
| // trim the decimalPart based one the scale |
| // the number of digits in the decimal portion needs to be adjusted if it contain |
| // leading zero(s) |
| decimalPart=decimalPart/pow((double)10, (int)(getDigitCount(decimalPart) + leadZeros - targetScale)); |
| } |
| useDouble = FALSE; |
| break; |
| case SQL_C_INTERVAL_MONTH: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| dTmp = -(intervalTmp->intval.year_month.month); |
| else |
| dTmp = intervalTmp->intval.year_month.month; |
| break; |
| case SQL_C_INTERVAL_YEAR: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| dTmp = -(intervalTmp->intval.year_month.year); |
| else |
| dTmp = intervalTmp->intval.year_month.year; |
| break; |
| case SQL_C_INTERVAL_DAY: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| dTmp = -(intervalTmp->intval.day_second.day); |
| else |
| dTmp = intervalTmp->intval.day_second.day; |
| break; |
| case SQL_C_INTERVAL_HOUR: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| dTmp = -(intervalTmp->intval.day_second.hour); |
| else |
| dTmp = intervalTmp->intval.day_second.hour; |
| break; |
| case SQL_C_INTERVAL_MINUTE: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| dTmp = -(intervalTmp->intval.day_second.minute); |
| else |
| dTmp = intervalTmp->intval.day_second.minute; |
| break; |
| default: |
| return IDS_07_006; |
| } |
| if (DataPtr == NULL) |
| { |
| if( useDouble ) |
| { |
| switch (ODBCDataType) |
| { |
| case SQL_TINYINT: |
| if(targetUnsigned) |
| { |
| if (dTmp < 0) |
| return IDS_22_003_02; //negValue in unsigned column |
| if(dTmp > UCHAR_MAX) |
| return IDS_22_003; |
| utTmp = (UCHAR)dTmp; |
| if(dTmp != utTmp) |
| retCode = IDS_01_S07; |
| DataPtr = &utTmp; |
| DataLen = sizeof(UCHAR); |
| } |
| else |
| { |
| if(unsignedInteger) |
| { |
| if(dTmp < 0 || dTmp > UCHAR_MAX) |
| return IDS_22_003; |
| tTmp = (SCHAR)dTmp; |
| } |
| else |
| { |
| if(dTmp < SCHAR_MIN || dTmp > SCHAR_MAX) |
| return IDS_22_003; |
| tTmp = (SCHAR)dTmp; |
| if (dTmp != tTmp) |
| retCode = IDS_01_S07; |
| } |
| DataPtr = &tTmp; |
| DataLen = sizeof(SCHAR); |
| } |
| break; |
| case SQL_SMALLINT: |
| if (targetUnsigned) |
| { |
| if ( dTmp < 0 ) |
| return IDS_22_003_02; //negValue in unsigned column |
| if (dTmp > USHRT_MAX) |
| return IDS_22_003; |
| usTmp = (USHORT)dTmp; |
| if (dTmp != usTmp) |
| retCode = IDS_01_S07; |
| DataPtr = &usTmp; |
| DataLen = sizeof(usTmp); |
| } |
| else |
| { |
| if (unsignedInteger) |
| { |
| if (dTmp < 0 || dTmp > USHRT_MAX) |
| return IDS_22_003; |
| sTmp = (SHORT)dTmp; |
| } |
| else |
| { |
| if (dTmp < SHRT_MIN || dTmp > SHRT_MAX) |
| return IDS_22_003; |
| sTmp = (SHORT)dTmp; |
| if (dTmp != sTmp) |
| retCode = IDS_01_S07; |
| } |
| DataPtr = &sTmp; |
| DataLen = sizeof(sTmp); |
| } |
| break; |
| case SQL_INTEGER: |
| if (targetUnsigned) |
| { |
| if (dTmp < 0) |
| return IDS_22_003_02;//negValue in unsigned col error |
| if (dTmp > UINT_MAX ) |
| return IDS_22_003; |
| ulTmp = (ULONG_P)dTmp; |
| if (dTmp != ulTmp) |
| retCode = IDS_01_S07; |
| DataPtr = &ulTmp; |
| DataLen = sizeof(ulTmp); |
| } |
| else |
| { |
| if (unsignedInteger) |
| { |
| if (dTmp < 0 || dTmp > UINT_MAX ) |
| return IDS_22_003; |
| lTmp = (LONG)dTmp; |
| } |
| else |
| { |
| if (dTmp < LONG_MIN || dTmp > INT_MAX) |
| return IDS_22_003; |
| lTmp = (LONG)dTmp; |
| if (dTmp != lTmp) |
| retCode = IDS_01_S07; |
| } |
| DataPtr = &lTmp; |
| DataLen = sizeof(lTmp); |
| } |
| break; |
| case SQL_REAL: |
| if (dTmp < -FLT_MAX || dTmp > FLT_MAX) |
| return IDS_22_003; |
| fltTmp = (SFLOAT)dTmp; |
| DataPtr = &fltTmp; |
| DataLen = sizeof(fltTmp); |
| break; |
| case SQL_DOUBLE: |
| case SQL_FLOAT: |
| DataPtr = &dTmp; |
| DataLen = sizeof(dTmp); |
| break; |
| case SQL_DECIMAL: |
| if (targetPrecision >= sizeof(cTmpBuf)) |
| return IDS_22_003; |
| #if defined MXHPUX || defined MXOSS || defined MXAIX || MXSUNSPARC || MXSUNSPARC |
| dTmp1 = pow((double)10,targetPrecision-targetScale+1); |
| #else |
| dTmp1 = pow(10,targetPrecision-targetScale+1); |
| #endif |
| if (targetUnsigned) |
| { |
| if ( dTmp < 0 ) |
| return IDS_22_003_02; //negValue in unsigned column |
| if (dTmp > dTmp1) |
| return IDS_22_003; |
| |
| tempPtr = _fcvt(dTmp, targetScale, &dec, &sign); |
| tempLen = strlen(tempPtr); |
| tempLen1 = (short)(targetPrecision-tempLen); |
| |
| if (tempLen1 < 0) |
| return IDS_22_003; |
| |
| memset((void *)cTmpBuf, '0', tempLen1); |
| strncpy((char *)(cTmpBuf+tempLen1), tempPtr, tempLen); |
| } |
| else |
| { |
| if (dTmp < -dTmp1 || dTmp > dTmp1) |
| return IDS_22_003; |
| |
| tempPtr = _fcvt(dTmp, targetScale, &dec, &sign); |
| tempLen = strlen(tempPtr); |
| tempLen1 = (short)(targetPrecision-tempLen); |
| |
| if (tempLen1 < 0) |
| return IDS_22_003; |
| |
| memset((void *)cTmpBuf, '0', tempLen1); |
| strncpy((char *)(cTmpBuf+tempLen1), tempPtr, tempLen); |
| if (sign) |
| *cTmpBuf = (UCHAR)(*cTmpBuf | (UCHAR)0x80); |
| } |
| DataPtr = cTmpBuf; |
| DataLen = targetPrecision; |
| break; |
| default: |
| return IDS_07_006; |
| } |
| } |
| else |
| { |
| 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 (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 < SCHAR_MIN || tempVal64 > SCHAR_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(sTmp); |
| break; |
| case SQLTYPECODE_INTEGER_UNSIGNED: |
| 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(ulTmp); |
| 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(lTmp); |
| break; |
| case SQLTYPECODE_IEEE_FLOAT: |
| if (tempVal64 < -FLT_MAX || tempVal64 > FLT_MAX) |
| return IDS_22_003; |
| fltTmp = (FLOAT)tempVal64; |
| if (tempVal64 != fltTmp) |
| retCode = IDS_01_S07; |
| DataPtr = &fltTmp; |
| DataLen = sizeof(fltTmp); |
| break; |
| case SQLTYPECODE_IEEE_DOUBLE: |
| if (tempVal64 < -DBL_MAX || tempVal64 > DBL_MAX) |
| return IDS_22_003; |
| dTmp = (DOUBLE)tempVal64; |
| if (tempVal64 != dTmp) |
| retCode = IDS_01_S07; |
| DataPtr = &dTmp; |
| DataLen = sizeof(dTmp); |
| break; |
| case SQLTYPECODE_DECIMAL_UNSIGNED: |
| case SQLTYPECODE_DECIMAL_LARGE_UNSIGNED: // Tandem extension |
| if(negative) |
| return IDS_22_003_02; |
| case SQLTYPECODE_DECIMAL: |
| case SQLTYPECODE_DECIMAL_LARGE: // Tandem extension |
| if(negative) |
| tempVal64 = -tempVal64; |
| #if defined MXHPUX || defined MXOSS || defined MXAIX || MXSUNSPARC || MXSUNSPARC |
| sprintf(cTmpBuf, "%0*lld", targetPrecision, tempVal64); |
| #elif defined unixcli |
| sprintf(cTmpBuf, "%0*Ld", targetPrecision, tempVal64); |
| #else |
| sprintf(cTmpBuf, "%0*I64d", targetPrecision, tempVal64); |
| #endif |
| if (negative) |
| *cTmpBuf = (UCHAR)(*cTmpBuf | (UCHAR)0x80); |
| DataPtr = cTmpBuf; |
| DataLen = strlen(cTmpBuf); |
| break; |
| case SQLTYPECODE_LARGEINT: |
| default: |
| DataPtr = &tempVal64; |
| DataLen = sizeof(tempVal64); |
| break; |
| } |
| } |
| } |
| else |
| { |
| switch (ODBCDataType) |
| { |
| case SQL_TINYINT: |
| DataLen = sizeof(SCHAR); |
| break; |
| case SQL_SMALLINT: |
| DataLen = sizeof(SHORT); |
| break; |
| case SQL_INTEGER: |
| DataLen = sizeof(LONG); |
| break; |
| case SQL_REAL: |
| DataLen = sizeof(FLOAT); |
| break; |
| case SQL_DOUBLE: |
| case SQL_FLOAT: |
| DataLen = sizeof(DOUBLE); |
| break; |
| default: |
| return IDS_07_006; |
| } |
| } |
| break; |
| case SQL_BIGINT: |
| switch (CDataType) |
| { |
| 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_CHAR: |
| { |
| retCode = ConvertCharToInt64(srcDataPtr, srcLength, tempVal64); |
| if (retCode != SQL_SUCCESS) |
| return retCode; |
| } |
| break; |
| case SQL_C_SHORT: |
| case SQL_C_SSHORT: |
| tempVal64 = *(SSHORT *)srcDataPtr; |
| break; |
| case SQL_C_USHORT: |
| tempVal64 = *(USHORT *)srcDataPtr; |
| break; |
| case SQL_C_TINYINT: |
| case SQL_C_STINYINT: |
| tempVal64 = *(SCHAR *)srcDataPtr; |
| break; |
| case SQL_C_UTINYINT: |
| case SQL_C_BIT: |
| tempVal64 = *(UCHAR *)srcDataPtr; |
| break; |
| case SQL_C_SLONG: |
| case SQL_C_LONG: |
| tempVal64 = *(SLONG_P *)srcDataPtr; |
| break; |
| case SQL_C_ULONG: |
| tempVal64 = *(ULONG_P *)srcDataPtr; |
| break; |
| case SQL_C_FLOAT: |
| tempVal64 = *(SFLOAT *)srcDataPtr; |
| break; |
| case SQL_C_DOUBLE: |
| tempVal64 = *(DOUBLE *)srcDataPtr; |
| break; |
| case SQL_C_BINARY: |
| DataPtr = srcDataPtr; |
| break; |
| case SQL_C_DEFAULT: |
| if (ODBCAppVersion >= SQL_OV_ODBC3) |
| DataPtr = srcDataPtr; |
| else |
| { |
| retCode = ConvertCharToInt64(srcDataPtr, srcLength, tempVal64); |
| if (retCode!= SQL_SUCCESS) |
| return retCode; |
| } |
| break; |
| case SQL_C_SBIGINT: |
| tempVal64 = *(__int64 *)srcDataPtr; |
| break; |
| case SQL_C_NUMERIC: |
| ConvertCNumericToChar((SQL_NUMERIC_STRUCT*)srcDataPtr, cTmpBuf); |
| srcLength = strlen(cTmpBuf); |
| retCode = ConvertCharToInt64((char*)cTmpBuf, srcLength, tempVal64); |
| if (retCode != SQL_SUCCESS) |
| return retCode; |
| break; |
| case SQL_C_INTERVAL_MONTH: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| tempVal64 = -(intervalTmp->intval.year_month.month); |
| else |
| tempVal64 = intervalTmp->intval.year_month.month; |
| break; |
| case SQL_C_INTERVAL_YEAR: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| tempVal64 = -(intervalTmp->intval.year_month.year); |
| else |
| tempVal64 = intervalTmp->intval.year_month.year; |
| break; |
| case SQL_C_INTERVAL_DAY: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| tempVal64 = -(intervalTmp->intval.day_second.day); |
| else |
| tempVal64 = intervalTmp->intval.day_second.day; |
| break; |
| case SQL_C_INTERVAL_HOUR: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| tempVal64 = -(intervalTmp->intval.day_second.hour); |
| else |
| tempVal64 = intervalTmp->intval.day_second.hour; |
| break; |
| case SQL_C_INTERVAL_MINUTE: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| tempVal64 = -(intervalTmp->intval.day_second.minute); |
| else |
| tempVal64 = intervalTmp->intval.day_second.minute; |
| break; |
| case SQL_C_INTERVAL_SECOND: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| tempVal64 = -(intervalTmp->intval.day_second.second); |
| else |
| tempVal64 = intervalTmp->intval.day_second.second; |
| break; |
| default: |
| return IDS_07_006; |
| } |
| if (DataPtr == NULL) |
| DataPtr = &tempVal64; |
| DataLen = sizeof(tempVal64); |
| break; |
| case SQL_NUMERIC: |
| // sol 10-0820-5315 |
| // for R2.3 SP2 release BigNum is only supported for the following data type |
| // SQL_C_DEFAULT, SQL_C_CHAR, SQL_C_FLOAT, SQL_C_DOUBLE |
| // other data types will be supported in future release(?) need to reject them now |
| if (((SQLDataType == SQLTYPECODE_NUMERIC) && (targetPrecision > 18)) || |
| ((SQLDataType == SQLTYPECODE_NUMERIC_UNSIGNED) && (targetPrecision > 9))) |
| { //Bignum |
| switch (CDataType) |
| { |
| case SQL_C_DEFAULT: |
| case SQL_C_CHAR: |
| case SQL_C_WCHAR: |
| case SQL_C_FLOAT: |
| case SQL_C_DOUBLE: |
| case SQL_C_NUMERIC: |
| break; |
| default: |
| return IDS_S1_006; |
| } |
| } |
| 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_CHAR: |
| if (srcLength == SQL_NTS) |
| tempLen = strlen((const char *)srcDataPtr); |
| else |
| tempLen = srcLength; |
| |
| if( tempLen > sizeof( cTmpBuf ) - 1) |
| return IDS_22_003; |
| |
| strncpy(cTmpBuf,(char*)srcDataPtr, tempLen); |
| cTmpBuf[ tempLen ] = '\0'; |
| rTrim(cTmpBuf); |
| tempLen = strlen(cTmpBuf); |
| |
| if( ((SQLDataType == SQLTYPECODE_NUMERIC) && (targetPrecision > 18)) || |
| ((SQLDataType == SQLTYPECODE_NUMERIC_UNSIGNED) && (targetPrecision > 9))) //for bignum support |
| { //Bignum |
| |
| retCode = Ascii_To_Bignum_Helper(cTmpBuf, |
| tempLen, |
| (char*)cTmpBuf2, |
| targetLength, |
| targetPrecision, |
| targetScale, |
| SQLDataType, |
| &dataTruncatedWarning); |
| |
| if(retCode != SQL_SUCCESS) |
| return retCode; |
| |
| useDouble = FALSE; |
| if (DataPtr == NULL) |
| // DataPtr = targetDataPtr; |
| DataPtr = (char*)cTmpBuf2; |
| |
| DataLen = targetLength; |
| |
| } else { |
| if ((retCode = ConvertCharToInt64Num(cTmpBuf, integralPart, |
| decimalPart, negative, leadZeros)) != 0) |
| { |
| // Return values -1 - Out of Range |
| // -2 - Illegal numeric value |
| |
| if (retCode == -1) |
| return IDS_22_003; |
| if (retCode == -2) |
| return IDS_22_005; |
| } |
| if(negative && targetUnsigned) |
| return IDS_22_003_02; |
| if ((integralPart < 0) || (integralPart > integralMax)) |
| return IDS_22_003; |
| decimalDigits = 0; |
| if (decimalPart > 0) |
| decimalDigits = getDigitCount(decimalPart); |
| if ((decimalPart > decimalMax) || ((decimalDigits + leadZeros) > targetScale)) |
| { |
| retCode = IDS_01_S07; |
| // sol 10-080603-3635 |
| // trim the decimalPart based one the scale |
| // the number of digits in the decimal portion needs to be adjusted if it contain |
| // leading zero(s) |
| decimalPart=decimalPart/pow((double)10, (int)(getDigitCount(decimalPart) + leadZeros - targetScale)); |
| } |
| useDouble = FALSE; |
| } |
| break; |
| case SQL_C_NUMERIC: |
| ConvertCNumericToChar((SQL_NUMERIC_STRUCT*)srcDataPtr, cTmpBuf); |
| tempLen = strlen(cTmpBuf); |
| if (((SQLDataType == SQLTYPECODE_NUMERIC) && (targetPrecision > 18)) || |
| ((SQLDataType == SQLTYPECODE_NUMERIC_UNSIGNED) && (targetPrecision > 9))) //for bignum support |
| { //Bignum |
| |
| retCode = Ascii_To_Bignum_Helper(cTmpBuf, |
| tempLen, |
| (char*)targetDataPtr, |
| targetLength, |
| targetPrecision, |
| targetScale, |
| SQLDataType, |
| &dataTruncatedWarning); |
| |
| if(retCode != SQL_SUCCESS) |
| return retCode; |
| |
| useDouble = FALSE; |
| if (DataPtr == NULL) |
| DataPtr = targetDataPtr; |
| |
| DataLen = targetLength; |
| } |
| else { |
| if ((retCode = ConvertCharToInt64Num(cTmpBuf, integralPart, |
| decimalPart, negative, leadZeros)) != 0) |
| { |
| // Return values -1 - Out of Range |
| // -2 - Illegal numeric value |
| |
| if (retCode == -1) |
| return IDS_22_003; |
| if (retCode == -2) |
| return IDS_22_005; |
| } |
| if(negative && targetUnsigned) |
| return IDS_22_003_02; |
| if ((integralPart < 0) || (integralPart > integralMax)) |
| return IDS_22_003; |
| decimalDigits = 0; |
| if (decimalPart > 0) |
| decimalDigits = getDigitCount(decimalPart); |
| if ((decimalPart > decimalMax) || ((decimalDigits + leadZeros) > targetScale)) |
| { |
| retCode = IDS_01_S07; |
| // sol 10-080603-3635 |
| // trim the decimalPart based one the scale |
| // the number of digits in the decimal portion needs to be adjusted if it contain |
| // leading zero(s) |
| decimalPart=decimalPart/pow((double)10, (int)(getDigitCount(decimalPart) + leadZeros - targetScale)); |
| } |
| useDouble = FALSE; |
| } |
| |
| break; |
| |
| case SQL_C_FLOAT: |
| case SQL_C_DOUBLE: |
| if(CDataType == SQL_C_DOUBLE) |
| dTmp = *(DOUBLE *)srcDataPtr; |
| else |
| dTmp = *(SFLOAT *)srcDataPtr; |
| negative = (dTmp < 0)? 1: 0; |
| if( ((SQLDataType == SQLTYPECODE_NUMERIC) && (targetPrecision > 18)) || |
| ((SQLDataType == SQLTYPECODE_NUMERIC_UNSIGNED) && (targetPrecision > 9))) |
| { //Bignum |
| |
| if(CDataType == SQL_C_DOUBLE) |
| { |
| if (!double_to_char (dTmp, DBL_DIG, cTmpBuf, sizeof(cTmpBuf))) |
| dataTruncatedWarning = TRUE; |
| } |
| else |
| { |
| if (!double_to_char (dTmp, FLT_DIG, cTmpBuf, sizeof(cTmpBuf))) |
| dataTruncatedWarning = TRUE; |
| } |
| |
| |
| retCode = Ascii_To_Bignum_Helper(cTmpBuf, |
| strlen(cTmpBuf), |
| (char*)cTmpBuf2, |
| targetLength, |
| targetPrecision, |
| targetScale, |
| SQLDataType, |
| &dataTruncatedWarning); |
| |
| if(retCode != SQL_SUCCESS) |
| return retCode; |
| |
| useDouble = FALSE; |
| if (DataPtr == NULL) |
| DataPtr = cTmpBuf2; |
| |
| DataLen = targetLength; |
| memcpy(outDataPtr, DataPtr, DataLen); |
| if (byteSwap) |
| { |
| if (Datatype_Dependent_Swap((BYTE *)outDataPtr, SQLDataType, targetCharSet, DataLen, IEEE_TO_TANDEM) != STATUS_OK) |
| return IDS_HY_000; |
| } |
| |
| if(dataTruncatedWarning) |
| return IDS_01_S07; |
| else |
| return SQL_SUCCESS; |
| |
| } |
| break; |
| |
| case SQL_C_SHORT: |
| case SQL_C_SSHORT: |
| dTmp = *(SSHORT *)srcDataPtr; |
| break; |
| case SQL_C_TINYINT: |
| case SQL_C_STINYINT: |
| dTmp = *(SCHAR *)srcDataPtr; |
| break; |
| case SQL_C_SLONG: |
| case SQL_C_LONG: |
| dTmp = *(SLONG_P *)srcDataPtr; |
| break; |
| case SQL_C_USHORT: |
| dTmp = *(USHORT *)srcDataPtr; |
| break; |
| case SQL_C_UTINYINT: |
| case SQL_C_BIT: |
| dTmp = *(UCHAR *)srcDataPtr; |
| break; |
| case SQL_C_ULONG: |
| dTmp = *(ULONG_P *)srcDataPtr; |
| break; |
| case SQL_C_BINARY: |
| if (srcLength != OutLen) |
| return IDS_22_003; |
| DataPtr = srcDataPtr; |
| DataLen = OutLen; |
| break; |
| case SQL_C_SBIGINT: |
| integralPart = *(__int64*)srcDataPtr; |
| |
| negative = (integralPart < 0)? 1: 0; |
| integralPart = (integralPart < 0)? -integralPart: integralPart; |
| decimalPart = 0; |
| leadZeros = 0; |
| if ( integralPart > integralMax ) |
| return IDS_22_003; |
| |
| useDouble = FALSE; |
| break; |
| case SQL_C_INTERVAL_MONTH: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| dTmp = -(intervalTmp->intval.year_month.month); |
| else |
| dTmp = intervalTmp->intval.year_month.month; |
| break; |
| case SQL_C_INTERVAL_YEAR: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| dTmp = -(intervalTmp->intval.year_month.year); |
| else |
| dTmp = intervalTmp->intval.year_month.year; |
| break; |
| case SQL_C_INTERVAL_DAY: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| dTmp = -(intervalTmp->intval.day_second.day); |
| else |
| dTmp = intervalTmp->intval.day_second.day; |
| break; |
| case SQL_C_INTERVAL_HOUR: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| dTmp = -(intervalTmp->intval.day_second.hour); |
| else |
| dTmp = intervalTmp->intval.day_second.hour; |
| break; |
| case SQL_C_INTERVAL_MINUTE: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| dTmp = -(intervalTmp->intval.day_second.minute); |
| else |
| dTmp = intervalTmp->intval.day_second.minute; |
| break; |
| case SQL_C_INTERVAL_SECOND: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| dTmp = -(intervalTmp->intval.day_second.second); |
| else |
| dTmp = intervalTmp->intval.day_second.second; |
| break; |
| default: |
| return IDS_07_006; |
| } |
| if (DataPtr == NULL) |
| { |
| if (useDouble) |
| { |
| 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_BOOLEAN: |
| tTmp = (SCHAR)dTmp; |
| DataPtr = &tTmp; |
| DataLen = sizeof(SCHAR); |
| break; |
| 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(usTmp); |
| break; |
| case SQLTYPECODE_SMALLINT: |
| sTmp = (SHORT)dTmp; |
| DataPtr = &sTmp; |
| DataLen = sizeof(sTmp); |
| break; |
| case SQLTYPECODE_INTEGER_UNSIGNED: |
| ulTmp = (ULONG_P)dTmp; |
| DataPtr = &ulTmp; |
| DataLen = sizeof(ulTmp); |
| break; |
| case SQLTYPECODE_INTEGER: |
| lTmp = (LONG)dTmp; |
| DataPtr = &lTmp; |
| DataLen = sizeof(lTmp); |
| break; |
| case SQLTYPECODE_LARGEINT: |
| tempVal64 = (__int64)dTmp; |
| DataPtr = &tempVal64; |
| DataLen = sizeof(tempVal64); |
| 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_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(sTmp); |
| 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(ulTmp); |
| 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(lTmp); |
| break; |
| case SQLTYPECODE_LARGEINT: |
| default: |
| DataPtr = &tempVal64; |
| DataLen = sizeof(tempVal64); |
| break; |
| } |
| |
| |
| } |
| |
| |
| } |
| break; // End of case for SQL_NUMERIC |
| case SQL_DATE: |
| case SQL_TYPE_DATE: |
| switch (CDataType) |
| { |
| 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_CHAR: |
| if (ConvertCharToSQLDate(srcDataPtr, srcLength, ODBCDataType, &SQLDate, targetPrecision) |
| != SQL_SUCCESS) |
| return IDS_22_008; |
| break; |
| case SQL_C_DATE: |
| case SQL_C_TYPE_DATE: |
| case SQL_C_DEFAULT: |
| dateTmp = (DATE_STRUCT *)srcDataPtr; |
| |
| for (i = 0 ; i < 8 ; i++) |
| datetime_parts[i] = 0; |
| datetime_parts[0] = dateTmp->year; |
| datetime_parts[1] = dateTmp->month; |
| datetime_parts[2] = dateTmp->day; |
| if (!checkDatetimeValue(datetime_parts)) |
| return IDS_22_008; |
| |
| SQLDate.year = dateTmp->year; |
| SQLDate.month = dateTmp->month; |
| SQLDate.day = dateTmp->day; |
| break; |
| case SQL_C_TIMESTAMP: |
| case SQL_C_TYPE_TIMESTAMP: |
| timestampTmp = (TIMESTAMP_STRUCT *)srcDataPtr; |
| // SQL/MX fraction precision is max 6 digits but ODBC accepts max precision 9 digits |
| // conversion from nano to micro fraction of second |
| ulFraction = (UDWORD_P)timestampTmp->fraction; |
| if (targetPrecision > 0) |
| { |
| ulFraction /= 1000; |
| sprintf(cTmpBuf, "%06u", ulFraction); |
| cTmpBuf[targetPrecision] = 0; |
| strcpy(cTmpFraction,cTmpBuf); |
| } |
| |
| for (i = 0 ; i < 8 ; i++) |
| datetime_parts[i] = 0; |
| datetime_parts[0] = timestampTmp->year; |
| datetime_parts[1] = timestampTmp->month; |
| datetime_parts[2] = timestampTmp->day; |
| datetime_parts[3] = timestampTmp->hour; |
| datetime_parts[4] = timestampTmp->minute; |
| datetime_parts[5] = timestampTmp->second; |
| datetime_parts[6] = (short)(ulFraction/1000); |
| datetime_parts[7] = (short)(ulFraction%1000); |
| if (!checkDatetimeValue(datetime_parts)) |
| return IDS_22_008; |
| |
| SQLDate.year = timestampTmp->year; |
| SQLDate.month = timestampTmp->month; |
| SQLDate.day = timestampTmp->day; |
| /* |
| if (timestampTmp->hour != 0 || timestampTmp->minute != 0 || timestampTmp->second != 0 || |
| timestampTmp->fraction != 0) |
| { |
| if (ODBCAppVersion >= SQL_OV_ODBC3) |
| return IDS_22_008; |
| else |
| retCode = IDS_22_001; |
| } |
| */ |
| break; |
| case SQL_C_BINARY: |
| if (srcLength != targetLength) |
| return IDS_22_003; |
| DataPtr = srcDataPtr; |
| break; |
| default: |
| return IDS_07_006; |
| } |
| if (DataPtr == NULL) |
| DataPtr = &SQLDate; |
| DataLen = targetLength; |
| |
| if (CDataType != SQL_C_BINARY && RWRSFormat == 0) |
| { |
| pSQLDate = (DATE_TYPES*)DataPtr; |
| switch (SQLDatetimeCode) |
| { |
| case SQLDTCODE_YEAR: |
| DataLen = sprintf(cTmpBuf, "%04d", pSQLDate->year); |
| break; |
| case SQLDTCODE_YEAR_TO_MONTH: |
| DataLen = sprintf(cTmpBuf, "%04d-%02d", pSQLDate->year,pSQLDate->month); |
| break; |
| case SQLDTCODE_MONTH: |
| DataLen = sprintf(cTmpBuf, "%02d", pSQLDate->month); |
| break; |
| case SQLDTCODE_MONTH_TO_DAY: |
| DataLen = sprintf(cTmpBuf, "%02d-%02d", pSQLDate->month,pSQLDate->day); |
| break; |
| case SQLDTCODE_DAY: |
| DataLen = sprintf(cTmpBuf, "%02d", pSQLDate->day); |
| break; |
| default: |
| DataLen = sprintf(cTmpBuf, "%04d-%02d-%02d", pSQLDate->year,pSQLDate->month,pSQLDate->day); |
| } |
| DataPtr = cTmpBuf; |
| } |
| if (DataLen != targetLength) |
| return IDS_22_003; |
| break; // End of case for SQL_DATE |
| case SQL_TIME: |
| case SQL_TYPE_TIME: |
| switch (CDataType) |
| { |
| case SQL_C_WCHAR: |
| if (iconv->isAppUTF16()) |
| { |
| if (srcLength != SQL_NTS) |
| srcLength = srcLength/2; |
| // translate from UTF16 to |
| 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_CHAR: |
| if (ConvertCharToSQLDate(srcDataPtr, srcLength, ODBCDataType, &SQLTime, targetPrecision) |
| != SQL_SUCCESS) |
| return IDS_22_008; |
| break; |
| case SQL_C_TIME: |
| case SQL_C_TYPE_TIME: |
| case SQL_C_DEFAULT: |
| timeTmp = (TIME_STRUCT *)srcDataPtr; |
| |
| for (i = 0 ; i < 8 ; i++) |
| datetime_parts[i] = 0; |
| datetime_parts[0] = 1; |
| datetime_parts[1] = 1; |
| datetime_parts[2] = 1; |
| datetime_parts[3] = timeTmp->hour; |
| datetime_parts[4] = timeTmp->minute; |
| datetime_parts[5] = timeTmp->second; |
| if (!checkDatetimeValue(datetime_parts)) |
| return IDS_22_008; |
| |
| SQLTime.hour = timeTmp->hour; |
| SQLTime.minute = timeTmp->minute; |
| SQLTime.second = timeTmp->second; |
| memset(&SQLTime.fraction,0,sizeof(UDWORD_P)); |
| break; |
| case SQL_C_TIMESTAMP: |
| case SQL_C_TYPE_TIMESTAMP: |
| timestampTmp = (TIMESTAMP_STRUCT *)srcDataPtr; |
| // SQL/MX fraction precision is max 6 digits but ODBC accepts max precision 9 digits |
| // conversion from nano to micro fraction of second |
| ulFraction = (UDWORD_P)timestampTmp->fraction; |
| if (targetPrecision > 0) |
| { |
| ulFraction /= 1000; |
| sprintf(cTmpBuf, "%06u", ulFraction); |
| cTmpBuf[targetPrecision] = 0; |
| strcpy(cTmpFraction,cTmpBuf); |
| } |
| |
| for (i = 0 ; i < 8 ; i++) |
| datetime_parts[i] = 0; |
| datetime_parts[0] = timestampTmp->year; |
| datetime_parts[1] = timestampTmp->month; |
| datetime_parts[2] = timestampTmp->day; |
| datetime_parts[3] = timestampTmp->hour; |
| datetime_parts[4] = timestampTmp->minute; |
| datetime_parts[5] = timestampTmp->second; |
| datetime_parts[6] = (short)(ulFraction/1000); |
| datetime_parts[7] = (short)(ulFraction%1000); |
| if (!checkDatetimeValue(datetime_parts)) |
| return IDS_22_008; |
| |
| SQLTime.hour = timestampTmp->hour; |
| SQLTime.minute = timestampTmp->minute; |
| SQLTime.second = timestampTmp->second; |
| memcpy(&SQLTime.fraction, &ulFraction, sizeof(UDWORD_P)); |
| if (targetPrecision == 0 && ulFraction != 0) |
| { |
| if (ODBCAppVersion >= SQL_OV_ODBC3) |
| return IDS_22_008; |
| else |
| retCode = IDS_01_S07; |
| } |
| break; |
| case SQL_C_BINARY: |
| if (srcLength != targetLength) |
| return IDS_22_008; |
| DataPtr = srcDataPtr; |
| break; |
| default: |
| return IDS_07_006; |
| break; |
| } |
| if (DataPtr == NULL) |
| DataPtr = &SQLTime; |
| DataLen = targetLength; |
| |
| if (CDataType != SQL_C_BINARY && RWRSFormat == 0) |
| { |
| pSQLTime = (TIME_TYPES*)DataPtr; |
| switch (SQLDatetimeCode) |
| { |
| case SQLDTCODE_HOUR: |
| DataLen = sprintf(cTmpBuf,"%02d",pSQLTime->hour); |
| break; |
| case SQLDTCODE_HOUR_TO_MINUTE: |
| DataLen = sprintf(cTmpBuf,"%02d:%02d",pSQLTime->hour,pSQLTime->minute); |
| break; |
| case SQLDTCODE_MINUTE: |
| DataLen = sprintf(cTmpBuf,"%02d",pSQLTime->minute); |
| break; |
| case SQLDTCODE_MINUTE_TO_SECOND: |
| if (targetPrecision > 0) |
| DataLen = sprintf(cTmpBuf,"%02d:%02d.%s",pSQLTime->minute,pSQLTime->second,cTmpFraction); |
| else |
| DataLen = sprintf(cTmpBuf,"%02d:%02d",pSQLTime->minute,pSQLTime->second); |
| break; |
| case SQLDTCODE_SECOND: |
| DataLen = sprintf(cTmpBuf,"%02d",pSQLTime->second); |
| break; |
| default: |
| DataLen = sprintf(cTmpBuf,"%02d:%02d:%02d",pSQLTime->hour,pSQLTime->minute,pSQLTime->second); |
| break; |
| } |
| DataPtr = cTmpBuf; |
| } |
| if (DataLen != targetLength) |
| return IDS_22_008; |
| break; // End of case for SQL_TIME |
| case SQL_TIMESTAMP: |
| case SQL_TYPE_TIMESTAMP: |
| switch (CDataType) |
| { |
| 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_CHAR: |
| if (ConvertCharToSQLDate(srcDataPtr, srcLength, ODBCDataType, &SQLTimestamp, targetPrecision) |
| != SQL_SUCCESS) |
| return IDS_22_008; |
| memcpy(&ulFraction, &SQLTimestamp.fraction, sizeof(UDWORD_P)); |
| if (targetPrecision > 0) |
| { |
| sprintf(cTmpFraction, "%0*lu", targetPrecision, ulFraction); |
| } |
| break; |
| case SQL_C_DATE: |
| case SQL_C_TYPE_DATE: |
| dateTmp = (DATE_STRUCT *)srcDataPtr; |
| |
| for (i = 0 ; i < 8 ; i++) |
| datetime_parts[i] = 0; |
| datetime_parts[0] = dateTmp->year; |
| datetime_parts[1] = dateTmp->month; |
| datetime_parts[2] = dateTmp->day; |
| if (!checkDatetimeValue(datetime_parts)) |
| return IDS_22_008; |
| |
| SQLTimestamp.year = dateTmp->year; |
| SQLTimestamp.month = dateTmp->month; |
| SQLTimestamp.day = dateTmp->day; |
| SQLTimestamp.hour = 0; |
| SQLTimestamp.minute = 0; |
| SQLTimestamp.second = 0; |
| memset(&SQLTimestamp.fraction, 0, sizeof(UDWORD_P)); |
| ulFraction = 0; |
| if (targetPrecision > 0) |
| { |
| sprintf(cTmpBuf, "%06u", ulFraction); |
| cTmpBuf[targetPrecision] = 0; |
| strcpy(cTmpFraction,cTmpBuf); |
| // ulFraction = atol(cTmpBuf); |
| } |
| break; |
| case SQL_C_TIME: |
| case SQL_C_TYPE_TIME: |
| struct tm *newtime; |
| time_t long_time; |
| |
| time( &long_time ); /* Get time as long integer. */ |
| newtime = localtime( &long_time ); /* Convert to local time. */ |
| |
| timeTmp = (TIME_STRUCT *)srcDataPtr; |
| |
| for (i = 0 ; i < 8 ; i++) |
| datetime_parts[i] = 0; |
| datetime_parts[0] = newtime->tm_year+1900; |
| datetime_parts[1] = newtime->tm_mon+1; |
| datetime_parts[2] = newtime->tm_mday; |
| datetime_parts[3] = timeTmp->hour; |
| datetime_parts[4] = timeTmp->minute; |
| datetime_parts[5] = timeTmp->second; |
| if (!checkDatetimeValue(datetime_parts)) |
| return IDS_22_008; |
| |
| SQLTimestamp.year = newtime->tm_year+1900; |
| SQLTimestamp.month = newtime->tm_mon+1; |
| SQLTimestamp.day = newtime->tm_mday; |
| SQLTimestamp.hour = timeTmp->hour; |
| SQLTimestamp.minute = timeTmp->minute; |
| SQLTimestamp.second = timeTmp->second; |
| memset(&SQLTimestamp.fraction, 0, sizeof(UDWORD_P)); |
| ulFraction = 0; |
| if (targetPrecision > 0) |
| { |
| sprintf(cTmpBuf, "%06u", ulFraction); |
| cTmpBuf[targetPrecision] = 0; |
| strcpy(cTmpFraction,cTmpBuf); |
| // ulFraction = atol(cTmpBuf); |
| } |
| break; |
| case SQL_C_TIMESTAMP: |
| case SQL_C_TYPE_TIMESTAMP: |
| case SQL_C_DEFAULT: |
| timestampTmp = (TIMESTAMP_STRUCT *)srcDataPtr; |
| // SQL/MX fraction precision is max 6 digits but ODBC accepts max precision 9 digits |
| // conversion from nano seconds to fraction of a second |
| ulFraction = (UDWORD_P)timestampTmp->fraction; |
| if (targetPrecision > 0) |
| ulFraction = (ulFraction * pow(10,targetPrecision)) / 1000000000.0; |
| else |
| ulFraction = 0; |
| sprintf(cTmpBuf, "%06u", ulFraction); |
| strcpy(cTmpFraction,&cTmpBuf[6 - targetPrecision]); |
| |
| for (i = 0 ; i < 8 ; i++) |
| datetime_parts[i] = 0; |
| datetime_parts[0] = timestampTmp->year; |
| datetime_parts[1] = timestampTmp->month; |
| datetime_parts[2] = timestampTmp->day; |
| datetime_parts[3] = timestampTmp->hour; |
| datetime_parts[4] = timestampTmp->minute; |
| datetime_parts[5] = timestampTmp->second; |
| datetime_parts[6] = (short)(ulFraction/1000); |
| datetime_parts[7] = (short)(ulFraction%1000); |
| if (!checkDatetimeValue(datetime_parts)) |
| return IDS_22_008; |
| |
| SQLTimestamp.year = timestampTmp->year; |
| SQLTimestamp.month = timestampTmp->month; |
| SQLTimestamp.day = timestampTmp->day; |
| SQLTimestamp.hour = timestampTmp->hour; |
| SQLTimestamp.minute = timestampTmp->minute; |
| SQLTimestamp.second = timestampTmp->second; |
| memset(&SQLTimestamp.fraction, 0, sizeof(UDWORD_P)); |
| if (targetPrecision > 0) |
| memcpy(&SQLTimestamp.fraction, &ulFraction, sizeof(SQLUINTEGER)); |
| break; |
| case SQL_C_BINARY: |
| if (srcLength != targetLength) |
| return IDS_22_003; |
| DataPtr = srcDataPtr; |
| break; |
| default: |
| return IDS_07_006; |
| } |
| if (DataPtr == NULL) |
| DataPtr = &SQLTimestamp; |
| if(RWRSFormat == 1) |
| DataLen = sizeof(SQLTimestamp)-1; // since it is only 11 bytes that matters |
| OutLen = DataLen; // in case user creates a table as datetime year to second, |
| // SQL/MX returns OutLen as 7 bytes |
| // Non-standard timestamp table year to second. |
| if (CDataType != SQL_C_BINARY && RWRSFormat == 0) |
| { |
| pSQLTimestamp = (TIMESTAMP_TYPES*)DataPtr; |
| switch (SQLDatetimeCode) |
| { |
| case SQLDTCODE_TIME: |
| if (targetPrecision > 0) |
| DataLen = sprintf(cTmpBuf,"%02d:%02d:%02d.%s", |
| pSQLTimestamp->hour,pSQLTimestamp->minute,pSQLTimestamp->second, |
| cTmpFraction); |
| else |
| DataLen = sprintf(cTmpBuf,"%02d:%02d:%02d", |
| pSQLTimestamp->hour,pSQLTimestamp->minute,pSQLTimestamp->second); |
| break; |
| case SQLDTCODE_YEAR_TO_HOUR: |
| DataLen = sprintf(cTmpBuf,"%04d-%02d-%02d %02d", |
| pSQLTimestamp->year,pSQLTimestamp->month,pSQLTimestamp->day, |
| pSQLTimestamp->hour); |
| break; |
| case SQLDTCODE_YEAR_TO_MINUTE: |
| DataLen = sprintf(cTmpBuf,"%04d-%02d-%02d %02d:%02d", |
| pSQLTimestamp->year,pSQLTimestamp->month,pSQLTimestamp->day, |
| pSQLTimestamp->hour,pSQLTimestamp->minute); |
| break; |
| case SQLDTCODE_MONTH_TO_HOUR: |
| DataLen = sprintf(cTmpBuf,"%02d-%02d %02d", |
| pSQLTimestamp->month,pSQLTimestamp->day, |
| pSQLTimestamp->hour); |
| break; |
| case SQLDTCODE_MONTH_TO_MINUTE: |
| DataLen = sprintf(cTmpBuf,"%02d-%02d %02d:%02d", |
| pSQLTimestamp->month,pSQLTimestamp->day, |
| pSQLTimestamp->hour,pSQLTimestamp->minute); |
| break; |
| case SQLDTCODE_MONTH_TO_SECOND: |
| if (targetPrecision > 0) |
| DataLen = sprintf(cTmpBuf,"%02d-%02d %02d:%02d:%02d.%s", |
| pSQLTimestamp->month,pSQLTimestamp->day, |
| pSQLTimestamp->hour,pSQLTimestamp->minute,pSQLTimestamp->second, |
| cTmpFraction); |
| else |
| DataLen = sprintf(cTmpBuf,"%02d-%02d %02d:%02d:%02d", |
| pSQLTimestamp->month,pSQLTimestamp->day, |
| pSQLTimestamp->hour,pSQLTimestamp->minute,pSQLTimestamp->second); |
| break; |
| case SQLDTCODE_DAY_TO_HOUR: |
| DataLen = sprintf(cTmpBuf,"%02d %02d", |
| pSQLTimestamp->day, |
| pSQLTimestamp->hour); |
| break; |
| case SQLDTCODE_DAY_TO_MINUTE: |
| DataLen = sprintf(cTmpBuf,"%02d %02d:%02d", |
| pSQLTimestamp->day, |
| pSQLTimestamp->hour,pSQLTimestamp->minute); |
| break; |
| case SQLDTCODE_DAY_TO_SECOND: |
| if (targetPrecision > 0) |
| DataLen = sprintf(cTmpBuf,"%02d %02d:%02d:%02d.%s", |
| pSQLTimestamp->day, |
| pSQLTimestamp->hour,pSQLTimestamp->minute,pSQLTimestamp->second, |
| cTmpFraction); |
| else |
| DataLen = sprintf(cTmpBuf,"%02d %02d:%02d:%02d", |
| pSQLTimestamp->day, |
| pSQLTimestamp->hour,pSQLTimestamp->minute,pSQLTimestamp->second); |
| break; |
| case SQLDTCODE_HOUR: |
| DataLen = sprintf(cTmpBuf,"%02d",pSQLTimestamp->hour); |
| break; |
| case SQLDTCODE_HOUR_TO_MINUTE: |
| DataLen = sprintf(cTmpBuf,"%02d:%02d",pSQLTimestamp->hour,pSQLTimestamp->minute); |
| break; |
| case SQLDTCODE_MINUTE: |
| DataLen = sprintf(cTmpBuf,"%02d",pSQLTimestamp->minute); |
| break; |
| case SQLDTCODE_MINUTE_TO_SECOND: |
| if (targetPrecision > 0) |
| DataLen = sprintf(cTmpBuf,"%02d:%02d.%s",pSQLTimestamp->minute,pSQLTimestamp->second,cTmpFraction); |
| else |
| DataLen = sprintf(cTmpBuf,"%02d:%02d",pSQLTimestamp->minute,pSQLTimestamp->second); |
| break; |
| case SQLDTCODE_SECOND: |
| if (targetPrecision > 0) |
| DataLen = sprintf(cTmpBuf,"%02d.%s",pSQLTimestamp->second,cTmpFraction); |
| else |
| DataLen = sprintf(cTmpBuf,"%02d",pSQLTimestamp->second); |
| break; |
| default: |
| if (targetPrecision > 0) |
| DataLen = sprintf(cTmpBuf,"%04d-%02d-%02d %02d:%02d:%02d.%s", |
| pSQLTimestamp->year,pSQLTimestamp->month,pSQLTimestamp->day, |
| pSQLTimestamp->hour,pSQLTimestamp->minute,pSQLTimestamp->second, |
| cTmpFraction); |
| else |
| DataLen = sprintf(cTmpBuf,"%04d-%02d-%02d %02d:%02d:%02d", |
| pSQLTimestamp->year,pSQLTimestamp->month,pSQLTimestamp->day, |
| pSQLTimestamp->hour,pSQLTimestamp->minute,pSQLTimestamp->second); |
| break; |
| |
| } |
| DataPtr = cTmpBuf; |
| } |
| if (DataLen != targetLength) |
| return IDS_22_003; |
| break; // End of SQL_TIMESTAMP |
| 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: |
| cTmpDataType = CDataType; |
| if (CDataType == SQL_C_DEFAULT) |
| { |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_MONTH: |
| cTmpDataType = SQL_C_INTERVAL_MONTH; |
| break; |
| case SQL_INTERVAL_YEAR: |
| cTmpDataType = SQL_C_INTERVAL_YEAR; |
| break; |
| case SQL_INTERVAL_YEAR_TO_MONTH: |
| cTmpDataType = SQL_C_INTERVAL_YEAR_TO_MONTH; |
| break; |
| case SQL_INTERVAL_DAY: |
| cTmpDataType = SQL_C_INTERVAL_DAY; |
| break; |
| case SQL_INTERVAL_HOUR: |
| cTmpDataType = SQL_C_INTERVAL_HOUR; |
| break; |
| case SQL_INTERVAL_MINUTE: |
| cTmpDataType = SQL_C_INTERVAL_MINUTE; |
| break; |
| case SQL_INTERVAL_SECOND: |
| cTmpDataType = SQL_C_INTERVAL_SECOND; |
| break; |
| case SQL_INTERVAL_DAY_TO_HOUR: |
| cTmpDataType = SQL_C_INTERVAL_DAY_TO_HOUR; |
| break; |
| case SQL_INTERVAL_DAY_TO_MINUTE: |
| cTmpDataType = SQL_C_INTERVAL_DAY_TO_MINUTE; |
| break; |
| case SQL_INTERVAL_DAY_TO_SECOND: |
| cTmpDataType = SQL_C_INTERVAL_DAY_TO_SECOND; |
| break; |
| case SQL_INTERVAL_HOUR_TO_MINUTE: |
| cTmpDataType = SQL_C_INTERVAL_HOUR_TO_MINUTE; |
| break; |
| case SQL_INTERVAL_HOUR_TO_SECOND: |
| cTmpDataType = SQL_C_INTERVAL_HOUR_TO_SECOND; |
| break; |
| case SQL_INTERVAL_MINUTE_TO_SECOND: |
| cTmpDataType = SQL_C_INTERVAL_MINUTE_TO_SECOND; |
| break; |
| default: |
| return IDS_07_006; |
| } |
| } |
| |
| switch (cTmpDataType) |
| { |
| 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_CHAR: |
| if (srcLength == SQL_NTS) |
| DataLen = strlen((const char *)srcDataPtr); |
| else |
| DataLen = srcLength; |
| if (StripIntervalLiterals(srcDataPtr, srcLength, ODBCDataType, cTmpBuf) != SQL_SUCCESS) |
| return IDS_22_018; |
| break; |
| case SQL_C_BINARY: |
| if (srcLength == SQL_NTS) |
| DataLen = strlen((const char *)srcDataPtr); |
| else |
| DataLen = srcLength; |
| strcpy(cTmpBuf, (const char *)srcDataPtr); |
| break; |
| case SQL_C_SHORT: |
| case SQL_C_SSHORT: |
| sTmp = *(SSHORT *)srcDataPtr; |
| _ltoa(sTmp, cTmpBuf, 10); |
| break; |
| case SQL_C_USHORT: |
| usTmp = *(USHORT *)srcDataPtr; |
| _ultoa(usTmp, cTmpBuf, 10); |
| break; |
| case SQL_C_TINYINT: |
| case SQL_C_STINYINT: |
| sTmp = *(SCHAR *)srcDataPtr; |
| _ltoa(sTmp, cTmpBuf, 10); |
| break; |
| case SQL_C_UTINYINT: |
| case SQL_C_BIT: |
| usTmp = *(UCHAR *)srcDataPtr; |
| _ultoa(usTmp, cTmpBuf, 10); |
| break; |
| case SQL_C_SLONG: |
| case SQL_C_LONG: |
| lTmp = *(SLONG_P *)srcDataPtr; |
| _ltoa(lTmp, cTmpBuf, 10); |
| break; |
| case SQL_C_ULONG: |
| ulTmp = *(ULONG_P *)srcDataPtr; |
| _ultoa(ulTmp, cTmpBuf, 10); |
| break; |
| case SQL_C_FLOAT: |
| dTmp = *(float *)srcDataPtr; |
| if (!double_to_char (dTmp, FLT_DIG, cTmpBuf, sizeof(cTmpBuf))) |
| return IDS_22_001; |
| break; |
| case SQL_C_DOUBLE: |
| dTmp = *(double *)srcDataPtr; |
| if (!double_to_char (dTmp, DBL_DIG, cTmpBuf, sizeof(cTmpBuf))) |
| return IDS_22_001; |
| break; |
| case SQL_C_NUMERIC: |
| ConvertCNumericToChar((SQL_NUMERIC_STRUCT*)srcDataPtr, cTmpBuf); |
| break; |
| case SQL_C_SBIGINT: |
| #ifndef unixcli |
| sprintf(cTmpBuf, "%I64d", *(__int64*)srcDataPtr); |
| #else |
| sprintf(cTmpBuf, "%Ld", *(__int64*)srcDataPtr); |
| #endif |
| break; |
| case SQL_C_INTERVAL_MONTH: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_MONTH: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.year_month.month); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.year_month.month); |
| break; |
| case SQL_INTERVAL_YEAR_TO_MONTH: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-00-%ld",intervalTmp->intval.year_month.month); |
| else |
| sprintf(cTmpBuf,"00-%ld",intervalTmp->intval.year_month.month); |
| break; |
| default: |
| return IDS_07_006; |
| } |
| break; |
| case SQL_C_INTERVAL_YEAR: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_YEAR: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.year_month.year); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.year_month.year); |
| break; |
| case SQL_INTERVAL_YEAR_TO_MONTH: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld-00",intervalTmp->intval.year_month.year); |
| else |
| sprintf(cTmpBuf,"%ld-00",intervalTmp->intval.year_month.year); |
| break; |
| default: |
| return IDS_07_006; |
| } |
| break; |
| case SQL_C_INTERVAL_YEAR_TO_MONTH: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_YEAR: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.year_month.year); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.year_month.year); |
| break; |
| case SQL_INTERVAL_MONTH: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld", intervalTmp->intval.year_month.month); |
| else |
| sprintf(cTmpBuf,"%ld", intervalTmp->intval.year_month.month); |
| break; |
| case SQL_INTERVAL_YEAR_TO_MONTH: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld-%ld",intervalTmp->intval.year_month.year, intervalTmp->intval.year_month.month); |
| else |
| sprintf(cTmpBuf,"%ld-%ld",intervalTmp->intval.year_month.year, intervalTmp->intval.year_month.month); |
| break; |
| default: |
| return IDS_07_006; |
| } |
| break; |
| case SQL_C_INTERVAL_DAY: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_DAY: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.day); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.day); |
| break; |
| case SQL_INTERVAL_DAY_TO_HOUR: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld 00",intervalTmp->intval.day_second.day); |
| else |
| sprintf(cTmpBuf,"%ld 00",intervalTmp->intval.day_second.day); |
| break; |
| case SQL_INTERVAL_DAY_TO_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld 00:00",intervalTmp->intval.day_second.day); |
| else |
| sprintf(cTmpBuf,"%ld 00:00",intervalTmp->intval.day_second.day); |
| break; |
| case SQL_INTERVAL_DAY_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld 00:00:00",intervalTmp->intval.day_second.day); |
| else |
| sprintf(cTmpBuf,"%ld 00:00:00",intervalTmp->intval.day_second.day); |
| break; |
| default: |
| return IDS_07_006; |
| } |
| break; |
| case SQL_C_INTERVAL_HOUR: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_HOUR: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_INTERVAL_DAY_TO_HOUR: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-00 %ld",intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"00 %ld",intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_INTERVAL_DAY_TO_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-00 %ld:00",intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"00 %ld:00",intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_INTERVAL_DAY_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-00 %ld:00:00",intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"00 %ld:00:00",intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_INTERVAL_HOUR_TO_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld:00",intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"%ld:00",intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_INTERVAL_HOUR_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld:00:00",intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"%ld:00:00",intervalTmp->intval.day_second.hour); |
| break; |
| default: |
| return IDS_07_006; |
| } |
| break; |
| case SQL_C_INTERVAL_MINUTE: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_DAY_TO_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-00 00:%ld",intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"00 00:%ld",intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_DAY_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-00 00:%ld:00",intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"00 00:%ld:00",intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_HOUR_TO_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-00:%ld",intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"00:%ld",intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_HOUR_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-00:%ld:00",intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"00:%ld:00",intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_MINUTE_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld:00",intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld:00",intervalTmp->intval.day_second.minute); |
| break; |
| default: |
| return IDS_07_006; |
| } |
| break; |
| case SQL_C_INTERVAL_SECOND: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"-%ld.%ld",intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| else |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"%ld.%ld",intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| break; |
| case SQL_INTERVAL_DAY_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"-00 00:00:%ld",intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"-00 00:00:%ld.%ld",intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| else |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"00 00:00:%ld",intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"00 00:00:%ld.%ld",intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| break; |
| case SQL_INTERVAL_HOUR_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"-00:00:%ld",intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"-00:00:%ld.%ld",intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| else |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"00:00:%ld",intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"00:00:%ld.%ld",intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| break; |
| case SQL_INTERVAL_MINUTE_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"-00:%ld",intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"-00:%ld.%ld",intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| else |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"00:%ld",intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"00:%ld.%ld",intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| break; |
| default: |
| return IDS_07_006; |
| } |
| break; |
| case SQL_C_INTERVAL_DAY_TO_HOUR: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_DAY: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.day); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.day); |
| break; |
| case SQL_INTERVAL_HOUR: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld", intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"%ld", intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_INTERVAL_DAY_TO_HOUR: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld %ld",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"%ld %ld",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_INTERVAL_DAY_TO_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld %ld:00",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"%ld %ld:00",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_INTERVAL_DAY_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld %ld:00:00",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"%ld %ld:00:00",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_INTERVAL_HOUR_TO_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld:00", intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"%ld:00", intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_INTERVAL_HOUR_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld:00:00", intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"%ld:00:00", intervalTmp->intval.day_second.hour); |
| break; |
| default: |
| return IDS_07_006; |
| } |
| break; |
| case SQL_C_INTERVAL_DAY_TO_MINUTE: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_DAY: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.day); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.day); |
| break; |
| case SQL_INTERVAL_HOUR: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_INTERVAL_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_DAY_TO_HOUR: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld %ld",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"%ld %ld",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_INTERVAL_DAY_TO_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld %ld:%ld",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld %ld:%ld",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_DAY_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld %ld:%ld:00",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld %ld:%ld:00",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_HOUR_TO_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_HOUR_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld:%ld:00",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld:%ld:00",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_MINUTE_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld:00",intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld:00",intervalTmp->intval.day_second.minute); |
| break; |
| default: |
| return IDS_07_006; |
| } |
| break; |
| case SQL_C_INTERVAL_DAY_TO_SECOND: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_DAY: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.day); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.day); |
| break; |
| case SQL_INTERVAL_HOUR: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_INTERVAL_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"-%ld.%ld",intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| else |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"%ld.%ld",intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| break; |
| case SQL_INTERVAL_DAY_TO_HOUR: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld %ld",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"%ld %ld",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_INTERVAL_DAY_TO_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld %ld:%ld",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld %ld:%ld",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_DAY_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"-%d %d:%d:%d",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"-%d %d:%d:%d.%d",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| else |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"%d %d:%d:%d",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"%d %d:%d:%d.%d",intervalTmp->intval.day_second.day,intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| break; |
| case SQL_INTERVAL_HOUR_TO_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_HOUR_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"-%ld:%ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"-%ld:%ld:%ld.%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| else |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"%ld:%ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"%ld:%ld:%ld.%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| break; |
| case SQL_INTERVAL_MINUTE_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"-%ld:%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"-%ld:%ld.%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| else |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"%ld:%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"%ld:%ld.%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| break; |
| default: |
| return IDS_07_006; |
| } |
| break; |
| case SQL_C_INTERVAL_HOUR_TO_MINUTE: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_HOUR: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_INTERVAL_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_DAY_TO_HOUR: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-00 %ld",intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"00 %ld",intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_INTERVAL_DAY_TO_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-00 %ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"00 %ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_DAY_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-00 %ld:%ld:00",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"00 %ld:%ld:00",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_HOUR_TO_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_HOUR_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld:%ld:00",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld:%ld:00",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_MINUTE_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld:00",intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld:00",intervalTmp->intval.day_second.minute); |
| break; |
| default: |
| return IDS_07_006; |
| } |
| break; |
| case SQL_C_INTERVAL_HOUR_TO_SECOND: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_HOUR: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_INTERVAL_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"-%ld.%ld",intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| else |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"%ld.%ld",intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| break; |
| case SQL_INTERVAL_DAY_TO_HOUR: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-00 %ld",intervalTmp->intval.day_second.hour); |
| else |
| sprintf(cTmpBuf,"00 %ld",intervalTmp->intval.day_second.hour); |
| break; |
| case SQL_INTERVAL_DAY_TO_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-00 %ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"00 %ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_DAY_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-00 %ld:%ld:00",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"00 %ld:%ld:00",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_HOUR_TO_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_HOUR_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"-%ld:%ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"-%ld:%ld:%ld.%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| else |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"%ld:%ld:%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"%ld:%ld:%ld.%ld",intervalTmp->intval.day_second.hour,intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| break; |
| case SQL_INTERVAL_MINUTE_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"-%ld:%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"-%ld:%ld.%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| else |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"%ld:%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"%ld:%ld.%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| break; |
| default: |
| return IDS_07_006; |
| } |
| break; |
| case SQL_C_INTERVAL_MINUTE_TO_SECOND: |
| intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr; |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"-%ld",intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"-%ld.%ld",intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| else |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"%ld",intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"%ld.%ld",intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| break; |
| case SQL_INTERVAL_DAY_TO_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-00 00:%ld",intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"00 00:%ld",intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_DAY_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"-00 00:%ld:%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"-00 00:%ld:%ld.%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| else |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"00 00:%ld:%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"00 00:%ld:%ld.%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| break; |
| case SQL_INTERVAL_HOUR_TO_MINUTE: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| sprintf(cTmpBuf,"-00:%ld",intervalTmp->intval.day_second.minute); |
| else |
| sprintf(cTmpBuf,"00:%ld",intervalTmp->intval.day_second.minute); |
| break; |
| case SQL_INTERVAL_HOUR_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"-00:%ld:%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"-00:%ld:%ld.%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| else |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"00:%ld:%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"00:%ld:%ld.%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| break; |
| case SQL_INTERVAL_MINUTE_TO_SECOND: |
| if (intervalTmp->interval_sign == SQL_TRUE) |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"-%ld:%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"-%ld:%ld.%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| else |
| { |
| if (intervalTmp->intval.day_second.fraction == 0) |
| sprintf(cTmpBuf,"%ld:%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second); |
| else |
| sprintf(cTmpBuf,"%ld:%ld.%ld",intervalTmp->intval.day_second.minute,intervalTmp->intval.day_second.second,intervalTmp->intval.day_second.fraction); |
| } |
| break; |
| default: |
| return IDS_07_006; |
| } |
| break; |
| default: |
| return IDS_07_006; |
| } |
| if (DataPtr == NULL) |
| { |
| if(RWRSFormat == 0) |
| if ((retCode = CheckIntervalOverflow(cTmpBuf, ODBCDataType, targetLength, targetPrecision)) != SQL_SUCCESS) |
| return retCode; |
| |
| if(RWRSFormat == 0) |
| InsertBlank(cTmpBuf, targetLength-strlen(cTmpBuf)); |
| |
| if(RWRSFormat == 0) |
| { |
| DataPtr = cTmpBuf; |
| DataLen = strlen(cTmpBuf); |
| } |
| else |
| { |
| retCode = Ascii_To_Interval_Helper(cTmpBuf, |
| strlen(cTmpBuf), |
| (char*)cTmpBuf2, |
| targetLength, |
| datetimeIntervalPrecision, |
| targetPrecision, |
| SQLDatetimeCode, //ODBCDataType - 100, |
| &dataTruncatedWarning); |
| |
| if(retCode != SQL_SUCCESS) |
| return retCode; |
| |
| DataPtr = (char*)cTmpBuf2; |
| DataLen = targetLength; |
| } |
| } |
| if (Offset != 0) |
| { |
| if(DataLen>32767){ |
| *(int *)targetDataPtr = DataLen; |
| outDataPtr = (unsigned char *)targetDataPtr + sizeof(int); |
| } |
| else{ |
| *(unsigned short *)targetDataPtr = DataLen; |
| outDataPtr = (unsigned char *)targetDataPtr + sizeof(USHORT); |
| } |
| } |
| OutLen = DataLen; // in case user creates a table as datetime year to second, |
| // SQL/MX returns OutLen as 7 bytes |
| // Non-standard timestamp table year to second. |
| break; |
| default: |
| return IDS_07_006; |
| } |
| if ((retCode == SQL_SUCCESS) || (retCode == IDS_01_S07)) |
| { |
| //10-080124-0030 |
| if(pdwGlobalTraceVariable && *pdwGlobalTraceVariable) |
| TraceOut(TR_ODBC_DEBUG, "ODBC::ConvertCToSQL DataPtr \"%s\", DataLen %d", |
| DataPtr, DataLen); |
| if (DataPtr != NULL && DataLen > 0 && |
| (ODBCDataType == SQL_CHAR || ODBCDataType == SQL_VARCHAR || ODBCDataType == SQL_LONGVARCHAR || |
| ODBCDataType == SQL_WCHAR || ODBCDataType == SQL_WVARCHAR) && CDataType != SQL_C_BINARY && SQLDataType != SQLTYPECODE_BOOLEAN) |
| { |
| SQLRETURN rc = SQL_SUCCESS; |
| if (targetCharSet == SQLCHARSETCODE_ISO88591) |
| { |
| if (CDataType == SQL_C_WCHAR) |
| { |
| if (iconv->isAppUTF16()) |
| { |
| // JJ should be now from UTF16 to ISO88591 |
| // translate from UTF16 to DrvrLocale |
| rc = iconv->WCharToISO88591((UChar*)DataPtr, DataLen, (char*)outDataPtr, OutLen+1, (int*)&translateLength, (char*)errorMsg, NULL); |
| if (rc != SQL_SUCCESS) |
| { |
| if (rc == SQL_SUCCESS_WITH_INFO) |
| return IDS_22_001; |
| else |
| return IDS_193_DRVTODS_ERROR; |
| } |
| DataLen = translateLength; |
| } |
| else |
| { |
| //JJ should be now from UTF8 to ISO88591 |
| rc = iconv->UTF8ToFromISO88591(true, (char*)DataPtr, DataLen, (char*)outDataPtr, OutLen+1, &translateLength, (char*)errorMsg); |
| if (rc != SQL_SUCCESS) |
| { |
| if (rc == SQL_SUCCESS_WITH_INFO) |
| return IDS_22_001; |
| else |
| return IDS_193_DRVTODS_ERROR; |
| } |
| DataLen = translateLength; |
| } |
| } |
| else // SQL_C_CHAR |
| { |
| /* may be something that needs to be done to make iso88591 faster |
| if(iconv->isDriverLocaleISO88591()) // behave like passthru - only for ISO88591 |
| { |
| if (DataLen > OutLen) |
| { |
| DataLen = OutLen; |
| return IDS_22_001; |
| } |
| memcpy(outDataPtr, DataPtr, DataLen); |
| } |
| else //Force the translation from DrvrLocale ISO88591 |
| { |
| */ |
| rc = iconv->TranslateISO88591(false, (char*)DataPtr, DataLen, (char*)outDataPtr, OutLen+1, &translateLength, (char*)errorMsg); |
| if (rc != SQL_SUCCESS) |
| { |
| if (rc == SQL_SUCCESS_WITH_INFO) |
| return IDS_22_001; |
| else |
| return IDS_193_DRVTODS_ERROR; |
| } |
| DataLen = translateLength; |
| // } |
| } |
| if (Offset != 0) |
| { |
| if(targetPrecision > SHRT_MAX) |
| *(unsigned int *)targetDataPtr = DataLen; |
| else |
| *(unsigned short *)targetDataPtr = DataLen; |
| } |
| } |
| else if (targetCharSet == SQLCHARSETCODE_UCS2) |
| { |
| // translate to UCS2 |
| if (CDataType == SQL_C_WCHAR) |
| { |
| if (iconv->isAppUTF16()) |
| { |
| // translate from UTF16 to UCS2 - no translation |
| if (DataLen > OutLen/2) |
| { |
| DataLen = OutLen/2; |
| return IDS_22_001; |
| } |
| u_strncpy((UChar*)outDataPtr, (const UChar*)DataPtr, DataLen); |
| ((UChar*)outDataPtr)[DataLen] = UCharNull; |
| } |
| else |
| { |
| // translate from UTF8 to UCS2 |
| rc = iconv->UTF8ToWChar((char*)DataPtr, DataLen, (UChar*)outDataPtr, OutLen/2+1, &translateLength, (char*)errorMsg); |
| if (rc != SQL_SUCCESS) |
| { |
| if (rc == SQL_SUCCESS_WITH_INFO) |
| return IDS_22_001; |
| else |
| return IDS_193_DRVTODS_ERROR; |
| } |
| DataLen = translateLength; |
| } |
| } |
| else //SQL_C_CHAR |
| { |
| // translate from DrvrLocale to UCS2 |
| rc = iconv->LocaleToWChar((char*)DataPtr, DataLen, (UChar*)outDataPtr, OutLen/2+1, (int*)&translateLength, (char*)errorMsg); |
| if (rc != SQL_SUCCESS) |
| { |
| if (rc == SQL_SUCCESS_WITH_INFO) |
| return IDS_22_001; |
| else |
| return IDS_193_DRVTODS_ERROR; |
| } |
| DataLen = translateLength; |
| } |
| if (Offset != 0) |
| { |
| if(targetPrecision > SHRT_MAX) |
| { |
| if(iconv->getUCS2Translation()) |
| *(unsigned int *)targetDataPtr = DataLen*2; |
| else |
| *(unsigned int *)targetDataPtr = DataLen; |
| } |
| else |
| { |
| if(iconv->getUCS2Translation()) |
| *(unsigned short *)targetDataPtr = DataLen*2; |
| else |
| *(unsigned short *)targetDataPtr = DataLen; |
| } |
| } |
| } |
| // needs to work with UTF8 columns |
| else if (targetCharSet == SQLCHARSETCODE_UTF8) |
| { |
| // translate to UTF8 |
| if (CDataType == SQL_C_WCHAR) |
| { |
| if (iconv->isAppUTF16()) |
| { |
| // translate from UTF16 to UTF8 |
| rc = iconv->WCharToUTF8((UChar*)DataPtr, DataLen, (char*)outDataPtr, OutLen+1, (int*)&translateLength, (char*)errorMsg); |
| if (rc != SQL_SUCCESS) |
| { |
| if (rc == SQL_SUCCESS_WITH_INFO) |
| return IDS_22_001; |
| else |
| return IDS_193_DRVTODS_ERROR; |
| } |
| DataLen = translateLength; |
| } |
| else //just copy |
| { |
| // source and target charset are the same - no translation needed |
| if (DataLen > OutLen) |
| { |
| DataLen = OutLen; |
| return IDS_22_001; |
| } |
| memcpy(outDataPtr, DataPtr, DataLen); |
| } |
| } |
| else |
| { |
| //Translate from DriverLocale to UTF8 |
| rc = iconv->TranslateUTF8(FALSE, (char*)DataPtr, DataLen, (char*)outDataPtr, OutLen+1, (int*)&translateLength, (char*)errorMsg); |
| if (rc != SQL_SUCCESS) |
| { |
| if (rc == SQL_SUCCESS_WITH_INFO) |
| return IDS_22_001; |
| else |
| return IDS_193_DRVTODS_ERROR; |
| } |
| DataLen = translateLength; |
| } |
| if (Offset != 0) |
| { |
| if(targetPrecision > SHRT_MAX) |
| *(unsigned int *)targetDataPtr = DataLen; |
| else |
| *(unsigned short *)targetDataPtr = DataLen; |
| } |
| } |
| |
| if (ODBCDataType == SQL_WCHAR || ODBCDataType == SQL_WVARCHAR) |
| { |
| tempLen = targetLength/2-DataLen-Offset-1; |
| u_memset((UChar*)outDataPtr+DataLen, L' ', tempLen); |
| DataLen = (DataLen+tempLen)*2; |
| } |
| } |
| else |
| { |
| if (OutLen < DataLen) |
| return IDS_22_001; |
| memcpy(outDataPtr, DataPtr, DataLen); |
| if (Offset != 0) //When Datalen = 0, length was not stored in buffer |
| { |
| if(targetPrecision > SHRT_MAX) |
| *(unsigned int *)targetDataPtr = DataLen; |
| else |
| *(unsigned short *)targetDataPtr = DataLen; |
| } |
| } |
| if (byteSwap) |
| { |
| if (Datatype_Dependent_Swap((BYTE *)outDataPtr-Offset, SQLDataType, targetCharSet, DataLen, IEEE_TO_TANDEM) != STATUS_OK) |
| return IDS_HY_000; |
| } |
| if (ODBCDataType == SQL_CHAR && SQLDataType != SQLTYPECODE_BOOLEAN || ODBCDataType == SQL_VARCHAR) |
| memset((unsigned char *)outDataPtr+DataLen, ' ', targetLength-DataLen-Offset-1); |
| } |
| if (dataTruncatedWarning) |
| retCode = IDS_01_S07; |
| |
| return retCode; |
| } |
| |
| |
| unsigned long ODBC::ConvertCharToNumeric(SQLPOINTER srcDataPtr, |
| SQLINTEGER srcLength, |
| double &dTmp) |
| { |
| int tempLen; |
| char cTmpBuf[100]; |
| char *errorCharPtr; |
| |
| if (srcLength == SQL_NTS ) |
| tempLen = strlen((const char *)srcDataPtr); |
| else |
| tempLen = srcLength; |
| if (tempLen >= sizeof(cTmpBuf)) |
| return IDS_22_003; |
| strncpy(cTmpBuf, (const char *)srcDataPtr, tempLen); |
| cTmpBuf[tempLen] = '\0'; |
| rTrim(cTmpBuf); |
| tempLen = strlen(cTmpBuf); |
| errno = 0; |
| dTmp = strtod(cTmpBuf, &errorCharPtr); |
| if (errno == ERANGE || errorCharPtr < (cTmpBuf + tempLen)) |
| return IDS_22_003; |
| return SQL_SUCCESS; |
| } |
| |
| unsigned long ODBC::ConvertCharToInt64(SQLPOINTER srcDataPtr, |
| SQLINTEGER srcLength, |
| __int64 &tempVal64) |
| { |
| int tempLen; |
| char cTmpBuf[100]; |
| bool truncation = false; |
| |
| if (srcLength == SQL_NTS ) |
| tempLen = strlen((const char *)srcDataPtr); |
| else |
| tempLen = srcLength; |
| if (tempLen >= sizeof(cTmpBuf)) |
| return IDS_22_003; |
| strncpy(cTmpBuf, (const char *)srcDataPtr, tempLen); |
| cTmpBuf[tempLen] = '\0'; |
| rTrim(cTmpBuf); |
| |
| if (!ctoi64(cTmpBuf, tempVal64, &truncation )) |
| return IDS_22_003; |
| if (truncation) |
| return IDS_22_001; |
| |
| return SQL_SUCCESS; |
| } |
| |
| |
| unsigned long ODBC::ConvertCharWithDecimalToInt64(SQLPOINTER srcDataPtr, |
| SQLINTEGER srcLength, |
| __int64 &integralPart, |
| __int64 &decimalPart) |
| { |
| int tempLen; |
| int integralLen; |
| int decimalLen; |
| char cTmpBuf[100]; |
| char *integral; |
| char *decimal; |
| bool truncation = false; |
| |
| if (srcLength == SQL_NTS ) |
| tempLen = strlen((const char *)srcDataPtr); |
| else |
| tempLen = srcLength; |
| if (tempLen >= sizeof(cTmpBuf)) |
| return IDS_22_003; |
| strncpy(cTmpBuf, (const char *)srcDataPtr, tempLen); |
| cTmpBuf[tempLen] = '\0'; |
| integral = cTmpBuf; |
| if ((decimal = strchr(integral, '.')) != NULL) |
| { |
| integralLen = decimal - integral; |
| *decimal++ = '\0'; |
| decimalLen = tempLen - integralLen -1; |
| } |
| if (!ctoi64(integral, integralPart, &truncation )) |
| return IDS_22_003; |
| if (decimal != NULL) |
| { |
| if (!ctoi64(decimal, decimalPart, &truncation )) |
| return IDS_22_003; |
| } |
| else |
| decimalPart = 0; |
| if (truncation) |
| return IDS_22_001; |
| return SQL_SUCCESS; |
| } |
| |
| SQLRETURN ODBC::ConvertCharToSQLDate(SQLPOINTER srcDataPtr, SQLINTEGER srcLength, SWORD ODBCDataType, |
| SQLPOINTER targetPtr, SQLSMALLINT targetPrecision) |
| { |
| char in_value[50]; |
| short datetime_parts[8]; |
| char *token; |
| short i; |
| SQLUINTEGER fraction_part=0; |
| char delimiters[3]; |
| int tempLen; |
| char sFraction[10]; |
| char* pDate = (char*)srcDataPtr; |
| bool bWMFormat = false; |
| char * saveptr=NULL; |
| |
| if (targetPrecision > 9) |
| return SQL_ERROR; |
| |
| if (srcLength == SQL_NTS ) |
| tempLen = strlen((const char *)srcDataPtr); |
| else |
| tempLen = srcLength; |
| if (tempLen > sizeof(in_value)-1) |
| return SQL_ERROR; |
| |
| if (gDrvrGlobal.gSpecial_1 && tempLen == (short)strspn(pDate, "1234567890")) |
| { |
| if (tempLen < 8 && tempLen > 5) |
| { |
| char sTmp[7]; |
| int century; |
| int year; |
| int month; |
| int day; |
| |
| memset(sTmp, '0', sizeof(sTmp)); |
| strncpy(sTmp+ sizeof(sTmp) - tempLen, pDate, tempLen); |
| |
| century = (19 + sTmp[0] - '0'); |
| year = century * 100 + (sTmp[1] - '0') * 10 + (sTmp[2] - '0'); |
| month = (sTmp[3] - '0') * 10 + (sTmp[4] - '0'); |
| day = (sTmp[5] - '0') * 10 + (sTmp[6] - '0'); |
| |
| sprintf(in_value,"%d/%02d/%02d",year,month,day); |
| tempLen = strlen(in_value); |
| bWMFormat = true; |
| } |
| } |
| |
| if (bWMFormat == false) |
| { |
| strncpy(in_value, (const char *)srcDataPtr, tempLen); |
| in_value[tempLen] = '\0'; |
| } |
| |
| // check if date, time, timestamp is in escape sequence format |
| // if yes, check format and convert {,},d,t,ts,' to blanks |
| |
| if (tempLen != (short)strspn(in_value, "1234567890:/.- ")) |
| { |
| if (tempLen != (short)strspn(in_value, "1234567890:/.-{}dts\' ")) |
| return SQL_ERROR; |
| |
| int nIndex = 0; |
| int nIteration = 0; |
| char cLastDel = 0; |
| char cChar; |
| |
| while( TRUE ) |
| { |
| while( in_value[ nIndex ] == ' ' ) nIndex++; |
| cChar = in_value[ nIndex ]; |
| |
| if( cChar == 0 ) |
| { |
| if( cLastDel != '}' || nIteration != 5 ) return(SQL_ERROR); |
| else break; |
| } |
| |
| if( cChar == '{' || cChar == 'd' || cChar == 't' || |
| cChar == '\'' || cChar == '}') |
| { |
| |
| switch ( nIteration++ ) |
| { |
| case 0: |
| if( cChar != '{' ) return(SQL_ERROR); |
| break; |
| case 1: |
| if( cChar != 'd' && cChar != 't' ) return(SQL_ERROR); |
| if( cChar == 't' && in_value[ nIndex + 1] == 's' ) |
| in_value[ nIndex + 1 ] = ' '; |
| break; |
| case 2: |
| if( cChar != '\'' ) return(SQL_ERROR); |
| break; |
| case 3: |
| if( cChar != '\'' ) return(SQL_ERROR); |
| break; |
| case 4: |
| if( cChar != '}' ) return(SQL_ERROR); |
| break; |
| default: |
| return(SQL_ERROR); |
| break; |
| } |
| |
| cLastDel = cChar; |
| in_value[ nIndex ] = ' '; |
| } |
| nIndex++; |
| } |
| } |
| |
| for (i = 0 ; i < 8 ; i++) |
| datetime_parts[i] = 0; |
| if (strpbrk(in_value, "/-") == NULL) |
| { |
| if ((ODBCDataType == SQL_DATE) || (ODBCDataType == SQL_TIMESTAMP)) |
| return SQL_ERROR; //not a valid date literal, return error : JoyJ |
| i = 3; |
| strcpy(delimiters, ":"); |
| |
| struct tm *newtime; |
| time_t long_time; |
| |
| time( &long_time ); /* Get time as long integer. */ |
| newtime = localtime( &long_time ); /* Convert to local time. */ |
| datetime_parts[0] = (short)(newtime->tm_year+1900); |
| datetime_parts[1] = (short)(newtime->tm_mon+1); |
| datetime_parts[2] = (short)newtime->tm_mday; |
| } |
| else |
| { |
| i = 0; |
| strcpy(delimiters, "/-"); |
| } |
| #ifndef unixcli |
| for (token = strtok(in_value, delimiters) ; token != NULL && i < 6 ; |
| token = strtok(NULL, delimiters), i++) |
| #else |
| for (token = strtok_r(in_value, delimiters,&saveptr) ; token != NULL && i < 6 ; |
| token = strtok_r(NULL, delimiters,&saveptr), i++) |
| #endif |
| { |
| datetime_parts[i] = (short)atoi(token); |
| if (i == 1) |
| strcpy(delimiters, ": "); |
| else |
| if (i == 2) |
| strcpy(delimiters, ":"); |
| else |
| if (i == 4) |
| strcpy(delimiters, "."); |
| } |
| if (token != NULL) |
| { |
| rTrim(token); |
| memset(sFraction, 0, sizeof(sFraction)); |
| memset(sFraction, '0', 9); |
| memcpy(sFraction, token, strlen(token)); |
| sFraction[targetPrecision] = 0; |
| fraction_part = atol(sFraction); |
| |
| datetime_parts[6] = (short)(fraction_part / 1000); |
| datetime_parts[7] = (short)(fraction_part % 1000); |
| } |
| if (! checkDatetimeValue(datetime_parts)) |
| return SQL_ERROR; |
| switch (ODBCDataType) { |
| case SQL_DATE: |
| { |
| DATE_TYPES *dateTmp = (DATE_TYPES *)targetPtr; |
| dateTmp->year = datetime_parts[0]; |
| dateTmp->month = (unsigned char)datetime_parts[1]; |
| dateTmp->day = (unsigned char)datetime_parts[2]; |
| } |
| break; |
| case SQL_TIME: |
| { |
| TIME_TYPES *timeTmp = (TIME_TYPES *)targetPtr; |
| timeTmp->hour=(unsigned char)datetime_parts[3]; |
| timeTmp->minute=(unsigned char)datetime_parts[4]; |
| timeTmp->second=(unsigned char)datetime_parts[5]; |
| } |
| break; |
| case SQL_TIMESTAMP: |
| { |
| TIMESTAMP_TYPES *timeStampTmp = (TIMESTAMP_TYPES *)targetPtr; |
| |
| timeStampTmp->year=datetime_parts[0]; |
| timeStampTmp->month=(unsigned char)datetime_parts[1]; |
| timeStampTmp->day=(unsigned char)datetime_parts[2]; |
| timeStampTmp->hour=(unsigned char)datetime_parts[3]; |
| timeStampTmp->minute=(unsigned char)datetime_parts[4]; |
| timeStampTmp->second=(unsigned char)datetime_parts[5]; |
| if (targetPrecision > 0) |
| memcpy(&timeStampTmp->fraction, &fraction_part, sizeof(UDWORD_P)); |
| else |
| memset(&timeStampTmp->fraction, 0, sizeof(UDWORD_P)); |
| |
| } |
| break; |
| default: |
| return SQL_ERROR; |
| } |
| return SQL_SUCCESS; |
| } |
| |
| //====================================================================== |
| void ODBC::getMaxNum( long precision, |
| long scale, |
| unsigned __int64 &integralMax, |
| unsigned __int64 &decimalMax) |
| { |
| |
| decimalMax = 0; |
| integralMax = 0; |
| int i; |
| |
| for(i=0; i < precision - scale; i++) |
| integralMax= integralMax * 10 + 9; |
| |
| for(i=0; i < scale; i++) |
| decimalMax = decimalMax * 10 + 9; |
| |
| } |
| |
| // |
| // This routine will attempt to convert a value into integralPart, decimalPart, negative, leadZeros |
| // |
| // for example |
| // -2.145 will have integralPart = 2, decimalPart = 145, negative = TRUE; leadZeros = 0 (no leading zero) |
| // 6.09811 will have integralPart = 6, decimalPart = 9811(not 09811), negative = FALSE, leadZeros = 1 (1 leading zero) |
| short ODBC::ConvertCharToInt64Num(const char *srcDataPtr, |
| __int64 &integralPart, |
| __int64 &decimalPart, |
| BOOL &negative, |
| long &leadZeros) |
| { |
| // Return values -1 - Out of Range |
| // -2 - Illegal numeric value |
| // 0 - success |
| |
| char *tempPtr,*tempPtr1,*tempPtr2; |
| int tempLen = 0; |
| double dTmp; |
| char *errorCharPtr; |
| BOOL decimalFound = false; |
| BOOL countZeros = true; |
| |
| leadZeros = 0; |
| decimalPart = 0; |
| integralPart = 0; |
| negative = FALSE; |
| |
| if (srcDataPtr == NULL) |
| return -2; |
| tempPtr = (char *)srcDataPtr; |
| trim(tempPtr); |
| if( strspn( tempPtr, "+-0123456789.eE" ) == strlen( tempPtr) ) |
| { |
| if( strspn( tempPtr, "+-0123456789." ) != strlen( tempPtr) ) |
| { |
| char sTmp[20]; |
| errno = 0; |
| dTmp = strtod(srcDataPtr, &errorCharPtr); |
| if (errno == ERANGE || errorCharPtr < (srcDataPtr + strlen(srcDataPtr))) |
| return -1; |
| sprintf(sTmp,"%lf",dTmp); |
| strcpy(tempPtr,sTmp); |
| rSup(tempPtr); |
| } |
| } |
| else |
| return -2; |
| |
| switch (*tempPtr) |
| { |
| case '+': |
| tempPtr++; |
| break; |
| case '-': |
| negative = TRUE; |
| tempPtr++; |
| break; |
| default: |
| break; |
| } |
| |
| tempPtr1 = strchr( tempPtr, '.' ); |
| if( tempPtr1 == NULL ) |
| { |
| if( strlen(tempPtr) > 33 ) |
| return -1; |
| } |
| else |
| { |
| if( tempPtr1 - tempPtr > 33 ) |
| return -1; |
| } |
| |
| while (*tempPtr != '\0') |
| { |
| if (*tempPtr == '.') |
| { |
| decimalFound = TRUE; |
| break; |
| } |
| if (*tempPtr >= '0' && *tempPtr <= '9') |
| { |
| integralPart= integralPart * 10 + (*tempPtr - '0'); |
| ++tempPtr; |
| } |
| else |
| return -2; |
| |
| } |
| |
| if (decimalFound) |
| { |
| // to get rid of trailing zeros |
| tempLen = strlen(tempPtr); |
| if ((tempPtr2 = (char*)malloc(tempLen + 1)) == NULL) |
| return -1; |
| strcpy(tempPtr2, tempPtr); |
| tempPtr2[tempLen] = '\0'; |
| |
| for (int i= tempLen - 1; i >=0; i--) |
| { |
| if (tempPtr2[i] == '0') |
| tempPtr2[i] = '\0'; |
| else |
| break; |
| } |
| tempPtr = tempPtr2; |
| |
| while (*++tempPtr != '\0') |
| { |
| if (*tempPtr >= '0' && *tempPtr <= '9') |
| { |
| decimalPart= decimalPart * 10 + (*tempPtr - '0'); |
| if(*tempPtr != '0' ) |
| countZeros = false; |
| |
| if(*tempPtr == '0' && countZeros ) |
| leadZeros++; |
| } |
| else |
| { |
| if (tempPtr2 != NULL) |
| free(tempPtr2); |
| |
| return -1; |
| } |
| } |
| |
| if (tempPtr2 != NULL) |
| free(tempPtr2); |
| } |
| |
| return 0; |
| } |
| |
| long ODBC::getDigitCount(__int64 value) |
| { |
| int i; |
| static __int64 decValue[] = {0, |
| 9, |
| 99, |
| 999, |
| 9999, |
| 99999, |
| 999999, |
| 9999999, |
| 99999999, |
| 999999999, |
| 9999999999LL, |
| 99999999999LL, |
| 999999999999LL, |
| 9999999999999LL, |
| 99999999999999LL, |
| 999999999999999LL, |
| 9999999999999999LL, |
| 99999999999999999LL, |
| 999999999999999999LL}; |
| |
| for (i = 4; i <= 16; i += 4) |
| if (value <= decValue[i]) { |
| if (value <= decValue[i-3]) |
| return(i-3); |
| if (value <= decValue[i-2]) |
| return(i-2); |
| if (value <= decValue[i-1]) |
| return(i-1); |
| else return i; |
| } |
| if (value <= decValue[17]) |
| return 17; |
| if (value <= decValue[18]) |
| return 18; |
| return 19; |
| } |
| |
| // |
| // the conversion from little endian mode to the character string |
| // |
| |
| SQLRETURN ODBC::ConvertCNumericToChar( SQL_NUMERIC_STRUCT* numericPtr, char* cTmpBuf) |
| { |
| |
| union |
| { |
| unsigned __int64 intTest[2]; |
| SQLCHAR tmpVal[SQL_MAX_NUMERIC_LEN]; |
| } tmpUnion; |
| |
| char localBuf[50]; |
| char* tempPtr = localBuf; |
| char* outBuf = localBuf; |
| |
| BOOLEAN bStart = false; |
| short offset = SQL_MAX_NUMERIC_LEN - 1; |
| |
| memset( localBuf, 0, sizeof(localBuf)); |
| memcpy( tmpUnion.tmpVal, numericPtr->val, SQL_MAX_NUMERIC_LEN ); |
| |
| if( numericPtr->sign == 2 || numericPtr->sign == 0) //ODBC 3.0 spec dictates a value of 2 for negative sign, |
| { //3.5 spec requires a 0 instead |
| strcpy( tempPtr, "-" ); //NOTE: we do not have any way to differentiate between ODBC3.0 and ODBC3.5 |
| tempPtr++; |
| } |
| |
| if( tmpUnion.intTest[1] == 0 ) |
| { |
| //AReynolds - _ui64toa expects ints to be in native endian format. |
| //SQL_NUMERIC_STRUCT value part is always in little endian, so we need |
| //to convert to big endian before calling _ui64toa |
| #ifdef BIGE |
| tmpUnion.intTest[1] = tmpUnion.intTest[0]; |
| int m,n=SQL_MAX_NUMERIC_LEN/2; |
| |
| for( m = n-1; m >= 0, n < SQL_MAX_NUMERIC_LEN; m--, n++) |
| tmpUnion.tmpVal[m] = tmpUnion.tmpVal[n]; |
| |
| tmpUnion.intTest[1] = 0; |
| #endif |
| _ui64toa( tmpUnion.intTest[0], tempPtr, 10 ); |
| } |
| else |
| { |
| //we should never enter this block of code until we support SQL_C_NUMERIC to BigNum. As of r2.3, we don't support SQL_NUMERIC_STRUCT->BigNum_vals |
| while( tmpUnion.intTest[0] != 0 || tmpUnion.intTest[1] != 0) |
| { |
| int i,a=0,b=0,current,calc=0; |
| |
| for( i = offset; i >= 0 ; i--) |
| { |
| if( tmpUnion.tmpVal[ i ] == 0 && !bStart) |
| { |
| offset--; |
| continue; |
| } |
| else |
| bStart = true; |
| |
| current = tmpUnion.tmpVal[ i ]; |
| calc = calc * 256 + current; |
| a = calc % 10; |
| b = calc / 10; |
| |
| tmpUnion.tmpVal[ i ] = b; |
| calc = a; |
| } |
| *tempPtr++ = a + '0'; |
| } |
| |
| tempPtr--; |
| |
| while (tempPtr >= outBuf ) |
| { |
| char cTmp; |
| |
| cTmp = *outBuf; |
| *(outBuf++) = *tempPtr; |
| *(tempPtr--) = cTmp; |
| } |
| |
| } |
| |
| memset(cTmpBuf, 0, numericPtr->precision + 1); |
| strncpy(cTmpBuf, localBuf, strlen(localBuf) - numericPtr->scale ); |
| if( numericPtr->scale != 0 ){ |
| strcat(cTmpBuf,"."); |
| strcat(cTmpBuf, localBuf + strlen(localBuf) - numericPtr->scale ); |
| } |
| |
| return SQL_SUCCESS; |
| } |
| |
| SQLRETURN ODBC::StripIntervalLiterals(SQLPOINTER srcDataPtr, SQLINTEGER srcLength, SWORD ODBCDataType, char* cTmpBuf) |
| { |
| |
| char in_value[128]; |
| char save_value[128]; |
| char *token; |
| short i = 0; |
| char delimiters[] = " {}\t\n"; |
| char validValue[] = "1234567890:-. "; |
| int tempLen; |
| BOOL signSet = FALSE; |
| int ch = '\''; |
| char *pdest; |
| int bresult, eresult; |
| char *saveptr=NULL; |
| |
| if (srcLength == SQL_NTS ) |
| tempLen = strlen((const char *)srcDataPtr); |
| else |
| tempLen = srcLength; |
| strncpy(in_value, (const char *)srcDataPtr, tempLen); |
| in_value[tempLen] = '\0'; |
| |
| if(in_value[0] != '{' && in_value[tempLen-1] != '}') // No Interval Literal just the value |
| { |
| i = strspn(in_value, validValue); |
| if (i < strlen(in_value)) return SQL_ERROR; |
| strcpy(cTmpBuf, in_value); |
| } |
| else |
| { |
| pdest = strchr( in_value, ch ); |
| if( pdest == NULL ) return SQL_ERROR; |
| bresult = pdest - in_value + 1; |
| /* Search backward. */ |
| pdest = strrchr( in_value, ch ); |
| if( pdest == NULL ) return SQL_ERROR; |
| eresult = pdest - in_value + 1; |
| |
| if (bresult == eresult) return SQL_ERROR; |
| strncpy(save_value, in_value+bresult, eresult-bresult); |
| save_value[eresult-bresult-1] = '\0'; |
| strnset(in_value+bresult-1,' ',eresult-bresult+1); |
| #ifndef unixcli |
| token = strtok( in_value, delimiters ); |
| #else |
| token = strtok_r( in_value, delimiters , &saveptr); |
| #endif |
| while( token != NULL ) |
| { |
| switch(i) |
| { |
| case 0: |
| if (stricmp(token, "INTERVAL") != 0) return SQL_ERROR; |
| break; |
| case 1: |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_MONTH: |
| if (strnicmp(token, "MONTH",5) != 0) return SQL_ERROR; |
| break; |
| case SQL_INTERVAL_YEAR: |
| case SQL_INTERVAL_YEAR_TO_MONTH: |
| if (strnicmp(token, "YEAR",4) != 0) return SQL_ERROR; |
| break; |
| case SQL_INTERVAL_DAY: |
| case SQL_INTERVAL_DAY_TO_HOUR: |
| case SQL_INTERVAL_DAY_TO_MINUTE: |
| case SQL_INTERVAL_DAY_TO_SECOND: |
| if (strnicmp(token, "DAY",3) != 0) return SQL_ERROR; |
| break; |
| case SQL_INTERVAL_HOUR: |
| case SQL_INTERVAL_HOUR_TO_MINUTE: |
| case SQL_INTERVAL_HOUR_TO_SECOND: |
| if (strnicmp(token, "HOUR",4) != 0) return SQL_ERROR; |
| break; |
| case SQL_INTERVAL_MINUTE: |
| case SQL_INTERVAL_MINUTE_TO_SECOND: |
| if (strnicmp(token, "MINUTE",6) != 0) return SQL_ERROR; |
| break; |
| case SQL_INTERVAL_SECOND: |
| if (strnicmp(token, "SECOND",5) != 0) return SQL_ERROR; |
| break; |
| default: |
| return SQL_ERROR; |
| } |
| break; |
| case 2: |
| if (stricmp(token, "TO") != 0) return SQL_ERROR; |
| break; |
| case 3: |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_YEAR_TO_MONTH: |
| if (strnicmp(token, "MONTH",5) != 0) return SQL_ERROR; |
| break; |
| case SQL_INTERVAL_DAY_TO_HOUR: |
| if (strnicmp(token, "HOUR",4) != 0) return SQL_ERROR; |
| break; |
| case SQL_INTERVAL_DAY_TO_MINUTE: |
| case SQL_INTERVAL_HOUR_TO_MINUTE: |
| if (strnicmp(token, "MINUTE",6) != 0) return SQL_ERROR; |
| break; |
| case SQL_INTERVAL_DAY_TO_SECOND: |
| case SQL_INTERVAL_HOUR_TO_SECOND: |
| case SQL_INTERVAL_MINUTE_TO_SECOND: |
| if (strnicmp(token, "SECOND",5) != 0) return SQL_ERROR; |
| break; |
| default: |
| return SQL_ERROR; |
| } |
| break; |
| default: |
| return SQL_ERROR; |
| } |
| // Get next token: |
| #ifndef unixcli |
| token = strtok( NULL, delimiters ); |
| #else |
| token = strtok_r( NULL, delimiters, &saveptr); |
| #endif |
| if( token != NULL ) |
| { |
| if (i == 0 && ((stricmp(token, "-") == 0) || (stricmp(token, "+") == 0))) |
| { |
| strcpy(cTmpBuf,token); |
| signSet = TRUE; |
| #ifndef unixcli |
| token = strtok( NULL, delimiters ); |
| #else |
| token = strtok_r( NULL, delimiters, &saveptr ); |
| #endif |
| } |
| } |
| i++; |
| |
| } |
| if(signSet) |
| strcat(cTmpBuf,save_value); |
| else |
| strcpy(cTmpBuf,save_value); |
| } |
| return SQL_SUCCESS; |
| } |
| |
| void ODBC::InsertBlank(char *str, short numBlank) |
| { |
| char temp[256]; |
| long length=0; |
| |
| memset(temp, ' ', numBlank); |
| length = numBlank + strlen(str); |
| length = length > 255 ? 255 : length; |
| memcpy(&temp[numBlank], str, length-numBlank); |
| temp[length] = '\0'; |
| strcpy(str, temp); |
| |
| return; |
| } |
| |
| unsigned long ODBC::CheckIntervalOverflow(char *intervalValue, SWORD ODBCDataType, SQLINTEGER targetLength, SQLSMALLINT secPrecision) |
| { |
| char *token; |
| short i = 0; |
| short j = 0; |
| char in_value[128 + 1]; |
| char delimiters[] = " :.-"; |
| char sep[5]={0,0,0,0,0}; |
| SQLINTEGER leadingPrecision; |
| unsigned __int64 integralMax; |
| unsigned __int64 decimalMax; |
| unsigned __int64 tempVal64; |
| unsigned int tempVal; |
| char *saveptr=NULL; |
| |
| // already exceeds the target length |
| if (strlen(intervalValue) > targetLength) return IDS_22_015; |
| |
| if (intervalValue[0] == '-') |
| strcpy(in_value, intervalValue+1); |
| else |
| strcpy(in_value, intervalValue); |
| |
| leadingPrecision = GetIntervalLeadingPrecision(ODBCDataType, targetLength, secPrecision); |
| |
| j = strcspn(in_value, delimiters); |
| sep[i] = in_value[j]; |
| #ifndef unixcli |
| token = strtok(in_value, delimiters); |
| #else |
| token = strtok_r(in_value, delimiters,&saveptr); |
| #endif |
| while( token != NULL ) |
| { |
| switch(i) |
| { |
| case 0: |
| getMaxNum(leadingPrecision, 0, integralMax, decimalMax); |
| tempVal64 = _atoi64(token); |
| if (tempVal64 > integralMax) return IDS_22_015; |
| break; |
| |
| case 1: |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_SECOND: |
| if (secPrecision == 0) return IDS_22_015; |
| if (sep[i-1] != '.') return IDS_22_018; |
| getMaxNum(secPrecision, 0, integralMax, decimalMax); |
| tempVal64 = _atoi64(token); |
| if (tempVal64 > integralMax) return IDS_22_015; |
| break; |
| case SQL_INTERVAL_YEAR_TO_MONTH: |
| if (sep[i-1] != '-') return IDS_22_018; |
| // month value must be between 0 and 11, inclusive |
| tempVal = atoi(token); |
| if (tempVal < 0 || tempVal > 11) return IDS_22_015; |
| break; |
| case SQL_INTERVAL_DAY_TO_HOUR: |
| case SQL_INTERVAL_DAY_TO_MINUTE: |
| case SQL_INTERVAL_DAY_TO_SECOND: |
| if (sep[i-1] != ' ') return IDS_22_018; |
| // hour value must be between 0 and 23, inclusive |
| tempVal = atoi(token); |
| if (tempVal < 0 || tempVal > 23) return IDS_22_015; |
| break; |
| case SQL_INTERVAL_HOUR_TO_MINUTE: |
| case SQL_INTERVAL_HOUR_TO_SECOND: |
| case SQL_INTERVAL_MINUTE_TO_SECOND: |
| if (sep[i-1] != ':') return IDS_22_018; |
| // minute or second value must be between 0 and 59, inclusive |
| tempVal = atoi(token); |
| if (tempVal < 0 || tempVal > 59) return IDS_22_015; |
| break; |
| default: |
| return IDS_22_018; |
| } |
| break; |
| |
| case 2: |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_DAY_TO_MINUTE: |
| case SQL_INTERVAL_DAY_TO_SECOND: |
| case SQL_INTERVAL_HOUR_TO_SECOND: |
| if (sep[i-1] != ':') return IDS_22_018; |
| // minute or second value must be between 0 and 59, inclusive |
| tempVal = atoi(token); |
| if (tempVal < 0 || tempVal > 59) return IDS_22_015; |
| break; |
| case SQL_INTERVAL_MINUTE_TO_SECOND: |
| if (secPrecision == 0) return IDS_22_015; |
| if (sep[i-1] != '.') return IDS_22_018; |
| getMaxNum(secPrecision, 0, integralMax, decimalMax); |
| tempVal64 = _atoi64(token); |
| if (tempVal64 > integralMax) return IDS_22_015; |
| break; |
| default: |
| return IDS_22_018; |
| } |
| break; |
| |
| case 3: |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_DAY_TO_SECOND: |
| if (sep[i-1] != ':') return IDS_22_018; |
| // second value must be between 0 and 59, inclusive |
| tempVal = atoi(token); |
| if (tempVal < 0 || tempVal > 59) return IDS_22_015; |
| break; |
| case SQL_INTERVAL_HOUR_TO_SECOND: |
| if (secPrecision == 0) return IDS_22_015; |
| if (sep[i-1] != '.') return IDS_22_018; |
| getMaxNum(secPrecision, 0, integralMax, decimalMax); |
| tempVal64 = _atoi64(token); |
| if (tempVal64 > integralMax) return IDS_22_015; |
| break; |
| default: |
| return IDS_22_018; |
| } |
| break; |
| |
| case 4: |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_DAY_TO_SECOND: |
| if (secPrecision == 0) return IDS_22_015; |
| if (sep[i-1] != '.') return IDS_22_018; |
| getMaxNum(secPrecision, 0, integralMax, decimalMax); |
| tempVal64 = _atoi64(token); |
| if (tempVal64 > integralMax) return IDS_22_015; |
| break; |
| default: |
| return IDS_22_018; |
| } |
| break; |
| |
| default: |
| return IDS_22_018; |
| } |
| // Get next token: |
| i++; |
| j += strcspn(in_value+j+1, delimiters)+1; |
| if (j > 128) |
| return IDS_22_018; |
| sep[i] = in_value[j]; |
| #ifndef unixcli |
| token = strtok(NULL, delimiters); |
| #else |
| token = strtok_r(NULL, delimiters, &saveptr); |
| #endif |
| } |
| |
| return SQL_SUCCESS; |
| } |
| |
| SQLINTEGER ODBC::GetIntervalLeadingPrecision(SWORD ODBCDataType, SQLINTEGER targetLength, SQLSMALLINT secPrecision) |
| { |
| SQLINTEGER leadingPrecision = 0; |
| switch (ODBCDataType) |
| { |
| case SQL_INTERVAL_SECOND: |
| if (secPrecision == 0) |
| leadingPrecision = targetLength-1; |
| else |
| leadingPrecision = targetLength-secPrecision-2; |
| break; |
| case SQL_INTERVAL_DAY_TO_SECOND: |
| if (secPrecision == 0) |
| leadingPrecision = targetLength-10; |
| else |
| leadingPrecision = targetLength-secPrecision-11; |
| break; |
| case SQL_INTERVAL_HOUR_TO_SECOND: |
| if (secPrecision == 0) |
| leadingPrecision = targetLength-7; |
| else |
| leadingPrecision = targetLength-secPrecision-8; |
| break; |
| case SQL_INTERVAL_MINUTE_TO_SECOND: |
| if (secPrecision == 0) |
| leadingPrecision = targetLength-4; |
| else |
| leadingPrecision = targetLength-secPrecision-5; |
| break; |
| case SQL_INTERVAL_YEAR: |
| case SQL_INTERVAL_MONTH: |
| case SQL_INTERVAL_DAY: |
| case SQL_INTERVAL_HOUR: |
| case SQL_INTERVAL_MINUTE: |
| leadingPrecision = targetLength-1; |
| break; |
| case SQL_INTERVAL_YEAR_TO_MONTH: |
| case SQL_INTERVAL_DAY_TO_HOUR: |
| case SQL_INTERVAL_HOUR_TO_MINUTE: |
| leadingPrecision = targetLength-4; |
| break; |
| case SQL_INTERVAL_DAY_TO_MINUTE: |
| leadingPrecision = targetLength-7; |
| break; |
| default: |
| break; |
| } |
| |
| return leadingPrecision; |
| } |