trafodion-codereview mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From DaveBirdsall <...@git.apache.org>
Subject [GitHub] trafodion pull request #1310: [TRAFODION-2816] ODBC data convert function sp...
Date Tue, 06 Feb 2018 20:49:00 GMT
Github user DaveBirdsall commented on a diff in the pull request:

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


---

Mime
View raw message