This is an automated email from the ASF dual-hosted git repository.

dbirdsall pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafodion.git


The following commit(s) were added to refs/heads/master by this push:
     new 1b00da8  fix TRAFODION-3262
     new 0ab8d50  Merge pull request #1818 from SuJinpei/M-9933
1b00da8 is described below

commit 1b00da8cdb55dc0184371ecb94ad46295f6d7e04
Author: SuJinpei <[email protected]>
AuthorDate: Fri Mar 29 03:09:58 2019 +0800

    fix TRAFODION-3262
---
 .../odbc/odbcclient/unixcli/cli/drvrglobal.cpp     |  86 ++++-------------
 .../odbc/odbcclient/unixcli/cli/drvrglobal.h       |   2 +-
 .../odbc/odbcclient/unixcli/cli/sqltocconv.cpp     |   4 +-
 win-odbc64/odbcclient/drvr35/drvrglobal.cpp        | 106 ++++++---------------
 win-odbc64/odbcclient/drvr35/drvrglobal.h          |   2 +-
 win-odbc64/odbcclient/drvr35/sqltocconv.cpp        |   7 +-
 6 files changed, 60 insertions(+), 147 deletions(-)

diff --git a/core/conn/unixodbc/odbc/odbcclient/unixcli/cli/drvrglobal.cpp 
b/core/conn/unixodbc/odbc/odbcclient/unixcli/cli/drvrglobal.cpp
old mode 100644
new mode 100755
index 90fd4f3..4d51846
--- a/core/conn/unixodbc/odbc/odbcclient/unixcli/cli/drvrglobal.cpp
+++ b/core/conn/unixodbc/odbc/odbcclient/unixcli/cli/drvrglobal.cpp
@@ -884,79 +884,35 @@ char* rSup( char* string )
        return string;
 }
 
-bool use_gcvt(double number, char* string, short size)
-{
-       char *buffer,*temp ;
-       int length;
-
-       temp = gcvt (number, size, string);
-       length = strlen(temp);
-       buffer = (char *) malloc (length + 2);
-       if (buffer==NULL)
-               return false;
-
-       strcpy(buffer,temp);
-       if (temp[length-1] == '.')
-       {
-               strcpy(buffer,temp);
-               strcat(buffer,"0");
-       }
-       if (temp[0] == '.')
-       {
-               strcpy( buffer, "0");
-               strcat( buffer, temp);
-       }
-       strcpy(string,buffer);
-       free (buffer);
-
-       if (strlen(string)>size)
-               return false;
-       else
-               return true;
-}
-
+/* double_to_char:
+*  number: the number to be converted to char string.
+*  precision: the number of digits after the decimal point(0 <= precision <= 
DBL_DIG).
+*  string: the buffer to receive a null terminated string result on success.
+*  size: the buffer size of string.
+*
+*  return: true on succeeded, false on failed.
+*/
 bool double_to_char (double number, int precision, char* string, short size)
 {
-    bool rc = false;
-    char format[16] = { '\0' };
+    char format[8] = { '\0' };
     size_t actualLen = 0;
 
-    // make sure any precision of possible double value can be format to the 
buf. 
-        char buf[MAX_DOUBLE_TO_CHAR_LEN] = { '\0' };
-
-    // precision should less than size
-    precision = precision < size ? precision : size - 1;
+    // make sure any precision of possible double value can be format to the 
buf.
+    char buf[MAX_DOUBLE_TO_CHAR_LEN] = { '\0' };
 
     // precission should be limit to a reasonable range.
-    if ((precision < 0) || (precision >(DBL_MANT_DIG - DBL_MIN_EXP))) {
-        goto fun_exit;
+    if ((precision < 0) || (precision > DBL_DIG))
+        return false;
+
+    if ((sprintf(format, "%%.%dlg", (precision > FLT_DIG) ? (precision + 2) : 
(precision + 3)) < 0) ||
+        ((actualLen = sprintf(buf, format, number)) < 0) ||
+        (actualLen > size)) {
+        return false;
     }
 
-    // we want to return reasonable value even when caller didn't provide 
sufficiently buffer. 
-    // here using loop because actualLen may increase even precision decrease 
when fix-point
-    // notation to exponential notation. for example:
-    // for double d = 12345678.9, the caller only provide size=8.
-    // d will first convert to "1.234568e+07", actualLen == 12. then convert 
to "1.2e+07".
-    do {
-        if (sprintf(format, "%%.%dlg", precision) < 0) {
-            goto fun_exit;
-        }
-        if ((actualLen = sprintf(buf, format, number)) < 0) {
-            goto fun_exit;
-        }
-        if (size > actualLen) {
-            strcpy(string, buf);
-            rc = true;
-            break;
-        }
-        else {
-            precision -= (actualLen - size + 1);
-        }
-    } while ((precision >= 0));
-
-fun_exit:
-    return rc;
-} 
+    strcpy(string, buf);
+    return true;
+}
 
 bool ctoi64(char* string, __int64& out, bool* truncation)
 {
diff --git a/core/conn/unixodbc/odbc/odbcclient/unixcli/cli/drvrglobal.h 
b/core/conn/unixodbc/odbc/odbcclient/unixcli/cli/drvrglobal.h
index 395dfd6..938d626 100644
--- a/core/conn/unixodbc/odbc/odbcclient/unixcli/cli/drvrglobal.h
+++ b/core/conn/unixodbc/odbc/odbcclient/unixcli/cli/drvrglobal.h
@@ -108,7 +108,7 @@ typedef int (*FPSQLGetPrivateProfileString) (
 #define        SQLERRWARN 1
 #define        ESTIMATEDCOSTRGERRWARN  2
 
-#define MAX_DOUBLE_TO_CHAR_LEN (DBL_MANT_DIG - DBL_MIN_EXP + 12)
+#define MAX_DOUBLE_TO_CHAR_LEN (DBL_DIG + 13)  // sign(1) + integer(1) + 
point(1) + fraction(DBL_DIG + 2) + e(1) + sign(1) + exp(3) + '\0' + align(2)
 
 typedef enum TRANSPORT_TYPE
 {
diff --git a/core/conn/unixodbc/odbc/odbcclient/unixcli/cli/sqltocconv.cpp 
b/core/conn/unixodbc/odbc/odbcclient/unixcli/cli/sqltocconv.cpp
index b2c0091..1932531 100644
--- a/core/conn/unixodbc/odbc/odbcclient/unixcli/cli/sqltocconv.cpp
+++ b/core/conn/unixodbc/odbc/odbcclient/unixcli/cli/sqltocconv.cpp
@@ -663,7 +663,7 @@ unsigned long ODBC::ConvertSQLToC(SQLINTEGER        
ODBCAppVersion,
                                else {
                                        dTmp = *(double *)srcDataPtr;
 //                                     _gcvt(dTmp, DBL_DIG, cTmpBuf);
-                                       if (!double_to_char (dTmp, DBL_DIG + 1, 
cTmpBuf, targetLength))
+                                       if (!double_to_char (dTmp, DBL_DIG, 
cTmpBuf, targetLength))
                                                return IDS_22_001;
                                }
                        }
@@ -1028,7 +1028,7 @@ unsigned long ODBC::ConvertSQLToC(SQLINTEGER      
ODBCAppVersion,
                                else {
                                        dTmp = *(double *)srcDataPtr;
 //                                     _gcvt(dTmp, DBL_DIG, cTmpBuf);
-                                       if (!double_to_char (dTmp, DBL_DIG + 1, 
cTmpBuf, targetLength))
+                                       if (!double_to_char (dTmp, DBL_DIG, 
cTmpBuf, targetLength))
                                                return IDS_22_001;
                                }
                        }
diff --git a/win-odbc64/odbcclient/drvr35/drvrglobal.cpp 
b/win-odbc64/odbcclient/drvr35/drvrglobal.cpp
index 7f3950f..e4ba55f 100755
--- a/win-odbc64/odbcclient/drvr35/drvrglobal.cpp
+++ b/win-odbc64/odbcclient/drvr35/drvrglobal.cpp
@@ -836,81 +836,37 @@ char* rSup( char* string )
        }
        return string;
 }
-
-bool use_gcvt(double number, char* string, short size)
-{
-       char *buffer,*temp ;
-       int length;
-
-       temp = _gcvt (number, size, string);
-       length = strlen(temp);
-       buffer = (char *) malloc (length + 2);
-       if (buffer==NULL)
-               return false;
-
-       strcpy(buffer,temp);
-       if (temp[length-1] == '.')
-       {
-               strcpy(buffer,temp);
-               strcat(buffer,"0");
-       }
-       if (temp[0] == '.')
-       {
-               strcpy( buffer, "0");
-               strcat( buffer, temp);
-       }
-       strcpy(string,buffer);
-       free (buffer);
-
-       if (strlen(string)>size)
-               return false;
-       else
-               return true;
-}
-
-bool double_to_char (double number, int precision, char* string, short size)
-{
-    bool rc = false;
-    char format[16] = { '\0' };
-    size_t actualLen = 0;
-
-    // make sure any precision of possible double value can be format to the 
buf. 
-    char buf[MAX_DOUBLE_TO_CHAR_LEN] = { '\0' };
-
-    // precision should less than size
-    precision = precision < size ? precision : size - 1;
-
-    // precission should be limit to a reasonable range.
-    if ((precision < 0) || (precision >(DBL_MANT_DIG - DBL_MIN_EXP))) {
-        goto fun_exit;
-    }
-
-    // we want to return reasonable value even when caller didn't provide 
sufficiently buffer. 
-    // here using loop because actualLen may increase even precision decrease 
when fix-point
-    // notation to exponential notation. for example:
-    // for double d = 12345678.9, the caller only provide size=8.
-    // d will first convert to "1.234568e+07", actualLen == 12. then convert 
to "1.2e+07".
-    do {
-        if (sprintf(format, "%%.%dlg", precision) < 0) {
-            goto fun_exit;
-        }
-        if ((actualLen = sprintf(buf, format, number)) < 0) {
-            goto fun_exit;
-        }
-        if (size > actualLen) {
-            strcpy(string, buf);
-            rc = true;
-            break;
-        }
-        else {
-            precision -= (actualLen - size + 1);
-        }
-    } while ((precision >= 0));
-
-fun_exit:
-       return rc;
-} 
-
+
+/* double_to_char:
+*  number: the number to be converted to char string.
+*  precision: the number of digits after the decimal point(0 <= precision <= 
DBL_DIG).
+*  string: the buffer to receive a null terminated string result on success.
+*  size: the buffer size of string.
+*
+*  return: true on succeeded, false on failed.
+*/
+bool double_to_char(double number, int precision, char* string, short size)
+{
+    char format[8] = { '\0' };
+    size_t actualLen = 0;
+
+    // make sure any precision of possible double value can be format to the 
buf.
+    char buf[MAX_DOUBLE_TO_CHAR_LEN] = { '\0' };
+
+    // precission should be limit to a reasonable range.
+    if ((precision < 0) || (precision > DBL_DIG))
+        return false;
+
+    if ((sprintf(format, "%%.%dlg", (precision > FLT_DIG) ? (precision + 2) : 
(precision + 3)) < 0) ||
+        ((actualLen = sprintf(buf, format, number)) < 0) ||
+        (actualLen > size)) {
+        return false;
+    }
+
+    strcpy(string, buf);
+    return true;
+}
+
 bool ctoi64(char* string, __int64& out, bool* truncation)
 {
        int len;
diff --git a/win-odbc64/odbcclient/drvr35/drvrglobal.h 
b/win-odbc64/odbcclient/drvr35/drvrglobal.h
index 12b2702..15d2a52 100755
--- a/win-odbc64/odbcclient/drvr35/drvrglobal.h
+++ b/win-odbc64/odbcclient/drvr35/drvrglobal.h
@@ -103,7 +103,7 @@ extern char* VprocString;
 
 #define STRICT_SCHEMA_ENV_VAL_SIZE 100
 
-#define MAX_DOUBLE_TO_CHAR_LEN (DBL_MANT_DIG - DBL_MIN_EXP + 12)
+#define MAX_DOUBLE_TO_CHAR_LEN (DBL_DIG + 13)  // sign(1) + integer(1) + 
point(1) + fraction(DBL_DIG + 2) + e(1) + sign(1) + exp(3) + '\0' + align(2)
 
 typedef enum SRVR_TYPE
 {
diff --git a/win-odbc64/odbcclient/drvr35/sqltocconv.cpp 
b/win-odbc64/odbcclient/drvr35/sqltocconv.cpp
index 062cca3..235af9c 100755
--- a/win-odbc64/odbcclient/drvr35/sqltocconv.cpp
+++ b/win-odbc64/odbcclient/drvr35/sqltocconv.cpp
@@ -36,6 +36,7 @@
 #include <errno.h>
 
 #define MAXCHARLEN 32768 //32K
+#define OUTBUF_MAX 1024
 
 // for server2008 when using function pow() then throws 
STATUS_ILLEGAL_INSTRUCTION
 double pow(int base, short power, unsigned long *error)
@@ -200,7 +201,7 @@ unsigned long ODBC::ConvertSQLToC(CConnect *m_ConnectHandle,
        USHORT          usTmp;
        SLONG           lTmp;
        ULONG           ulTmp;
-       CHAR            cTmpBuf[MAX_DOUBLE_TO_CHAR_LEN];
+       CHAR            cTmpBuf[OUTBUF_MAX];
        CHAR            cTmpBuf1[30];
        __int64         tempVal64;
        __int64         power;
@@ -665,7 +666,7 @@ unsigned long ODBC::ConvertSQLToC(CConnect *m_ConnectHandle,
                                else {
                                        dTmp = *(double *)srcDataPtr;
 //                                     _gcvt(dTmp, DBL_DIG, cTmpBuf);
-                                       if (!double_to_char (dTmp, DBL_DIG + 1, 
cTmpBuf, sizeof(cTmpBuf)))
+                                       if (!double_to_char (dTmp, DBL_DIG, 
cTmpBuf, sizeof(cTmpBuf)))
                                                return IDS_22_001;
                                }
                        }
@@ -1017,7 +1018,7 @@ unsigned long ODBC::ConvertSQLToC(CConnect 
*m_ConnectHandle,
                                else {
                                        dTmp = *(double *)srcDataPtr;
 //                                     _gcvt(dTmp, DBL_DIG, cTmpBuf);
-                    if (!double_to_char(dTmp, DBL_DIG + 1, cTmpBuf, 
sizeof(cTmpBuf)))
+                    if (!double_to_char(dTmp, DBL_DIG, cTmpBuf, 
sizeof(cTmpBuf)))
                                                return IDS_22_001;
                                }
                        }

Reply via email to