Skip to content

Preserve duplicate column names in query results, closes #624#773

Merged
simonw merged 1 commit into
mainfrom
duplicate-column-names
Jul 6, 2026
Merged

Preserve duplicate column names in query results, closes #624#773
simonw merged 1 commit into
mainfrom
duplicate-column-names

Conversation

@simonw

@simonw simonw commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Queries returning duplicate column names - e.g. joins between tables sharing column names - silently lost values because rows were built with dict(zip(keys, row)), where the last duplicate wins.

Later occurrences are now renamed with a numeric suffix: id, id becomes id, id_2 - skipping any suffix that would collide with a real column in the same query.

The new utils.dedupe_keys() helper transforms the key list once per query, so the per-row dict construction is unchanged and there is no measurable performance impact.

Applied in Database.query() (including the PRAGMA and RETURNING paths), Table.rows_where(), Table.search() and the CLI's JSON output. CSV, TSV and table output keep the original duplicate headers.

Replaces:

Closes:

@simonw simonw marked this pull request as ready for review July 5, 2026 23:21
@codecov

codecov Bot commented Jul 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.24%. Comparing base (a00ed60) to head (4a03fe6).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #773      +/-   ##
==========================================
+ Coverage   95.22%   95.24%   +0.02%     
==========================================
  Files           9        9              
  Lines        3578     3597      +19     
==========================================
+ Hits         3407     3426      +19     
  Misses        171      171              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

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

@simonw

simonw commented Jul 5, 2026

Copy link
Copy Markdown
Owner Author

Without this fix:

uvx sqlite-utils memory 'select 1 as n, 2 as n'
[{"n": 2}]

With this fix:

uv run sqlite-utils memory 'select 1 as n, 2 as n'
[{"n": 1, "n_2": 2}]

Queries returning duplicate column names - e.g. joins between tables
sharing column names - silently lost values because rows were built
with dict(zip(keys, row)), where the last duplicate wins.

Later occurrences are now renamed with a numeric suffix: id, id
becomes id, id_2 - skipping any suffix that would collide with a
real column in the same query.

The new utils.dedupe_keys() helper transforms the key list once per
query, so the per-row dict construction is unchanged and there is no
measurable performance impact.

Applied in Database.query() (including the PRAGMA and RETURNING
paths), Table.rows_where(), Table.search() and the CLI's JSON output.
CSV, TSV and table output keep the original duplicate headers.

Refs #722

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@simonw simonw force-pushed the duplicate-column-names branch from 68e730c to 4a03fe6 Compare July 6, 2026 04:18
@simonw

simonw commented Jul 6, 2026

Copy link
Copy Markdown
Owner Author

Failures in CI relate to the GitHub Actions cache service, I'm merging anyway.

@simonw simonw merged commit 07b603e into main Jul 6, 2026
104 of 108 checks passed
@simonw simonw deleted the duplicate-column-names branch July 6, 2026 04:20
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.

1 participant