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 Mon, 05 Feb 2018 19:59:26 GMT
Github user DaveBirdsall commented on a diff in the pull request:

    https://github.com/apache/trafodion/pull/1310#discussion_r166082247
  
    --- 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 --
    
    Shouldn't we add a null terminator? I don't see tempLen being passed to Ascii_To_Bignum_Helper
below so I assume it is depending on the presence of a null terminator.


---

Mime
View raw message