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
