lurcher / unixODBC

The unixODBC Project goals are to develop and promote unixODBC to be the definitive standard for ODBC on non MS Windows platforms.
GNU Lesser General Public License v2.1
94 stars 51 forks source link

SQLBindCol doesn't allow a driver-specific C type binding. #132

Open groprima opened 1 year ago

groprima commented 1 year ago

The DB2 CLI ODBC defines several driver-specific SQL, C types and memory layouts for them. These types have been around for quite a while. With the current implementation in the SQLBindCol, they are rejected in the check_target_type(..). My understanding of the MS specs is that the validation only happens when ODBC is 3.8 and up. For the versions below 3.8 any value is accepted.

What do you think about that?

DB2 sqlcli.h:

/ SQL extended data types /

define SQL_GRAPHIC -95

define SQL_VARGRAPHIC -96

define SQL_LONGVARGRAPHIC -97

define SQL_BLOB -98

define SQL_CLOB -99

define SQL_DBCLOB -350

define SQL_XML -370

define SQL_CURSORHANDLE -380

define SQL_DATALINK -400

define SQL_USER_DEFINED_TYPE -450

/ C data type to SQL data type mapping /

define SQL_C_DBCHAR SQL_DBCLOB

define SQL_C_DECIMAL_IBM SQL_DECIMAL

define SQL_C_DATALINK SQL_C_CHAR

define SQL_C_PTR 2463

define SQL_C_DECIMAL_OLEDB 2514

define SQL_C_DECIMAL64 SQL_DECFLOAT

define SQL_C_DECIMAL128 -361

define SQL_C_TIMESTAMP_EXT -362

define SQL_C_TYPE_TIMESTAMP_EXT SQL_C_TIMESTAMP_EXT

define SQL_C_BINARYXML -363

define SQL_C_TIMESTAMP_EXT_TZ -364

define SQL_C_TYPE_TIMESTAMP_EXT_TZ SQL_C_TIMESTAMP_EXT_TZ

define SQL_C_CURSORHANDLE -365

Microsoft: https://learn.microsoft.com/en-us/sql/odbc/reference/develop-app/c-data-types-in-odbc?view=sql-server-ver16

C Data Type Extensibility In ODBC 3.8, you can specify driver-specific C data types ........ .......... ........... A C data type is defined in the driver as follows:

The ODBC compliance level for an application, ODBC driver, and Driver Manager is 3.8 (or higher).

The data range of a driver-specific C type is between 0x4000 and 0x7FFF.

The driver defines the structure of the data corresponding to the C type. This can be done in the driver-specific SDK.

The driver manager will not validate a C type defined in the range of 0x4000 and 0x7FFF; the driver will perform the validation and any data type conversion. But if the data range of a C type passed to the driver manager is between 0x0000 and 0x3FFF or between 0x8000 and 0xFFFF, the driver manager will validate the C data type.

lurcher commented 1 year ago

On 03/02/2023 18:18, groprima wrote:

The DB2 CLI ODBC defines several driver-specific SQL, C types and memory layouts for them. These types have been around for quite a while. With the current implementation in the SQLBindCol, they are rejected in the check_target_type(..). My understanding of the MS specs is that the validation only happens when ODBC is 3.8 and up. For the versions below 3.8 any value is accepted.

What do you think about that?

Well, the code in unixODBC dates back to when the spec from MS was different, then it quietly changed over time. But my reading would be

"In ODBC 3.8, you can specify driver-specific C data types."

I read that as before 3.8 you cant define driver specific types, therefor there is only the types that there is defined in ODBC. And the validation was based on that assumption. There have been more than one place where the driver manager did the validation which matched what happened on windows back the DM was written, then the first I know that this have changed is when something works on windows but not on Unix, so the checks are unwound.

This is probably another one of them.

TallTed commented 1 year ago

It may be worth noting that ODBC 3.8 is a typo; this should actually read ODBC 3.80.