microsoft / ODBC-Specification

Microsoft ODBC Specification
Other
122 stars 40 forks source link

SQL_ATTR_TYPE_EXCEPTION_BEHAVIOR clarification #94

Closed matthew-wozniczka closed 7 years ago

matthew-wozniczka commented 7 years ago

If it's set to SQL_TE_REPORT_EXCEPTION, and a fetch is interrupted with SQL_METADATA_CHANGED due to a conversion error, what happens if the application attempts to restart the fetch without fetching the data with SQLGetData or rebinding (or, rebinding to another incompatible binding)? Does the driver immediately ('stubbornly') return SQL_METADATA_CHANGED again? Does it just set the length indicator to SQL_TYPE_EXCEPTION and move on?

matthew-wozniczka commented 7 years ago

A related question: Is SQL_TE_REPORT_ALL meant to be a 'superset' of SQL_TE_REPORT_EXCEPTION?

In the scenario above, if SQL_ATTR_TYPE_EXCEPTION_BEHAVIOR were set to SQL_TE_REPORT_ALL, my reading of the spec would have the restarted fetch act as if the conversion error was an error (the same as SQL_TE_ERROR).

matthew-wozniczka commented 7 years ago

If the application binds a column after prepare, and the column's metadata changes after execute, does that cause the initial fetch to be interrupted if SQL_TE_REPORT_ALL was being used? (I guess not since the change happened before the fetch?)

mikepizzo commented 7 years ago

We no longer support fetching into a rebound buffer. If the client gets a type exception then they can retrieve using SQLGetData but, whether they do or not, we don't attempt to use the binding to fetch that value.

Yes, REPORT_ALL is a superset of ERROR.

The fact that the user did (or did not) do a prepare shouldn't affect the state when fetching results. Any time the binding doesn't support the type on the wire, the type exception handling kicks in.

matthew-wozniczka commented 7 years ago

Yes, REPORT_ALL is a superset of ERROR.

Sorry, want to clarify this, you're saying it's a superset of SQL_TE_ERROR? Did you mean SQL_TE_REPORT_EXCEPTION?

mikepizzo commented 7 years ago

Yes, SQL_TE_REPORT_ALL is a superset of SQL_TE_REPORT_EXCEPTION. i.e., it will return SQL_METADATA_CHANGED either if the value is not compatible with the bound type (SQL_TE_REPORT_EXCEPTION) or if the type information in the IRD/IPD has changed.

Actually, the name "SQL_METADATA_CHANGED" might be a bit mislead for the SQL_TE_REPORT_EXCEPTION case; i.e., even if the user intentionally bound to a different type, and the type of the value still matches the type in the IPD/IRD, then I would expect the condition to be raised. We could add a separate "SQL_TYPE_EXCEPTION" return code that would be used if the application intentionally bound to the wrong type, but that seems a bit strange...

Updated description: