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;
}
}