Skip to content

feat(jdbc): read key and type metadata from SQLite pragmas - #143

Merged
magnusp merged 1 commit into
mainfrom
fix/i113-key-metadata
Oct 23, 2026
Merged

magnusp merged 1 commit into
mainfrom
fix/i113-key-metadata

Conversation

@magnusp

@magnusp magnusp commented Oct 23, 2026

Copy link
Copy Markdown
Owner

Fixes #113.

Contract: Hrana 3 governs transport and values, so the pragmas run through execute; java.sql defines the 14-column foreign-key shape, the six primary-key columns, and the 18 type-info columns; xerial/sqlite-jdbc 3.53.4.0 is the behavioral reference for row values and the type table.

Changes

  • getImportedKeys, getExportedKeys, and getCrossReference read pragma foreign_key_list (joined to sqlite_schema for constraint names and case-corrected table names) and synthesize the xerial row shape, including KEY_SEQ, update/delete rule constants, FK_NAME, PK_NAME, and DEFERRABILITY.
  • getTypeInfo returns the sqlite-jdbc type table: NULL, INTEGER, REAL, TEXT, BLOB, ordered by DATA_TYPE, with the same per-type flags.
  • getPrimaryKeys parses a named CONSTRAINT ... PRIMARY KEY from the table SQL and reports it in PK_NAME; inline primary keys keep a NULL PK_NAME.
  • Empty databases and tables without foreign keys return well-formed empty result sets, not errors.

Divergences and reference notes

  • getCrossReference with both a parent and a child table returns the real matching rows. xerial ends that path in limit 0 and returns no rows. Reason: the issue asks for pragma-driven key metadata, and the both-table form is the useful cross-reference query.
  • getPrimaryKeys keeps the driver's existing KEY_SEQ ordering. xerial orders primary-key columns by COLUMN_NAME; ordering is unchanged by this PR and composites remain readable through KEY_SEQ.
  • DEFERRABILITY is always importedKeyInitiallyDeferred, matching xerial. pragma foreign_key_list does not expose deferrability.
  • Missing FK/PK names are empty strings in imported/exported rows and NULL in getPrimaryKeys, matching xerial.

Evidence at head d6ea8b7 (base 662d066)

Lane Command Result
1 regression ./mvnw -pl libsql-jdbc test -Dtest=LibsqlDatabaseMetaDataTest at trunk Red: 7 failures, 1 error; the new cases fail on the WHERE 0 stubs and missing PK_NAME
1 regression same at head Green: 35/35
2 row shape targeted shape probes Green: 14 FK columns, rule constants, named FK/PK, xerial type table
3 live sqld DOCKER_CONFIG=... ./mvnw -pl libsql-itests -am -Dit.test=DatabaseMetaDataIT verify Green: 2/2; pragmas round-trip through Hrana
4 module ./mvnw -pl libsql-jdbc test BUILD SUCCESS, 264 tests
5 conformance ./mvnw -pl libsql-conformance -am verify BUILD SUCCESS, 123 tests, 1 skipped
6 control ./mvnw -pl libsql-conformance -am -Pxerial-control verify BUILD SUCCESS, 100 tests, 1 skipped
7 format ./mvnw spotless:check BUILD SUCCESS
8 reactor ./mvnw test BUILD SUCCESS
9 empty case -Dtest=LibsqlDatabaseMetaDataTest#emptyDatabaseReturnsWellFormedEmptyKeyMetadata Green: empty results are well-formed
10 package ./mvnw -pl libsql-jdbc -am package -DskipTests BUILD SUCCESS; driver jar built
perf module test, 3 interleaved runs per side Trunk median 2.05 s, head median 2.09 s (+1.95%, within 10%)

Logs: /tmp/xerial-parity-i113/.

Files outside the plan's Files block

  • libsql-itests/src/test/java/com/github/magnusp/libsql/itest/DatabaseMetaDataIT.java is new. Lane 3 requires a live sqld metadata case, and the plan's Files block names no itest file.

Ready for review. Not merged.

getImportedKeys, getExportedKeys, and getCrossReference now map pragma foreign_key_list rows to the JDBC shape, getTypeInfo returns the sqlite-jdbc type table, and getPrimaryKeys reports the parsed constraint name in PK_NAME.

Fixes #113
@magnusp
magnusp merged commit ba3f2e7 into main Oct 23, 2026
6 checks passed
@magnusp
magnusp deleted the fix/i113-key-metadata branch October 23, 2026 00:47
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.

getImportedKeys, getExportedKeys, getCrossReference, and getTypeInfo return empty results

1 participant