wonderix / crystal-tds

MIT License
11 stars 2 forks source link

Fix `TDS::ProtocolError` raised when non-nil non-String argument is provided when executing a statement that was prepared with that argument set to nil #17

Closed lachlan closed 9 months ago

lachlan commented 9 months ago

If a statement happens to be initially prepared with a nil argument then that argument type is inferred to be NVARCHAR and the type is cached. Later when the statement is executed with a non-nil non-String argument, an exception is raised that the argument value is not supported because it is expecting the cached NVARCHAR type (previously inferred from nil) even though the actual argument and column type could be anything. If the type is a non-*CHAR type, then the following exception is raised:

Unsupported value : <Class> = <Value> (expected type: String | Nil) (TDS::ProtocolError)

This change fixes this issue by caching the prepared statement handles against the unique combination of inferred types, and then fetching the relevant handle using the inferred types of the given arguments at statement execution time.

Prepared statements are now also unprepared when the statement is closed to clean up the database-side resources gracefully.