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

SQLGetDiagField for SQL_DIAG_NUMBER not called on SQL_NO_DATA #136

Closed kadler closed 1 year ago

kadler commented 1 year ago

A customer of ours reported a behavior discrepancy with our driver on Linux vs Windows. Update statement returns SQL_NO_DATA when the update doesn't affect any rows (eg. unmatched WHERE clause). They then call SQLGetDiagField with SQL_DIAG_NUMBER to determine how many diagnostic records are available. On Windows, this returns 1 (a warning "SQL0100 - Row not found for UPDATE"), but with unixODBC this returns 0.

From a driver trace, I can see that SQLGetDiagField in the driver is never getting called. Looking at the driver manager code, it looks like this value is cached by the driver manager and the cached value is simply returned here: https://github.com/lurcher/unixODBC/blob/master/DriverManager/SQLGetDiagField.c#L481-L497

Looks like this information is only cached if a value of SQL_ERROR or SQL_SUCCESS_WITH_INFO is returned: https://github.com/lurcher/unixODBC/blob/master/DriverManager/__info.c#L5115 and indeed if I change the driver to return one of these instead, I do get the expected result. However, ODBC docs for SQLExecDirect says:

If SQLExecDirect executes a searched update, insert, or delete statement that does not affect any rows at the data source, the call to SQLExecDirect returns SQL_NO_DATA.

kadler commented 1 year ago

This also seems to affect calling SQLGetDiagRec as well. So even ignoring SQL_DIAG_NUMBER and just calling SQLGetDiagRec until it returns SQL_NO_DATA will not let you retrieve these records.