Skip to content

fix(jdbc): close the StatementTest conversion and batch gaps - #160

Merged
magnusp merged 1 commit into
mainfrom
fix/i158-statement-gaps
Oct 23, 2026
Merged

magnusp merged 1 commit into
mainfrom
fix/i158-statement-gaps

Conversation

@magnusp

@magnusp magnusp commented Oct 23, 2026

Copy link
Copy Markdown
Owner

Fixes #158

What changed

Three driver gaps from the StatementTest re-triage now follow java.sql.

  • LibsqlResultSet: empty or blank TEXT reads as SQL NULL for getDate, getTime, getTimestamp, and the LocalDate/LocalTime/LocalDateTime targets. Other unparseable text still throws.
  • LibsqlStatement and LibsqlResultSet: setFetchDirection accepts FETCH_FORWARD, FETCH_REVERSE, and FETCH_UNKNOWN, and throws SQLException for any other value.
  • LibsqlStatement.executeBatch: a step whose StmtResult carries columns is a result set, so the batch throws BatchUpdateException with the counts of the steps up to and including it. LibsqlPreparedStatement inherits the same path.

Contract

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

Red

New unit cases at the base, before the fix:

./mvnw -pl libsql-jdbc -Dtest='LibsqlResultSetTest,LibsqlStatementTest' test
Tests run: 44, Failures: 2, Errors: 1
LibsqlResultSetTest.emptyTextDateAndTimeGettersReturnNull: SQL Bad value for type Date:
LibsqlStatementTest.batchThatReturnsResultsThrowsBatchUpdateException: Expecting code to raise a throwable
LibsqlStatementTest.setFetchDirectionRejectsAnUnknownDirection: Expecting code to raise a throwable

Vendored StatementTest at the base, with the triage copy selected temporarily:

./mvnw -pl libsql-conformance -am -Dit.test=StatementTest verify
Tests run: 46, Failures: 4, Errors: 4, Skipped: 1

Green

At head 853f9c484f03295b310630fab3eb7e634667f390:

./mvnw -pl libsql-jdbc -Dtest='LibsqlResultSetTest,LibsqlStatementTest' test
Tests run: 44, Failures: 0, Errors: 0

./mvnw -pl libsql-conformance -am -Dit.test=StatementTest verify
Tests run: 46, Failures: 2, Errors: 3, Skipped: 1

The five remaining cases are classified below. The three fixed cases are emptyDate, setFetchDirectionBadArgument, and batchReturnsResults.

Full lanes:

./mvnw -pl libsql-conformance -am verify              Tests run: 123, Failures: 0, Errors: 0, Skipped: 1
./mvnw -pl libsql-conformance -am -Pxerial-control verify  Tests run: 100, Failures: 0, Errors: 0, Skipped: 1
./mvnw -pl libsql-jdbc test                           Tests run: 311, Failures: 0, Errors: 0
./mvnw test                                           BUILD SUCCESS
./mvnw -pl libsql-jdbc -am package -DskipTests        BUILD SUCCESS
./mvnw spotless:check                                 BUILD SUCCESS
tools/export-upstream --verify                        verified

Logs are in /tmp/xerial-parity-i158/. The vendored tree is unchanged.

Remaining failures and divergences

  • dateTimeTest is a reference divergence. xerial's default DateClass.INTEGER stores setDate as epoch milliseconds, so getDate returns the original java.sql.Date millis. java.sql defines SQL DATE without a time, and java.sql.Date requires normalization to zero time before use. The test constructs a non-normalized Date, so preserving millis is an xerial implementation detail, not a requirement. A probe against xerial 3.53.4.0 confirmed stored type integer and exact millis. The driver keeps the java.sql date-only value and does not copy this behavior.
  • executeUpdate and multipleStatements are remote-model divergences. Hrana carries one statement per Stmt, and sqld rejects multi-statement strings with SQL_MANY_STATEMENTS / "SQL string contains more than one statement".
  • tempTable is a remote-model divergence. sqld rejects CREATE TEMP TABLE with SQL_PARSE_ERROR / "unsupported statement".
  • failToDropWhenRSOpen is a remote-model divergence. Hrana streams are independent and the driver materializes rows, so an open result set does not hold a local SQLite read lock that blocks DROP.

The later selection PR records these divergence lines. This PR does not edit the vendored test.

Files

libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlResultSet.java, libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlStatement.java, libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/LibsqlResultSetTest.java, libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/LibsqlStatementTest.java.

Base e172d2204c1bf57d80076067c93e7e4b6031f953, head 853f9c484f03295b310630fab3eb7e634667f390.

@magnusp
magnusp merged commit 36c7201 into main Oct 23, 2026
6 checks passed
@magnusp
magnusp deleted the fix/i158-statement-gaps branch October 23, 2026 03:12
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.

StatementTest exposes statement lifecycle and conversion gaps

1 participant