Skip to content

Apply python_scan_all_frames to externally supplied duckdb connections#2790

Merged
Niels-b merged 1 commit into
v3from
fix/duckdb-scan-all-frames-external-connection
Jul 14, 2026
Merged

Apply python_scan_all_frames to externally supplied duckdb connections#2790
Niels-b merged 1 commit into
v3from
fix/duckdb-scan-all-frames-external-connection

Conversation

@Niels-b

@Niels-b Niels-b commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #2527. That PR restored the pre-1.1.0 python_scan_all_frames behavior by passing it via connect-time config, but the config only reaches connections Soda creates itself (the file-read and :memory:/path branches). It never reaches the duckdb_connection branch used by Scan.add_duckdb_connection(...) — the canonical pandas/polars DataFrame workflow.

Since duckdb ≥1.1.0 defaults python_scan_all_frames to False, a user-supplied connection can no longer resolve a DataFrame defined in a caller frame, and the check fails with Table ... does not exist.

Why the existing test didn't catch it

test_pandas_df uses the shared fixture, which pre-registers its own duckdb connection (built through the config path, which already sets the flag). DataSourceManager.get_data_source returns that cached instance, so add_duckdb_connection(con) writes to a dict that's never read — the branch is never exercised, and the bug is masked.

Changes

  • duckdb_data_source.py — restore python_scan_all_frames at runtime (via SET) on externally supplied connections, driven by self.configuration so overrides still win. (custom_user_agent can only be set at connect time, so it can't be applied to a pre-existing connection.)
  • scan.py / configuration.py — new optional configuration argument on add_duckdb_connection, reusing the existing data-source configuration plumbing. Default restores the old behavior; pass configuration={"python_scan_all_frames": False} to opt out.
  • test_duckdb.py — two regression tests that exercise the real user-connection branch (bare Scan, not the fixture): one guards the restored default (fails without this fix), one verifies the override is honored.

Behavior

Call connection setting after connect DataFrame check
add_duckdb_connection(con) (default) True passes (old behavior restored)
add_duckdb_connection(con, configuration={"python_scan_all_frames": False}) False fails (opted out)
add_duckdb_connection(con, configuration={"python_scan_all_frames": True}) True passes

Testing

Verified against a dedicated venv with duckdb==1.5.4 (resolved from the >=1.1.0,<2.0 range). Full duckdb suite: 6 passed. The restored-default test fails without the source fix and passes with it.

🤖 Generated with Claude Code

PR #2527 upgraded duckdb to >=1.1.0 and restored the pre-1.1.0
`python_scan_all_frames` behavior by passing it via connect-time `config`.
That config only reaches connections Soda creates itself (the file-read and
`:memory:`/path branches); it never reaches the `duckdb_connection` branch used
by `Scan.add_duckdb_connection(...)` -- the canonical pandas/polars workflow.

Because duckdb >=1.1.0 defaults `python_scan_all_frames` to False, a
user-supplied connection can no longer resolve a DataFrame defined in a caller
frame, and the check fails with "Table ... does not exist". The repo's existing
`test_pandas_df` did not catch this: the shared fixture pre-registers its own
connection (built through the config path, which already sets the flag), so a
fixture-based scan never exercises the externally-supplied-connection branch.

Fix:
- Restore `python_scan_all_frames` at runtime (via SET) on externally supplied
  connections, driven by `self.configuration` so overrides still win.
  (custom_user_agent can only be set at connect time, so it cannot be applied to
  a pre-existing connection.)
- Let callers override the applied settings through a new optional
  `configuration` argument on `add_duckdb_connection`, reusing the existing
  data-source `configuration` plumbing. Default restores the old behavior; pass
  `configuration={"python_scan_all_frames": False}` to opt out.
- Add regression tests that exercise the real user-connection branch (bare Scan,
  not the fixture): one guards the restored default, one verifies the override.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Niels-b
Niels-b force-pushed the fix/duckdb-scan-all-frames-external-connection branch from 1f2ded8 to e453794 Compare July 14, 2026 07:55
@sonarqubecloud

Copy link
Copy Markdown

@Niels-b
Niels-b merged commit a3b72fd into v3 Jul 14, 2026
15 of 16 checks passed
@Niels-b
Niels-b deleted the fix/duckdb-scan-all-frames-external-connection branch July 14, 2026 09:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants