Skip to content

fix(adapters): resolve DuckDB extension, Arrow NULL-typing, and MSSQL row-format bugs#641

Merged
cofin merged 3 commits into
mainfrom
fix/adapter-bugs-636-631-630
Jul 11, 2026
Merged

fix(adapters): resolve DuckDB extension, Arrow NULL-typing, and MSSQL row-format bugs#641
cofin merged 3 commits into
mainfrom
fix/adapter-bugs-636-631-630

Conversation

@cofin

@cofin cofin commented Jul 11, 2026

Copy link
Copy Markdown
Member

Fixes three independent adapter bugs, each with regression coverage.

#631select_to_arrow all-NULL columns lose their type

pa.Table.from_pylist infers types from values only, so a column that is NULL in every row collapsed to Arrow null type and lost the DB column's declared type. Downstream consumers misread it (DuckDB materializes null as INTEGER, so COALESCE(col, 'x') raised a conversion error). convert_dict_to_arrow now retypes value-inferred null columns to string, which safely holds the all-null values.

Closes #631

#636 — DuckDB emits two warnings for one extension setup failure

A non-required extension whose explicit install failed and whose subsequent load also failed emitted both pool.extension.install.failed and pool.extension.load.failed for one unusable extension. Install + load are now treated as one setup outcome:

  • install-fail + cached-load-success → no warning (install detail logged at DEBUG)
  • install-fail + load-fail → one pool.extension.setup.failed carrying both install_error and load_error
  • install-success + load-fail → one pool.extension.setup.failed
  • name-only load-only and required=True contracts unchanged

Closes #636

#630 — MSSQL marks rows row_format="tuple" but driver returns mssql_python.Row

mssql_python.Row is iterable/indexable but not a tuple subclass, so declaring row_format="tuple" tripped the debug row-format fidelity assertion during dict materialization. dispatch_execute now materializes fetched rows into real tuples (new materialize_tuple_rows helper), matching the tuple row shape used across the SQL Server adapter family.

Closes #630

Testing

  • New/updated unit tests for all three (arrow null-typing, DuckDB setup-outcome collapse, MSSQL Row→tuple materialization)
  • make type-check clean (mypy + pyright)
  • Verified downstream: DuckDB COALESCE on an all-NULL column, and SQLResult materialization of Row-like objects under row_format="tuple"

cofin added 3 commits July 11, 2026 02:43
pa.Table.from_pylist infers column types from values only, so a column
that is NULL in every row collapsed to Arrow null type and lost the
database column's declared type. Downstream consumers misread these
columns (DuckDB materializes null as INTEGER, breaking string ops).
Fall back all-null value-inferred columns to string in convert_dict_to_arrow.

Fixes #631
A non-required extension whose explicit install failed and whose
subsequent load also failed emitted two warnings for one unusable
extension. Treat install plus load as a single setup outcome:
install-fail + load-success emits no warning (install detail at DEBUG),
and any terminal failure of an explicitly-installed extension emits one
pool.extension.setup.failed warning carrying install_error and load_error.
Name-only load-only and required=True contracts are unchanged.

Fixes #636
…format

mssql-python returns mssql_python.Row objects that are iterable and
indexable but are not tuple subclasses, while the driver declared
row_format="tuple". That mismatch tripped the debug row-format fidelity
assertion during dict materialization. Convert fetched rows to real
tuples in dispatch_execute so the declared contract holds, matching the
tuple row shape used across the SQL Server adapter family.

Fixes #630
@codecov-commenter

codecov-commenter commented Jul 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.65217% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 76.82%. Comparing base (6bb5742) to head (e087c6e).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
sqlspec/adapters/mssql_python/driver.py 50.00% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main     #641   +/-   ##
=======================================
  Coverage   76.82%   76.82%           
=======================================
  Files         473      473           
  Lines       66108    66123   +15     
  Branches     9821     9825    +4     
=======================================
+ Hits        50785    50799   +14     
+ Misses      12031    12029    -2     
- Partials     3292     3295    +3     
Flag Coverage Δ
integration 60.01% <39.13%> (-0.03%) ⬇️
py3.10 75.08% <95.65%> (+0.01%) ⬆️
py3.11 75.10% <95.65%> (+0.01%) ⬆️
py3.12 75.09% <95.65%> (+<0.01%) ⬆️
py3.13 75.09% <95.65%> (+0.01%) ⬆️
py3.14 76.02% <95.65%> (+0.01%) ⬆️
unit 63.94% <95.65%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
sqlspec/adapters/duckdb/pool.py 79.48% <100.00%> (+0.44%) ⬆️
sqlspec/adapters/mssql_python/core.py 82.03% <100.00%> (+0.57%) ⬆️
sqlspec/utils/arrow_helpers.py 72.94% <100.00%> (+1.85%) ⬆️
sqlspec/adapters/mssql_python/driver.py 76.56% <50.00%> (ø)

... and 5 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cofin cofin merged commit 53c631a into main Jul 11, 2026
20 checks passed
@cofin cofin deleted the fix/adapter-bugs-636-631-630 branch July 11, 2026 03:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants