Changeset: 94c8caa1d3b3 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=94c8caa1d3b3
Modified Files:
        clients/odbc/driver/ODBCDesc.c
        clients/odbc/driver/ODBCDesc.h
        clients/odbc/driver/SQLDescribeCol.c
        clients/odbc/driver/SQLDescribeParam.c
        clients/odbc/driver/SQLExecute.c
        clients/odbc/driver/SQLPrepare.c
Branch: Aug2011
Log Message:

Distinguish between Column Size and Display Size.
The two are the same for some types, but different for especially the
numeric types.  See
<http://msdn.microsoft.com/en-us/library/ms712499%28v=VS.85%29.aspx>.


diffs (245 lines):

diff --git a/clients/odbc/driver/ODBCDesc.c b/clients/odbc/driver/ODBCDesc.c
--- a/clients/odbc/driver/ODBCDesc.c
+++ b/clients/odbc/driver/ODBCDesc.c
@@ -231,8 +231,9 @@ addODBCDescRec(ODBCDesc *desc, SQLSMALLI
        return &desc->descRec[recno];
 }
 
+/* Return either the column size or display size for a column or parameter. */
 SQLULEN
-ODBCDisplaySize(ODBCDescRec *rec)
+ODBCLength(ODBCDescRec *rec, int display)
 {
        switch (rec->sql_desc_concise_type) {
        case SQL_CHAR:
@@ -247,67 +248,121 @@ ODBCDisplaySize(ODBCDescRec *rec)
                return rec->sql_desc_length;
        case SQL_DECIMAL:
        case SQL_NUMERIC:
-               return rec->sql_desc_length;
+               return rec->sql_desc_length + (display ? 2 : 0);
        case SQL_BIT:
                return 1;
        case SQL_TINYINT:
-               return 3;
+               return 3 + (display && !rec->sql_desc_unsigned);
        case SQL_SMALLINT:
-               return 5;
+               return 5 + (display && !rec->sql_desc_unsigned);
        case SQL_INTEGER:
-               return 10;
+               return 10 + (display && !rec->sql_desc_unsigned);
        case SQL_BIGINT:
-               return rec->sql_desc_unsigned ? 20 : 19;
+               return display || rec->sql_desc_unsigned ? 20 : 19;
        case SQL_REAL:
-               return 7;
+               /* display: sign, 7 digits, decimal point, E, sign, 2 digits */
+               return display ? 14 : 7;
        case SQL_FLOAT:
        case SQL_DOUBLE:
-               return 15;
+               /* display: sign, 15 digits, decimal point, E, sign, 3 digits */
+               return display ? 24 : 15;
        case SQL_TYPE_DATE:
-               return 10;      /* strlen("yyyy-mm-dd") */
+               /* strlen("yyyy-mm-dd") */
+               return 10;
        case SQL_TYPE_TIME:
-               return 12;      /* strlen("hh:mm:ss.fff") */
+               /* strlen("hh:mm:ss.fff") */
+               return 12;
        case SQL_TYPE_TIMESTAMP:
-               return 23;      /* strlen("yyyy-mm-dd hh:mm:ss.fff") */
+               /* strlen("yyyy-mm-dd hh:mm:ss.fff") */
+               return 23;
        case SQL_INTERVAL_SECOND:
                /* strlen("INTERVAL -'sss[.fff]' SECOND(p,q)") */
-               return 11 + 13 + (rec->sql_desc_datetime_interval_precision > 
10) + (rec->sql_desc_precision > 10) + 
rec->sql_desc_datetime_interval_precision + (rec->sql_desc_precision > 0 ? 
rec->sql_desc_precision + 1 : 0);
+               return 11 + 13 +
+                       (rec->sql_desc_datetime_interval_precision > 10) +
+                       (rec->sql_desc_precision > 10) +
+                       rec->sql_desc_datetime_interval_precision +
+                       (rec->sql_desc_precision > 0 ?
+                        rec->sql_desc_precision + 1 :
+                        0);
        case SQL_INTERVAL_DAY_TO_SECOND:
                /* strlen("INTERVAL -'ddd hh:mm:ss[.fff]' DAY(p) TO SECOND(q)") 
*/
-               return 11 + 21 + (rec->sql_desc_datetime_interval_precision > 
10) + (rec->sql_desc_precision > 10) + 
rec->sql_desc_datetime_interval_precision + 9 + (rec->sql_desc_precision > 0 ? 
rec->sql_desc_precision + 1 : 0);
+               return 11 + 21 +
+                       (rec->sql_desc_datetime_interval_precision > 10) +
+                       (rec->sql_desc_precision > 10) +
+                       rec->sql_desc_datetime_interval_precision +
+                       9 +
+                       (rec->sql_desc_precision > 0 ?
+                        rec->sql_desc_precision + 1 :
+                        0);
        case SQL_INTERVAL_HOUR_TO_SECOND:
                /* strlen("INTERVAL -'hhh:mm:ss[.fff]' HOUR(p) TO SECOND(q)") */
-               return 11 + 22 + (rec->sql_desc_datetime_interval_precision > 
10) + (rec->sql_desc_precision > 10) + 
rec->sql_desc_datetime_interval_precision + 6 + (rec->sql_desc_precision > 0 ? 
rec->sql_desc_precision + 1 : 0);
+               return 11 + 22 +
+                       (rec->sql_desc_datetime_interval_precision > 10) +
+                       (rec->sql_desc_precision > 10) +
+                       rec->sql_desc_datetime_interval_precision +
+                       6 +
+                       (rec->sql_desc_precision > 0 ?
+                        rec->sql_desc_precision + 1 :
+                        0);
        case SQL_INTERVAL_MINUTE_TO_SECOND:
                /* strlen("INTERVAL -'mmm:ss[.fff]' MINUTE(p) TO SECOND(q)") */
-               return 11 + 24 + (rec->sql_desc_datetime_interval_precision > 
10) + (rec->sql_desc_precision > 10) + 
rec->sql_desc_datetime_interval_precision + 3 + (rec->sql_desc_precision > 0 ? 
rec->sql_desc_precision + 1 : 0);
+               return 11 + 24 +
+                       (rec->sql_desc_datetime_interval_precision > 10) +
+                       (rec->sql_desc_precision > 10) +
+                       rec->sql_desc_datetime_interval_precision +
+                       3 +
+                       (rec->sql_desc_precision > 0 ?
+                        rec->sql_desc_precision + 1 :
+                        0);
        case SQL_INTERVAL_YEAR:
                /* strlen("INTERVAL -'yyy' YEAR(p)") */
-               return 11 + 9 + (rec->sql_desc_datetime_interval_precision > 
10) + rec->sql_desc_datetime_interval_precision;
+               return 11 + 9 +
+                       (rec->sql_desc_datetime_interval_precision > 10) +
+                       rec->sql_desc_datetime_interval_precision;
        case SQL_INTERVAL_MONTH:
                /* strlen("INTERVAL -'yyy' MONTH(p)") */
-               return 11 + 10 + (rec->sql_desc_datetime_interval_precision > 
10) + rec->sql_desc_datetime_interval_precision;
+               return 11 + 10 +
+                       (rec->sql_desc_datetime_interval_precision > 10) +
+                       rec->sql_desc_datetime_interval_precision;
        case SQL_INTERVAL_DAY:
                /* strlen("INTERVAL -'yyy' DAY(p)") */
-               return 11 + 8 + (rec->sql_desc_datetime_interval_precision > 
10) + rec->sql_desc_datetime_interval_precision;
+               return 11 + 8 +
+                       (rec->sql_desc_datetime_interval_precision > 10) +
+                       rec->sql_desc_datetime_interval_precision;
        case SQL_INTERVAL_HOUR:
                /* strlen("INTERVAL -'yyy' HOUR(p)") */
-               return 11 + 9 + (rec->sql_desc_datetime_interval_precision > 
10) + rec->sql_desc_datetime_interval_precision;
+               return 11 + 9 +
+                       (rec->sql_desc_datetime_interval_precision > 10) +
+                       rec->sql_desc_datetime_interval_precision;
        case SQL_INTERVAL_MINUTE:
                /* strlen("INTERVAL -'yyy' MINUTE(p)") */
-               return 11 + 11 + (rec->sql_desc_datetime_interval_precision > 
10) + rec->sql_desc_datetime_interval_precision;
+               return 11 + 11 +
+                       (rec->sql_desc_datetime_interval_precision > 10) +
+                       rec->sql_desc_datetime_interval_precision;
        case SQL_INTERVAL_YEAR_TO_MONTH:
                /* strlen("INTERVAL -'yyy' YEAR(p) TO MONTH") */
-               return 11 + 18 + (rec->sql_desc_datetime_interval_precision > 
10) + rec->sql_desc_datetime_interval_precision + 3;
+               return 11 + 18 +
+                       (rec->sql_desc_datetime_interval_precision > 10) +
+                       rec->sql_desc_datetime_interval_precision +
+                       3;
        case SQL_INTERVAL_DAY_TO_HOUR:
                /* strlen("INTERVAL -'yyy' DAY(p) TO HOUR") */
-               return 11 + 16 + (rec->sql_desc_datetime_interval_precision > 
10) + rec->sql_desc_datetime_interval_precision + 3;
+               return 11 + 16 +
+                       (rec->sql_desc_datetime_interval_precision > 10) +
+                       rec->sql_desc_datetime_interval_precision +
+                       3;
        case SQL_INTERVAL_HOUR_TO_MINUTE:
                /* strlen("INTERVAL -'yyy' HOUR(p) TO MINUTE") */
-               return 11 + 19 + (rec->sql_desc_datetime_interval_precision > 
10) + rec->sql_desc_datetime_interval_precision + 3;
+               return 11 + 19 +
+                       (rec->sql_desc_datetime_interval_precision > 10) +
+                       rec->sql_desc_datetime_interval_precision +
+                       3;
        case SQL_INTERVAL_DAY_TO_MINUTE:
                /* strlen("INTERVAL -'yyy' DAY(p) TO MINUTE") */
-               return 11 + 18 + (rec->sql_desc_datetime_interval_precision > 
10) + rec->sql_desc_datetime_interval_precision + 6;
+               return 11 + 18 +
+                       (rec->sql_desc_datetime_interval_precision > 10) +
+                       rec->sql_desc_datetime_interval_precision +
+                       6;
        case SQL_GUID:
                /* strlen("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee") */
                return 36;
diff --git a/clients/odbc/driver/ODBCDesc.h b/clients/odbc/driver/ODBCDesc.h
--- a/clients/odbc/driver/ODBCDesc.h
+++ b/clients/odbc/driver/ODBCDesc.h
@@ -99,7 +99,7 @@ ODBCError *getDescError(ODBCDesc *desc);
 void destroyODBCDesc(ODBCDesc *desc);
 void setODBCDescRecCount(ODBCDesc *desc, int count);
 ODBCDescRec *addODBCDescRec(ODBCDesc *desc, SQLSMALLINT recno);
-SQLULEN ODBCDisplaySize(ODBCDescRec *rec);
+SQLULEN ODBCLength(ODBCDescRec *rec, int display);
 
 SQLRETURN SQLGetDescField_(ODBCDesc *desc, SQLSMALLINT RecordNumber, 
SQLSMALLINT FieldIdentifier, SQLPOINTER Value, SQLINTEGER BufferLength, 
SQLINTEGER *StringLength);
 SQLRETURN SQLSetDescField_(ODBCDesc *desc, SQLSMALLINT RecordNumber, 
SQLSMALLINT FieldIdentifier, SQLPOINTER Value, SQLINTEGER BufferLength);
diff --git a/clients/odbc/driver/SQLDescribeCol.c 
b/clients/odbc/driver/SQLDescribeCol.c
--- a/clients/odbc/driver/SQLDescribeCol.c
+++ b/clients/odbc/driver/SQLDescribeCol.c
@@ -90,7 +90,7 @@ SQLDescribeCol_(ODBCStmt *stmt,
 
        /* also see SQLDescribeParam */
        if (ColumnSizePtr)
-               *ColumnSizePtr = ODBCDisplaySize(rec);
+               *ColumnSizePtr = ODBCLength(rec, 0);
 
        /* also see SQLDescribeParam */
        if (DecimalDigitsPtr) {
diff --git a/clients/odbc/driver/SQLDescribeParam.c 
b/clients/odbc/driver/SQLDescribeParam.c
--- a/clients/odbc/driver/SQLDescribeParam.c
+++ b/clients/odbc/driver/SQLDescribeParam.c
@@ -86,7 +86,7 @@ SQLDescribeParam(SQLHSTMT StatementHandl
 
        /* also see SQLDescribeCol */
        if (ParameterSizePtr)
-               *ParameterSizePtr = ODBCDisplaySize(rec);
+               *ParameterSizePtr = ODBCLength(rec, 0);
 
        /* also see SQLDescribeCol */
        if (DecimalDigitsPtr) {
diff --git a/clients/odbc/driver/SQLExecute.c b/clients/odbc/driver/SQLExecute.c
--- a/clients/odbc/driver/SQLExecute.c
+++ b/clients/odbc/driver/SQLExecute.c
@@ -230,16 +230,16 @@ ODBCInitResult(ODBCStmt *stmt)
 
                /* this must come after other fields have been
                 * initialized */
-               rec->sql_desc_length = ODBCDisplaySize(rec);
-               rec->sql_desc_display_size = rec->sql_desc_length;
+               rec->sql_desc_length = ODBCLength(rec, 0);
+               rec->sql_desc_display_size = ODBCLength(rec, 1);
                if (rec->sql_desc_concise_type == SQL_CHAR ||
                    rec->sql_desc_concise_type == SQL_VARCHAR ||
                    rec->sql_desc_concise_type == SQL_LONGVARCHAR) {
                        /* in theory, each character (really: Unicode
                         * code point) could need 6 bytes in the UTF-8
-                        * encoding, plus we need a byte for the
-                        * terminating NUL byte */
-                       rec->sql_desc_octet_length = 6 * rec->sql_desc_length + 
1;
+                        * encoding; don't include the terminating
+                        * NULL byte */
+                       rec->sql_desc_octet_length = 6 * rec->sql_desc_length;
                } else
                        rec->sql_desc_octet_length = rec->sql_desc_length;
 
diff --git a/clients/odbc/driver/SQLPrepare.c b/clients/odbc/driver/SQLPrepare.c
--- a/clients/odbc/driver/SQLPrepare.c
+++ b/clients/odbc/driver/SQLPrepare.c
@@ -254,16 +254,16 @@ SQLPrepare_(ODBCStmt *stmt,
 
                /* this must come after other fields have been
                 * initialized */
-               rec->sql_desc_length = ODBCDisplaySize(rec);
-               rec->sql_desc_display_size = rec->sql_desc_length;
+               rec->sql_desc_length = ODBCLength(rec, 0);
+               rec->sql_desc_display_size = ODBCLength(rec, 1);
                if (rec->sql_desc_concise_type == SQL_CHAR ||
                    rec->sql_desc_concise_type == SQL_VARCHAR ||
                    rec->sql_desc_concise_type == SQL_LONGVARCHAR) {
                        /* in theory, each character (really: Unicode
                         * code point) could need 6 bytes in the UTF-8
-                        * encoding, plus we need a byte for the
-                        * terminating NUL byte */
-                       rec->sql_desc_octet_length = 6 * rec->sql_desc_length + 
1;
+                        * encoding; don't include the terminating
+                        * NULL byte */
+                       rec->sql_desc_octet_length = 6 * rec->sql_desc_length;
                } else
                        rec->sql_desc_octet_length = rec->sql_desc_length;
        }
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to