Commit 9d6b2ee
feat!: adapt to core's catalog query types and sealed rows, and correct four info values
The follow-up the previous commit deferred, plus everything else core moved
since. Three breaking changes with no compiling intermediate state, so they land
together.
Catalog query types. The six catalog methods take a sealed query object instead
of five to eight positional arguments — `SQLForeignKeys` alone took six
`Option<&str>` in a row, where crossing a primary-key argument with its
foreign-key counterpart compiled without complaint. The query travels all the
way into `metadata.rs` rather than being unpacked at the trait boundary, which
would reintroduce that hazard one layer down. `TablesQuery::table_types()` is a
`&[String]` core has already split on commas and stripped the quotes from, so
`metadata::tables` loses its own parsing; a lone "%" still arrives, because the
`SQL_ALL_TABLE_TYPES` enumeration core answers itself additionally requires the
other three arguments to be empty strings, and is still read as no filter.
Sealed rows. Every catalog row type is `#[non_exhaustive]`, so the eight struct
literals become `Default` plus the consuming setter per column. A column this
driver does not populate is now unnamed rather than spelled `None`, which is the
point — it makes a column added to a spec result set a core-only change — so
each site says in a comment which columns it leaves NULL and why.
Ten new required capability hooks. Six are values this driver already stated and
that now move out of `sqlite_get_info` into the hook, because answering in both
places is the "declare it once" violation AGENTS.md describes: `driver_name`,
`driver_version`, `dbms_name`, `dbms_version`, `integrity` and `txn_capable`.
The snapshot pins all six regardless of which layer answers, which is what made
moving them safe. Two more were already pinned at core's default and are now
claims this driver makes on purpose: `accessible_procedures` "N" and
`txn_capable` SQL_TC_DML. `driver_name`/`driver_version` take no connection —
the Windows DM asks for driver identity before `SQLDriverConnectW` — while
`dbms_name`/`dbms_version` describe what was connected to and take one.
Two info values were wrong, and both are now live-probed rather than read off the
documentation. `SQL_QUOTED_IDENTIFIER_CASE` claimed SQL_IC_SENSITIVE, telling an
application that "T" and "t" are different tables; in SQLite double quotes are a
delimiter, not a case-sensitivity switch, so it is SQL_IC_MIXED, and the probe
asserts both halves of that — case-insensitive matching and mixed-case storage.
`SQL_SPECIAL_CHARACTERS` claimed "", which was core's old default rather than a
claim this driver ever made; SQLite parses `$` in an undelimited identifier, so
it is "$", probed over 31 candidates with the rejected ones asserted too. The
negative half is what stops it understating again, the same lesson
`alter_table_capabilities_are_each_live_probed` records.
SQLRowCount. Core now reads a zero-column statement reporting `Some(0)` as
SQL_NO_DATA, per SQLExecDirect's Comments, which surfaced that this driver
answered `Some(0)` for DDL — so every `CREATE TABLE` it ran returned SQL_NO_DATA
to the application, and 60 of the 66 initial test failures were that. `row_count`
now distinguishes "counted zero" from "no count applies". SQLite exposes no
predicate for this (`sqlite3_stmt_readonly` is false for DDL too), so
`is_searched_dml` decides from the leading keyword, past whitespace and both
comment forms, counting REPLACE and WITH alongside the obvious three. That also
removes a stale count: `sqlite3_changes()` reports the most recently completed
INSERT, UPDATE or DELETE, so a `CREATE TABLE` run after a three-row INSERT was
handed that 3 and reported it.
Two values changed underneath us, both core-owned and both describing core's
fetch path rather than SQLite, so the snapshot follows: `SQL_CURSOR_SENSITIVITY`
to SQL_UNSPECIFIED, and `SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2` to
SQL_CA2_READ_ONLY_CONCURRENCY.
Tests. The two `get_info_every_named_info_type_has_the_declared_shape_*` tests
asserted SQL_SUCCESS where core now documents that the shape probe's zero-length
buffer is total truncation; they assert "not SQL_ERROR", which is what their own
messages always claimed. `dbms_ver_is_well_formed` and `driver_ver_is_well_formed`
read through the hooks, the first via `test_connection` since it needs a data
source. `SQL_MULTIPLE_ACTIVE_TXN` has no `odbc_sys::InfoType` variant, so it is
pinned through the raw path — the snapshot iterates named types only.
Also fixes a pre-existing rustdoc failure that only surfaced once the crate
compiled again: a public doc comment linked to the `pub(crate)`
`SqliteConnection::interrupt`.
Verified against stackable-odbc-core dd25a22: cargo test 280 passing, clippy
clean, `pre-commit run --all-files` green across all 15 hooks, and the pyodbc
suite 23/23 through real unixODBC.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>1 parent 9c081d5 commit 9d6b2ee
7 files changed
Lines changed: 962 additions & 389 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
| |||
179 | 180 | | |
180 | 181 | | |
181 | 182 | | |
182 | | - | |
| 183 | + | |
183 | 184 | | |
184 | 185 | | |
185 | | - | |
186 | | - | |
187 | | - | |
188 | | - | |
189 | | - | |
190 | | - | |
191 | | - | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
192 | 198 | | |
193 | 199 | | |
194 | 200 | | |
195 | 201 | | |
196 | 202 | | |
197 | 203 | | |
198 | 204 | | |
199 | | - | |
200 | | - | |
201 | | - | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
202 | 212 | | |
203 | 213 | | |
204 | 214 | | |
| |||
366 | 376 | | |
367 | 377 | | |
368 | 378 | | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
369 | 411 | | |
370 | 412 | | |
371 | | - | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
372 | 416 | | |
373 | 417 | | |
374 | 418 | | |
375 | | - | |
376 | | - | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
377 | 450 | | |
378 | 451 | | |
379 | 452 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
70 | 70 | | |
71 | 71 | | |
72 | 72 | | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
73 | 102 | | |
74 | 103 | | |
75 | 104 | | |
| |||
224 | 253 | | |
225 | 254 | | |
226 | 255 | | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
227 | 272 | | |
228 | 273 | | |
229 | 274 | | |
| |||
0 commit comments