Commit 932ec74
committed
fix(backend/kernel): comparator parity — async retention + intervals_as_string + precision/scale + named params + utils.exc fix
Five small comparator-parity fixes surfaced by the same audit run.
All are independently small but ship together because they share
the kernel-backend client surface and the audit baseline.
### 1. Async Statement retention
`KernelDatabricksClient.execute_command` closed the parent `Statement`
in `finally` regardless of `async_op`. The kernel's `Statement.close()`
invalidates child handles (see databricks-sql-kernel
`src/statement/validity.rs`), so the async handle died before the user
could poll it — breaking `execute_async` → `is_query_pending` →
`get_async_execution_result`.
Fix: when `async_op=True`, retain the parent Statement in a new
`_async_statements` dict alongside `_async_handles`, and close it
from `close_command`, `close_session`, and `get_execution_result`
after the executed handle is done.
Comparator outcome: STATEMENT_ASYNC suite 3/3 match (was 0/3).
### 2. `intervals_as_string` wire-through
pyarrow's Python bindings cannot decode Arrow's `month_interval` type
(id 21 — `KeyError` from `.as_py`, `to_pylist`, `cast(string)`,
`to_pandas`). Every kernel-backend `SELECT *` over a table with an
`INTERVAL YEAR TO MONTH` column raised `ArrowNotImplementedError` —
32 / 88 audit diffs.
Fix: pass `intervals_as_string=True` to the kernel `Session(...)`
constructor unconditionally. The kernel post-processor stringifies
`Interval` / `Duration` columns server-side to `Utf8` (kernel PR #64).
Comparator outcome: bucket A (ArrowNotImplementedError) 32 → 0.
### 3. Decimal precision/scale extraction
`description_from_arrow_schema` hard-coded `None` for PEP 249
description-tuple slots 4 and 5. For DECIMAL columns the Arrow
schema carries `precision` / `scale` on `Decimal128Type`, but they
were silently dropped — 88 cell diffs (44 precision + 44 scale).
Fix: factor out `_precision_scale_for_arrow_type(arrow_type)` and
call it from the description builder. Today it only handles
decimals; future extensions slot in here.
Comparator outcome: 88 precision+scale diffs → 0.
### 4. Named-parameter binding
`bind_tspark_params` raised `NotSupportedError` for any
`TSparkParameter` with `name` set. The canonical SEA proto marks
`StatementParameter.name` as `openapi_required=true` (named is the
spec-required public form; `ordinal` is `PUBLIC_UNDOCUMENTED`).
Kernel PR #65 added a `Statement.bind_named_param` PyO3 API.
Fix: route named bindings via the new API. Positional ordinals
self-increment so a named entry in the middle of the list doesn't
claim a positional slot.
Comparator outcome: PREPARED_STATEMENT_NAMED 1/1 match (was 0/1).
Full thrift-vs-kernel run: 97/132 match (was 96/132).
### 5. `utils.ParamEscaper` `exc.ProgrammingError` import fix
`ParamEscaper.escape_args` and `escape_item` both raised
`exc.ProgrammingError(...)`, but `exc` was never imported. On any
unsupported parameter shape the user saw `NameError: name 'exc' is
not defined` instead of a clean PEP 249 `ProgrammingError`.
Surfaced via the same audit harness running INLINE_PARAMS: both
backends raised `NameError`, which the comparator's class+message
match treated as parity — a false-positive that hid both the driver
bug and the underlying caller-side type mismatch.
Fix: import `ProgrammingError` directly from `databricks.sql.exc`
(matching the pattern used in `session.py`, `client.py`,
`result_set.py`, etc.) and replace the two `exc.ProgrammingError(...)`
sites with bare `ProgrammingError(...)`.
## Dependencies
Items #2, #3, and #4 require the matching databricks-sql-kernel
changes: PR #64 (`intervals_as_string` + empty-result schema fix)
and PR #65 (named-param binding). For local testing the comparator
harness uses `KERNEL_FREEZE=1` against a kernel checkout of the
feature branches.
## Headline comparator results (full thrift-vs-kernel run)
| | Before | After |
|------------------------------------|--------|-------|
| match / diff / skipped | 60 / 88 / 0 | **97 / 34 / 1** |
| Bucket A (ArrowNotImplementedError)| 32 | 0 |
| `decimal_column` precision/scale | 88 | 0 |
| Bucket B1 (named params) | 1 | 0 |
| Suites fully clean | 12 / 30 | **17 / 30** |
Remaining 34 diffs cluster into documented causes (complex types in
`fetchall_arrow`, timestamp tz on Arrow path, VOID surface,
METADATA pattern semantics) — tracked in
`~/docs/python-kernel/comparator-diff-tasklist.md`.
## Test plan
- [x] Manual repro of async path: `cur.execute_async("SELECT 1")` →
`is_query_pending` → `get_async_execution_result` → `fetchall`
succeeds on `use_kernel=True`
- [x] Manual repro of interval path: `cur.execute("SELECT ym_interval_column FROM ...")`
returns string-shaped rows matching the Thrift surface
- [x] Manual repro of decimal path: `cur.description` for a
`DECIMAL(10,2)` column now reports `precision=10, scale=2`
- [x] Live e2e: `test_parameterized_query_named_params` /
`test_parameterized_query_named_param_with_null` (added)
- [x] Unit tests: `bind_tspark_params` named/positional/mixed
routing (`tests/unit/test_kernel_type_mapping.py`)
- [x] Manual repro of utils fix:
`ParamEscaper().escape_args(object())` raises
`ProgrammingError`, not `NameError`
- [x] Full thrift-vs-kernel comparator: 97 / 34 / 1 of 132
- [x] Existing connector unit suite: 752 passed
Co-authored-by: Isaac1 parent fb55001 commit 932ec74
5 files changed
Lines changed: 195 additions & 53 deletions
File tree
- src/databricks/sql
- backend/kernel
- tests
- e2e
- unit
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
129 | 129 | | |
130 | 130 | | |
131 | 131 | | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
132 | 141 | | |
133 | 142 | | |
134 | 143 | | |
| |||
167 | 176 | | |
168 | 177 | | |
169 | 178 | | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
170 | 189 | | |
171 | 190 | | |
172 | 191 | | |
| |||
197 | 216 | | |
198 | 217 | | |
199 | 218 | | |
| 219 | + | |
200 | 220 | | |
| 221 | + | |
201 | 222 | | |
202 | 223 | | |
203 | 224 | | |
| |||
211 | 232 | | |
212 | 233 | | |
213 | 234 | | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
214 | 245 | | |
215 | 246 | | |
216 | 247 | | |
| |||
249 | 280 | | |
250 | 281 | | |
251 | 282 | | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
252 | 288 | | |
253 | 289 | | |
254 | 290 | | |
| |||
262 | 298 | | |
263 | 299 | | |
264 | 300 | | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
265 | 307 | | |
266 | 308 | | |
267 | 309 | | |
268 | 310 | | |
269 | 311 | | |
270 | | - | |
271 | | - | |
272 | | - | |
273 | | - | |
274 | | - | |
275 | | - | |
276 | | - | |
277 | | - | |
278 | | - | |
279 | | - | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
280 | 321 | | |
281 | 322 | | |
282 | 323 | | |
| |||
307 | 348 | | |
308 | 349 | | |
309 | 350 | | |
| 351 | + | |
310 | 352 | | |
311 | 353 | | |
312 | 354 | | |
313 | 355 | | |
314 | 356 | | |
315 | 357 | | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
316 | 366 | | |
317 | 367 | | |
318 | 368 | | |
319 | 369 | | |
320 | 370 | | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
321 | 379 | | |
322 | 380 | | |
323 | 381 | | |
| |||
378 | 436 | | |
379 | 437 | | |
380 | 438 | | |
| 439 | + | |
381 | 440 | | |
382 | 441 | | |
383 | 442 | | |
| |||
387 | 446 | | |
388 | 447 | | |
389 | 448 | | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
390 | 461 | | |
391 | 462 | | |
392 | 463 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
24 | | - | |
| 24 | + | |
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| |||
102 | 102 | | |
103 | 103 | | |
104 | 104 | | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
105 | 113 | | |
106 | 114 | | |
107 | 115 | | |
108 | 116 | | |
109 | 117 | | |
110 | 118 | | |
111 | 119 | | |
112 | | - | |
113 | | - | |
| 120 | + | |
114 | 121 | | |
115 | 122 | | |
116 | 123 | | |
117 | 124 | | |
118 | 125 | | |
119 | 126 | | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
120 | 146 | | |
121 | 147 | | |
122 | 148 | | |
| |||
173 | 199 | | |
174 | 200 | | |
175 | 201 | | |
176 | | - | |
177 | | - | |
| 202 | + | |
178 | 203 | | |
179 | | - | |
180 | | - | |
181 | | - | |
| 204 | + | |
| 205 | + | |
182 | 206 | | |
183 | 207 | | |
184 | 208 | | |
185 | 209 | | |
186 | 210 | | |
187 | 211 | | |
188 | 212 | | |
189 | | - | |
190 | | - | |
191 | | - | |
192 | | - | |
193 | | - | |
194 | | - | |
195 | | - | |
196 | | - | |
197 | | - | |
198 | | - | |
199 | | - | |
200 | | - | |
201 | | - | |
| 213 | + | |
| 214 | + | |
202 | 215 | | |
203 | 216 | | |
204 | 217 | | |
| |||
214 | 227 | | |
215 | 228 | | |
216 | 229 | | |
217 | | - | |
218 | | - | |
219 | | - | |
220 | | - | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
| 22 | + | |
22 | 23 | | |
23 | 24 | | |
24 | 25 | | |
| |||
548 | 549 | | |
549 | 550 | | |
550 | 551 | | |
551 | | - | |
| 552 | + | |
552 | 553 | | |
553 | 554 | | |
554 | 555 | | |
| |||
606 | 607 | | |
607 | 608 | | |
608 | 609 | | |
609 | | - | |
| 610 | + | |
610 | 611 | | |
611 | 612 | | |
612 | 613 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
241 | 241 | | |
242 | 242 | | |
243 | 243 | | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
244 | 272 | | |
245 | 273 | | |
246 | 274 | | |
| |||
0 commit comments