Skip to content

Fix columns with the same name returning the wrong values - #34

Merged
CollierKing merged 1 commit into
CollierKing:mainfrom
danielalyoshin:fix/duplicate-column-names
Oct 2, 2026
Merged

CollierKing merged 1 commit into
CollierKing:mainfrom
danielalyoshin:fix/duplicate-column-names

Conversation

@danielalyoshin

Copy link
Copy Markdown
Contributor

Problem

When a query returns two columns with the same name, every one of them gets the value of the last one (#31). SELECT a.id, a.name, b.id FROM a JOIN b ON b.a_id = a.id returns (7, 'x', 7) instead of (1, 'x', 7), and SELECT * over a join hits it whenever both tables have an id. _execute_query turned each /raw row into dict(zip(columns, row)), and fetchone read the values back by name.

Fix

Keep the rows as the arrays /raw sends and build the tuples by position, in both Connection and AsyncConnection. Worker rows come from all() as dicts and are read as before. all() gives one object per row, so same-name columns are already merged there, and this PR does not change that path.

Tests

  • New tests/unit/test_connection.py with fake /raw replies through httpx.MockTransport: the sync cursor, the async cursor and a SQLAlchemy engine all return (1, 'x', 7). The new tests fail without the fix. Unit suite: 48 passed on Python 3.11 and 3.9.
  • REST API integration against a real D1: new TestColumnsWithSameName class (join through the cursor, SELECT * over the join, join through SQLAlchemy). All 3 fail on main. With the fix, the REST API and base URL integration files pass: 89 passed.
  • ruff check, ruff format --diff, mypy src/, codespell and pre-commit run --all-files are clean.
  • Worker integration tests were not run here. The Worker path is unchanged.

This PR and #33 touch different lines and merge cleanly together.

Fixes #31

The /raw rows were turned into dicts keyed by column name, and fetchone
read the values back by name. When two columns shared a name, as in
SELECT a.id, b.id or SELECT * over a join, the last one overwrote the
others, so every one of them came back with the same value.

Keep the rows as the arrays D1 sends and build the tuples by position.
Worker rows from all() are still dicts and are read as before.

Fixes CollierKing#31
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.

Columns with the same name come back with the wrong values

2 participants