Github user DaveBirdsall commented on a diff in the pull request:

    https://github.com/apache/trafodion/pull/1310#discussion_r168055820
  
    --- 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);
    +                else
    +                    strncpy(cTmpBuf, (char *)srcDataPtr, tempLen);
                     break;
    -            case SQL_C_SHORT:
    -            case SQL_C_SSHORT:
    -                dTmp = *(SSHORT *)srcDataPtr;
    +
    +            case SQL_C_NUMERIC:
    +                ConvertCNumericToChar((SQL_NUMERIC_STRUCT*)srcDataPtr, 
cTmpBuf);
    +                tempLen = strlen(cTmpBuf);
                     break;
    -            case SQL_C_USHORT:
    -                dTmp = *(USHORT *)srcDataPtr;
    +    
    +            case SQL_C_FLOAT:
    +            case SQL_C_DOUBLE:
    +                if(CDataType == SQL_C_DOUBLE)
    +                    dTmp = *(DOUBLE *)srcDataPtr;
    +                else
    +                    dTmp = *(SFLOAT *)srcDataPtr;
    +
    +                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;
    +                }
    +                break;
    +    
    +            case SQL_C_UTINYINT:
    +            case SQL_C_BIT:
    +                sprintf(cTmpBuf, "%u", *(UCHAR *)srcDataPtr);
                     break;
                 case SQL_C_TINYINT:
                 case SQL_C_STINYINT:
    -                dTmp = *(SCHAR *)srcDataPtr;
    +                sprintf(cTmpBuf, "%d", *(SCHAR *)srcDataPtr);
                     break;
    -            case SQL_C_UTINYINT:
    -            case SQL_C_BIT:
    -                dTmp = *(UCHAR *)srcDataPtr;
    +    
    +            case SQL_C_USHORT:
    +                sprintf(cTmpBuf, "%u", *(USHORT *)srcDataPtr);
                     break;
    -            case SQL_C_SLONG:
    -            case SQL_C_LONG:
    -                dTmp = *(SLONG_P *)srcDataPtr;
    +            case SQL_C_SHORT:
    +            case SQL_C_SSHORT:
    +                sprintf(cTmpBuf, "%d", *(SSHORT *)srcDataPtr);
                     break;
    +    
                 case SQL_C_ULONG:
                     dTmp = *(ULONG_P *)srcDataPtr;
    +                sprintf(cTmpBuf, "%u", *(ULONG_P *)srcDataPtr);
                     break;
    -            case SQL_C_FLOAT:
    -                dTmp = *(SFLOAT *)srcDataPtr;
    +            case SQL_C_SLONG:
    +            case SQL_C_LONG:
    +                sprintf(cTmpBuf, "%d", *(SLONG_P *)srcDataPtr);
                     break;
    -            case SQL_C_DOUBLE:
    -                dTmp = *(DOUBLE *)srcDataPtr;
    +    
    +            case SQL_C_SBIGINT:
    +                sprintf(cTmpBuf, "%lld", *(__int64*)srcDataPtr);
    +                DataPtr = cTmpBuf;
                     break;
    -            case SQL_C_BINARY:
    -                DataPtr = srcDataPtr;
    +            case SQL_C_UBIGINT:
    +                sprintf(cTmpBuf, "%llu", *(unsigned __int64*)srcDataPtr);
    +                DataPtr = cTmpBuf;
                     break;
    -            case SQL_C_DEFAULT:
    -                if (ODBCAppVersion >= SQL_OV_ODBC3)
    -                    DataPtr = srcDataPtr;
    +    
    +            case SQL_C_INTERVAL_MONTH:
    +                intervalTmp = (SQL_INTERVAL_STRUCT *)srcDataPtr;
    +                if (intervalTmp->interval_sign == SQL_TRUE)
    +                    dTmp = -(intervalTmp->intval.year_month.month);
                     else
    -                {
    -                    retCode = ConvertCharToNumeric(srcDataPtr, srcLength, 
dTmp);
    -                    if (retCode!= SQL_SUCCESS)
    -                        return retCode;
    -                }
    +                    dTmp = intervalTmp->intval.year_month.month;
    +                sprintf(cTmpBuf, "%lf", dTmp);
                     break;
    -            case SQL_C_SBIGINT:
    -                dTmp = *(__int64 *)srcDataPtr;
    +            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;
    +                sprintf(cTmpBuf, "%lf", dTmp);
                     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;
    +            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;
    +                sprintf(cTmpBuf, "%lf", dTmp);
    +                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;
    +                sprintf(cTmpBuf, "%lf", dTmp);
    +                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;
    +                sprintf(cTmpBuf, "%lf", dTmp);
    +                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;
    +                sprintf(cTmpBuf, "%lf", dTmp);
                     break;
    +    
                 default:
                     return IDS_07_006;
    -            }
    -            if (DataPtr == NULL)
    -            {
    -                if(dTmp < 0)
    +        }
    +            retCode = Ascii_To_Bignum_Helper(cTmpBuf,
    +                            strlen(cTmpBuf),
    +                            (char*)cTmpBuf2,
    +                            targetLength,
    +                            targetPrecision,
    +                            targetScale,
    +                            SQLDataType,
    +                            &dataTruncatedWarning);
    +
    +            if(retCode != SQL_SUCCESS)
    +                return retCode;
    +    
    +            if (dataTruncatedWarning)
    +                retCode = IDS_01_S07;
    +
    +            memcpy(targetDataPtr, cTmpBuf2, targetLength);
    +    }
    +    else
    +    {
    +        getMaxNum(targetPrecision, targetScale, integralMax, decimalMax);
    +        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 > CHARTMPLEN - 1)
    +                    strncpy(cTmpBuf, (char *)srcDataPtr, CHARTMPLEN - 1);
    --- End diff --
    
    Ignore this comment. The array is already initialized to null everywhere.


---

Reply via email to