Skip to content

fix(jdbc): keep column origin aligned with the protocol width (#100) - #123

Merged
magnusp merged 1 commit into
mainfrom
fix/i100-star-width
Oct 22, 2026
Merged

magnusp merged 1 commit into
mainfrom
fix/i100-star-width

Conversation

@magnusp

@magnusp magnusp commented Oct 22, 2026

Copy link
Copy Markdown
Owner

Fixes #100

Contract: Hrana 3 is the source of truth for transport, values, and metadata. java.sql is the source of truth for the JDBC surface. xerial/sqlite-jdbc is a behavioral reference and conformance foundation, never a copy target.

Protocol basis

StmtResult.cols is authoritative for column count, name, and decltype. The protocol has no column-origin field, so the local parser supplies only table origin and nullability. The parser expansion is now compared with cols.size(), and it never overrides the protocol width.

Change

  • resolveColumnOrigins passes cols.size() to a new SqlTableReference.resolve(sql, schema, columnCount) overload that discards the resolution when the parser expansion count differs. Every misalignment reports an empty table name and columnNullableUnknown instead of a wrong table.
  • Table column lists load through pragma_table_xinfo with p.hidden != 1, so generated columns are present in * expansions and virtual-table hidden columns stay out.
  • * expansion drops the right-side duplicate of a USING or NATURAL join column, which is what SQLite does.
  • Tests cover a USING join, a NATURAL join, a generated-column table joined with another table, a VALUES subquery, and an unknown source, each asserting the resolved column count equals the result column count.

Evidence

Red at base 2c83a84 (new tests only, width seam returning the parser result unchanged):

  • SqlTableReferenceTest: 22 run, 3 failed. USING, NATURAL, and width-discard cases failed on [resolved column count equals the result column count] Expecting value to be true but was false. Log: /tmp/xerial-parity-i100/red-parser.log.
  • LibsqlResultSetMetaDataTest: 30 run, 3 failed. resolvesUsingJoinStarColumnsToTheLeftTable expected "c" but was "b", resolvesGeneratedColumnStarColumnsThroughTableXinfo expected "g" but was "c", leavesEveryColumnUnknownWhenTheStarWidthDiffers Expecting empty but was: "c". Log: /tmp/xerial-parity-i100/red-metadata.log.

Green at head a755f21:

Lane Command Result
1 Regression ./mvnw -pl libsql-jdbc test -Dtest=SqlTableReferenceTest 22 run, 0 failed (/tmp/xerial-parity-i100/green-parser.log)
2 Metadata ./mvnw -pl libsql-jdbc test -Dtest=LibsqlResultSetMetaDataTest 30 run, 0 failed (/tmp/xerial-parity-i100/green-metadata.log)
3 USING end to end resolvesUsingJoinStarColumnsToTheLeftTable merged column resolves to the left table a, z to c
4 Module suite ./mvnw -pl libsql-jdbc test 197 run, 0 failed, BUILD SUCCESS (lane-4-module-suite.log)
5 Conformance ./mvnw -pl libsql-conformance -am verify 115 run, 0 failed, 1 skipped, BUILD SUCCESS (lane-5-conformance.log)
6 xerial control ./mvnw -pl libsql-conformance -am -Pxerial-control verify 100 run, 0 failed, 1 skipped, BUILD SUCCESS (lane-6-control.log)
7 Format ./mvnw spotless:check BUILD SUCCESS, no violations (lane-7-spotless.log)
8 Reactor ./mvnw test BUILD SUCCESS, 197 run in libsql-jdbc (lane-8-reactor.log)
9 Vendored RSMetaDataTest inside lane 5 13 run, 0 failed
10 Package ./mvnw -pl libsql-jdbc -am package -DskipTests jar built (lane-10-package.log)

Perf: wall clock of ./mvnw -pl libsql-jdbc test, three interleaved runs per side. Trunk median 2.14 s, head median 2.17 s, +1.4 percent, inside the ten percent rule (perf-interleaved.log).

Divergence

None from SQLite or xerial. When the parser cannot prove alignment the driver reports the documented JDBC unknown values, which is the behavior the issue asks for.

Base 2c83a84, head a755f21.

The parser mapped the Nth select item to the Nth result column without
comparing the two widths. A `*` expansion that SQLite narrows, such as a
USING or NATURAL join, or that the parser cannot expand at all, shifted
every later column onto the wrong table.

Discard the resolution when the expansion width differs from
`StmtResult.cols`, so a misalignment reports an unknown origin instead of
a wrong one. Load table columns through `pragma_table_xinfo` and exclude
hidden columns, which keeps generated columns in the expansion. Drop the
right-side duplicate of a USING or NATURAL join column while expanding
`*`.
@magnusp
magnusp merged commit cb1c609 into main Oct 22, 2026
4 checks passed
@magnusp
magnusp deleted the fix/i100-star-width branch October 22, 2026 19:27
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.

Column origin resolution shifts after SELECT * when the expanded width differs from SQLite

1 participant