From 29d1be0c2572eb37ec610ffa75ee72ef32d1ab7c Mon Sep 17 00:00:00 2001 From: Magnus Persson <1431685+magnusp@users.noreply.github.com> Date: Fri, 23 Oct 2026 01:50:40 +0200 Subject: [PATCH] test(jdbc): pin isFirst across cursor boundaries Assert isFirst is true only on the first row and false before the first row and after the last, including the single-row case. Current production behavior already satisfies java.sql, so no code change. xerial 3.53.4.0 reports true after the last row of a single-row result because isFirst() is row == 1 and next() leaves row unchanged on SQLITE_DONE. That difference is recorded as a reference note and not copied. --- .../jdbc/LibsqlResultSetNavigationTest.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/LibsqlResultSetNavigationTest.java b/libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/LibsqlResultSetNavigationTest.java index aeda4b5..c003068 100644 --- a/libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/LibsqlResultSetNavigationTest.java +++ b/libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/LibsqlResultSetNavigationTest.java @@ -118,6 +118,41 @@ void isLastAlwaysThrowsLikeXerial() throws SQLException { .hasMessage("not supported by sqlite"); } + @Test + void isFirstIsTrueOnlyOnTheFirstRow() throws SQLException { + LibsqlResultSet resultSet = resultSet(TWO_ROWS); + + assertThat(resultSet.isFirst()).isFalse(); + assertThat(resultSet.next()).isTrue(); + assertThat(resultSet.isFirst()).isTrue(); + assertThat(resultSet.next()).isTrue(); + assertThat(resultSet.isFirst()).isFalse(); + assertThat(resultSet.next()).isFalse(); + assertThat(resultSet.isFirst()).isFalse(); + assertThat(resultSet.next()).isFalse(); + assertThat(resultSet.isFirst()).isFalse(); + } + + @Test + void isFirstIsTrueOnTheSingleRowAndFalseAfterTheEnd() throws SQLException { + LibsqlResultSet resultSet = resultSet(DUPLICATE_LABELS); + + assertThat(resultSet.isFirst()).isFalse(); + assertThat(resultSet.next()).isTrue(); + assertThat(resultSet.isFirst()).isTrue(); + assertThat(resultSet.next()).isFalse(); + assertThat(resultSet.isFirst()).isFalse(); + } + + @Test + void isFirstIsFalseForAnEmptyResultSet() throws SQLException { + LibsqlResultSet resultSet = resultSet(NO_ROWS); + + assertThat(resultSet.isFirst()).isFalse(); + assertThat(resultSet.next()).isFalse(); + assertThat(resultSet.isFirst()).isFalse(); + } + @Test void wasNullThrowsBeforeAnyGetterAndAfterTheEndWithoutAGetter() throws SQLException { LibsqlResultSet beforeFirst = resultSet(DUPLICATE_LABELS);