Skip to content

test(jdbc): pin closeOnCompletion result-set close per java.sql - #147

Merged
magnusp merged 1 commit into
mainfrom
fix/i86-close-on-completion
Oct 23, 2026
Merged

magnusp merged 1 commit into
mainfrom
fix/i86-close-on-completion

Conversation

@magnusp

@magnusp magnusp commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Fixes #86

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 is a behavioral reference and conformance foundation, never a copy target. This change is protocol-neutral: java.sql defines the lifecycle.

What changed

Closing a result set on a statement whose closeOnCompletion flag is set closes the statement, per java.sql. The driver already did this in LibsqlResultSet.close(), so no production behavior changed. This PR pins the rule in LibsqlStatementLifecycleTest for the executeQuery, execute + getResultSet, and prepared-statement paths, keeps the non-flag case open, and includes the #119 metadata statement case, which closes through its own closeStatementOnClose flag while isCloseOnCompletion() stays false. The change to LibsqlStatement.java is the class-javadoc bullet that documents the rule.

Red and green

  • Green: LibsqlStatementLifecycleTest, 14/14 pass at head (fbabb79).
  • Probe: the new cases also pass at origin/main (3adf8e3), because the behavior pre-existed. Lane 1's plan expectation of red at trunk therefore does not apply to this issue; the coverage gap, not a behavior gap, was real.
  • Pin proof: mutating the auto-close condition out of LibsqlResultSet.close() in a throwaway trunk worktree fails exactly the three new close-on-completion cases (3 failures) and leaves the metadata case green. Logs: /tmp/xerial-parity-i86/lane-1-trunk.log, lane-1-head.log, lane-1-mutation.log.

xerial reference note

The issue text says xerial only tracks the flag. That does not reproduce on the pinned xerial 3.53.4.0. JDBC4ResultSet.close() closes the statement when JDBC4Statement.closeOnCompletion is set, and prepared statements inherit that class through CorePreparedStatement extends JDBC4Statement. A direct probe against the pinned jar shows a plain statement and a prepared statement both report isClosed() == true after ResultSet.close() (/tmp/xerial-parity-i86/xerial-probe.log). So this is a reference match, not a divergence: both drivers auto-close, and this PR keeps the JDBC-correct behavior with no xerial-specific exception.

Evidence

Base 3adf8e3bfe05840aa3d18649e4b6036a50e35b76 (origin/main), head fbabb791b6375447748ca1c501ba9d675f44c80a. Logs in /tmp/xerial-parity-i86/.

Lane Command Result
1 lifecycle at trunk / head pre-existing pass at both; mutation probe red 3/3
2 -pl libsql-jdbc test -Dtest=LibsqlDatabaseMetaDataTest 36/36 pass, #119 leak cases green
3 -pl libsql-conformance -am verify -Dit.test=MetadataLeakTest 1/1 pass
4 -pl libsql-jdbc test 278/278, BUILD SUCCESS
5 -pl libsql-conformance -am verify 123 tests, 1 skipped, BUILD SUCCESS
6 -pl libsql-conformance -am -Pxerial-control verify 100 tests, 1 skipped, BUILD SUCCESS
7 spotless:check BUILD SUCCESS
8 ./mvnw test reactor BUILD SUCCESS
9 full LibsqlStatementLifecycleTest 14/14 pass
10 -pl libsql-jdbc -am package -DskipTests jar built

Perf: -pl libsql-jdbc test wall clock, three interleaved runs each side. Trunk median 2.09 s, head median 2.15 s (+2.9%, within the 10% rule). No hot-path code changed.

Note: the plan names mise exec --; this environment's brief and AGENTS.md say to run java and ./mvnw directly. Every lane above ran without mise.

Closing a result set on a statement with closeOnCompletion set closes the
statement, per java.sql. The driver already did this through LibsqlResultSet;
add lifecycle cases for the query, execute, and prepared paths, keep the
metadata statement case from #119 in the pin, and document the rule.

A probe against the pinned xerial 3.53.4.0 shows it also auto-closes
(JDBC4ResultSet.close checks JDBC4Statement.closeOnCompletion, and prepared
statements inherit JDBC4Statement), so no divergence exists to record.
@magnusp
magnusp merged commit 9bf5d0f into main Oct 23, 2026
6 checks passed
@magnusp
magnusp deleted the fix/i86-close-on-completion branch October 23, 2026 01:33
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.

closeOnCompletion auto-closes on ResultSet.close; xerial only tracks the flag

1 participant