Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions src/main/java/org/duckdb/DuckDBArrayResultSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -317,22 +317,22 @@ public BigDecimal getBigDecimal(String columnLabel) throws SQLException {

@Override
public boolean isBeforeFirst() throws SQLException {
return currentValueIndex < 0;
return length > 0 && currentValueIndex < 0;
}

@Override
public boolean isAfterLast() throws SQLException {
return currentValueIndex >= length;
return length > 0 && currentValueIndex >= length;
}

@Override
public boolean isFirst() throws SQLException {
return currentValueIndex == 0;
return length > 0 && currentValueIndex == 0;
}

@Override
public boolean isLast() throws SQLException {
return currentValueIndex == length - 1;
return length > 0 && currentValueIndex == length - 1;
}

@Override
Expand Down Expand Up @@ -365,7 +365,7 @@ public boolean last() throws SQLException {

@Override
public int getRow() throws SQLException {
return currentValueIndex + 1;
return isValidRow() ? currentValueIndex + 1 : 0;
}

@Override
Expand All @@ -379,12 +379,16 @@ public boolean absolute(int row) throws SQLException {
return checkBounds();
}

private boolean isValidRow() {
return currentValueIndex >= 0 && currentValueIndex < length;
}

private boolean checkBounds() {
if (currentValueIndex < -1) {
if (currentValueIndex < 0) {
currentValueIndex = -1;
return false;
}
if (currentValueIndex > length) {
if (currentValueIndex >= length) {
currentValueIndex = length;
return false;
}
Expand Down
128 changes: 128 additions & 0 deletions src/test/java/org/duckdb/TestDuckDBJDBC.java
Original file line number Diff line number Diff line change
Expand Up @@ -1405,6 +1405,134 @@ public static void test_array_resultset() throws Exception {
}
}

@SuppressWarnings("try")
public static void test_array_resultset_cursor() throws Exception {
try (Connection connection = DriverManager.getConnection(JDBC_URL);
Statement statement = connection.createStatement()) {
try (ResultSet rs = statement.executeQuery("select [10, 20, 30]")) {
assertTrue(rs.next());
try (ResultSet arrayResultSet = rs.getArray(1).getResultSet()) {
// initial position: before first, not on a row
assertTrue(arrayResultSet.isBeforeFirst());
assertFalse(arrayResultSet.isAfterLast());
assertFalse(arrayResultSet.isFirst());
assertFalse(arrayResultSet.isLast());
assertEquals(arrayResultSet.getRow(), 0);

// absolute positive within bounds
assertTrue(arrayResultSet.absolute(2));
assertFalse(arrayResultSet.isBeforeFirst());
assertFalse(arrayResultSet.isAfterLast());
assertFalse(arrayResultSet.isFirst());
assertFalse(arrayResultSet.isLast());
assertEquals(arrayResultSet.getRow(), 2);
assertEquals(arrayResultSet.getInt(2), 20);

assertTrue(arrayResultSet.absolute(1));
assertTrue(arrayResultSet.isFirst());
assertEquals(arrayResultSet.getRow(), 1);

// absolute beyond last (length + 1) -> after last
assertFalse(arrayResultSet.absolute(4));
assertTrue(arrayResultSet.isAfterLast());
assertFalse(arrayResultSet.isBeforeFirst());
assertEquals(arrayResultSet.getRow(), 0);

// absolute(0) -> before first
assertFalse(arrayResultSet.absolute(0));
assertTrue(arrayResultSet.isBeforeFirst());
assertFalse(arrayResultSet.isAfterLast());
assertEquals(arrayResultSet.getRow(), 0);

// negative absolute counts from the end
assertTrue(arrayResultSet.absolute(-1));
assertTrue(arrayResultSet.isLast());
assertEquals(arrayResultSet.getRow(), 3);
assertEquals(arrayResultSet.getInt(2), 30);

assertTrue(arrayResultSet.absolute(-3));
assertTrue(arrayResultSet.isFirst());
assertEquals(arrayResultSet.getRow(), 1);

assertFalse(arrayResultSet.absolute(-4));
assertTrue(arrayResultSet.isBeforeFirst());
assertEquals(arrayResultSet.getRow(), 0);

// relative edges
assertTrue(arrayResultSet.absolute(1));
assertTrue(arrayResultSet.relative(2));
assertTrue(arrayResultSet.isLast());
assertFalse(arrayResultSet.relative(1));
assertTrue(arrayResultSet.isAfterLast());
assertFalse(arrayResultSet.relative(0));

assertTrue(arrayResultSet.absolute(1));
assertTrue(arrayResultSet.relative(0));
assertTrue(arrayResultSet.isFirst());

// previous from the first row -> before first
assertFalse(arrayResultSet.previous());
assertTrue(arrayResultSet.isBeforeFirst());
assertFalse(arrayResultSet.isAfterLast());
assertEquals(arrayResultSet.getRow(), 0);
// previous again stays before first
assertFalse(arrayResultSet.previous());
assertTrue(arrayResultSet.isBeforeFirst());
assertEquals(arrayResultSet.getRow(), 0);

// next walks 1 -> 2 -> 3 -> after last
assertTrue(arrayResultSet.next());
assertTrue(arrayResultSet.isFirst());
assertEquals(arrayResultSet.getRow(), 1);
assertEquals(arrayResultSet.getInt(2), 10);

// second next -> second row, neither first nor last
assertTrue(arrayResultSet.next());
assertFalse(arrayResultSet.isBeforeFirst());
assertFalse(arrayResultSet.isFirst());
assertFalse(arrayResultSet.isLast());
assertEquals(arrayResultSet.getRow(), 2);
assertEquals(arrayResultSet.getInt(2), 20);

// third next -> last row
assertTrue(arrayResultSet.next());
assertFalse(arrayResultSet.isFirst());
assertTrue(arrayResultSet.isLast());
assertEquals(arrayResultSet.getRow(), 3);
assertEquals(arrayResultSet.getInt(2), 30);

// fourth next -> after last
assertFalse(arrayResultSet.next());
assertFalse(arrayResultSet.isBeforeFirst());
assertTrue(arrayResultSet.isAfterLast());
assertEquals(arrayResultSet.getRow(), 0);
}
}

// empty array (0 values)
try (ResultSet rs = statement.executeQuery("select []::INTEGER[]")) {
assertTrue(rs.next());
try (ResultSet empty = rs.getArray(1).getResultSet()) {
assertFalse(empty.isBeforeFirst());
assertFalse(empty.isAfterLast());
assertEquals(empty.getRow(), 0);
assertFalse(empty.first());
assertFalse(empty.last());
assertFalse(empty.next());
assertFalse(empty.absolute(1));
assertFalse(empty.absolute(-1));
assertFalse(empty.absolute(0));
assertFalse(empty.relative(1));
assertFalse(empty.relative(0));
assertFalse(empty.previous());
assertFalse(empty.isBeforeFirst());
assertFalse(empty.isAfterLast());
assertEquals(empty.getRow(), 0);
}
}
}
}

@SuppressWarnings("unchecked")
private static <T> List<T> arrayToList(Array array) throws SQLException {
return arrayToList((T[]) array.getArray());
Expand Down
Loading