You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Runtime errors in a batch surface as "Expected ColumnMetadata in context" (mssql-tds-preview drain_stream) #37
When one statement in a batch fails with a runtime error and a later statement in the same batch returns rows, the driver can't parse the rest of the response. The user sees a misleading error instead of the real SQL error:
SQL Server connection failure: IO error: Expected ColumnMetadata in context
This happens at every compatibility level.
Cause
mssql-tds-preview's drain_stream (src/connection/tds_client.rs) reads every token after an ERROR token with ParserContext::None and doesn't handle COLMETADATA. So when a later statement returns a result set, the ROW tokens that follow can't be parsed, because the parser has no column metadata for them.
The latest release (0.1.0-preview.9) has the same drain_stream. We pin =0.1.0-preview.1.
Where it hits the plugin
update_record / insert_record: the plugin appends SELECT CAST(@@ROWCOUNT AS BIGINT) AS [__tabularis_affected_rows] to the DML (src/driver/helpers.rs). Any runtime error in the DML (arithmetic overflow, constraint violation, etc.) is followed by that SELECT, so it always takes this path and the real error is lost.
execute_query: SELECT 1/0; SELECT 2 hangs.
Repro
Against any SQL Server, run SELECT 1/0; SELECT 2 through execute_query. It hangs instead of returning error 8134.
Update a REAL column to a value that overflows (for example 3.4028235e38 at compatibility level below 130, Msg 232). It returns Expected ColumnMetadata in context instead of the overflow error.
Options
Upstream fix in mssql-tds-preview (https://github.com/saurabh500/mssql-rs): make drain_stream handle COLMETADATA (or skip result sets correctly) after an error.
Plugin-side workaround: avoid batches where a result set can follow a failing statement. For DML, that could mean getting the row count from the DONE token instead of a trailing SELECT @@ROWCOUNT, if the crate exposes it.
Option 1 is the real fix; option 2 would at least surface the right error for update_record / insert_record until upstream ships one.
Activity
test: cover runtime error followed by result set (#37) (#39)