blob: c26fbbb13a1ce61b91a74d887b20f4d4a4bb70b5 [file] [log] [blame]
/**********************************************************************
// @@@ 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';
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;
getMaxNum(targetPrecision, targetScale, integralMax, decimalMax);
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;
getMaxNum(targetPrecision, targetScale, integralMax, decimalMax);
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;
getMaxNum(targetPrecision, targetScale, integralMax, decimalMax);
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;
getMaxNum(targetPrecision, targetScale, integralMax, decimalMax);
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;
getMaxNum(targetPrecision, targetScale, integralMax, decimalMax);
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;
}