Changeset: 2aafad578fd4 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/2aafad578fd4 Added Files: clients/odbc/ChangeLog Modified Files: clients/odbc/driver/ODBCDbc.h clients/odbc/driver/SQLExecute.c clients/odbc/driver/SQLGetTypeInfo.c clients/odbc/driver/SQLPrepare.c clients/odbc/driver/SQLSetDescField.c Branch: Oct2020 Log Message:
Silently convert HUGEINT to BIGINT in the ODBC driver. This conversion stops when the application uses the SQL_HUGEINT value in a call to SQLGetTypeInfo or SQLSetDescField. diffs (98 lines): diff --git a/clients/odbc/ChangeLog b/clients/odbc/ChangeLog new file mode 100644 --- /dev/null +++ b/clients/odbc/ChangeLog @@ -0,0 +1,13 @@ +# ChangeLog file for odbc +# This file is updated with Maddlog + +* Thu Mar 25 2021 Sjoerd Mullender <[email protected]> +- The ODBC driver now only passes on information about HUGEINT columns + as HUGEINT when the application has indicated interest by querying + about the SQL_HUGEINT extension type using the SQLGetTypeInfo + function or by specifying the type in a call to SQLSetDescField. + Otherwise the driver silently translates the HUGEINT type to BIGINT. + This means that most application will see BIGINT columns when the + server produced a HUGEINT column and only give an error if the value + in the HUGEINT column didn't fit into a BIGINT. + diff --git a/clients/odbc/driver/ODBCDbc.h b/clients/odbc/driver/ODBCDbc.h --- a/clients/odbc/driver/ODBCDbc.h +++ b/clients/odbc/driver/ODBCDbc.h @@ -55,6 +55,7 @@ typedef struct tODBCDRIVERDBC { char *dbname; /* Database Name or NULL */ bool Connected; /* whether we are connecte to a server */ bool has_comment; /* whether the server has sys.comments */ + bool allow_hugeint; /* whether the application deals with HUGEINT */ SQLUINTEGER sql_attr_autocommit; SQLUINTEGER sql_attr_metadata_id; SQLUINTEGER sql_attr_connection_timeout; 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 @@ -228,6 +228,8 @@ ODBCInitResult(ODBCStmt *stmt) s = mapi_get_type(hdl, i); if (s == NULL) /* shouldn't happen */ s = ""; + if (!stmt->Dbc->allow_hugeint && strcmp(s, "hugeint") == 0) + s = "bigint"; if (rec->sql_desc_type_name) free(rec->sql_desc_type_name); rec->sql_desc_type_name = (SQLCHAR *) strdup(s); diff --git a/clients/odbc/driver/SQLGetTypeInfo.c b/clients/odbc/driver/SQLGetTypeInfo.c --- a/clients/odbc/driver/SQLGetTypeInfo.c +++ b/clients/odbc/driver/SQLGetTypeInfo.c @@ -1057,7 +1057,6 @@ MNDBGetTypeInfo(ODBCStmt *stmt, case SQL_VARBINARY: case SQL_LONGVARBINARY: case SQL_BIGINT: - case SQL_HUGEINT: case SQL_TINYINT: case SQL_BIT: case SQL_WCHAR: @@ -1079,6 +1078,12 @@ MNDBGetTypeInfo(ODBCStmt *stmt, case SQL_INTERVAL_MINUTE_TO_SECOND: break; + case SQL_HUGEINT: + /* the application shows interest in HUGEINT, so now we + * enable it */ + stmt->Dbc->allow_hugeint = true; + break; + /* some pre ODBC 3.0 data types which can be mapped to ODBC * 3.0 data types */ case -80: /* SQL_INTERVAL_YEAR */ 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 @@ -180,6 +180,8 @@ MNDBPrepare(ODBCStmt *stmt, } s = mapi_fetch_field(hdl, 0); /* type */ + if (!stmt->Dbc->allow_hugeint && strcmp(s, "hugeint") == 0) + s = "bigint"; rec->sql_desc_type_name = (SQLCHAR *) strdup(s); concise_type = ODBCConciseType(s); diff --git a/clients/odbc/driver/SQLSetDescField.c b/clients/odbc/driver/SQLSetDescField.c --- a/clients/odbc/driver/SQLSetDescField.c +++ b/clients/odbc/driver/SQLSetDescField.c @@ -129,6 +129,8 @@ MNDBSetDescField(ODBCDesc *desc, case SQL_DESC_CONCISE_TYPE: /* SQLSMALLINT */ while (tp->concise_type != 0) { if ((intptr_t) tp->concise_type == (intptr_t) ValuePtr) { + if (tp->concise_type == SQL_HUGEINT) + desc->Dbc->allow_hugeint = true; rec->sql_desc_concise_type = tp->concise_type; rec->sql_desc_type = tp->type; rec->sql_desc_datetime_interval_code = tp->code; @@ -241,6 +243,8 @@ MNDBSetDescField(ODBCDesc *desc, (((SQLSMALLINT) (intptr_t) ValuePtr != SQL_DATETIME && (SQLSMALLINT) (intptr_t) ValuePtr != SQL_INTERVAL) || tp->code == rec->sql_desc_datetime_interval_code)) { + if (tp->concise_type == SQL_HUGEINT) + desc->Dbc->allow_hugeint = true; rec->sql_desc_concise_type = tp->concise_type; rec->sql_desc_type = tp->type; rec->sql_desc_datetime_interval_code = tp->code; _______________________________________________ checkin-list mailing list [email protected] https://www.monetdb.org/mailman/listinfo/checkin-list
