diff --git a/src/main/java/org/duckdb/DuckDBPreparedStatement.java b/src/main/java/org/duckdb/DuckDBPreparedStatement.java index 0d056057b..c62f12973 100644 --- a/src/main/java/org/duckdb/DuckDBPreparedStatement.java +++ b/src/main/java/org/duckdb/DuckDBPreparedStatement.java @@ -53,6 +53,7 @@ public class DuckDBPreparedStatement implements PreparedStatement { volatile boolean closeOnCompletion = false; private DuckDBResultSet selectResult = null; + private boolean selectResultReturned = false; private long updateResult = 0; private DuckDBChunkedResult chunkedResult = null; @@ -231,6 +232,7 @@ public boolean execute() throws SQLException { cleanupCancelQueryTask(); DuckDBResultSetMetaData resultMeta = DuckDBNative.duckdb_jdbc_query_result_meta(resultRef); selectResult = new DuckDBResultSet(conn, this, resultMeta, resultRef); + selectResultReturned = false; returnsResultSet = resultMeta.return_type.equals(QUERY_RESULT); returnsChangedRows = resultMeta.return_type.equals(CHANGED_ROWS); returnsNothing = resultMeta.return_type.equals(NOTHING); @@ -607,14 +609,13 @@ public ResultSet getResultSet() throws SQLException { throw new SQLException("Statement was closed"); } - if (!returnsResultSet) { + if (!returnsResultSet || selectResultReturned) { return null; } // getResultSet can only be called once per result - ResultSet to_return = selectResult; - this.selectResult = null; - return to_return; + this.selectResultReturned = true; + return selectResult; } private long getUpdateCountInternal() throws SQLException { @@ -1374,6 +1375,7 @@ private void clearResults() throws SQLException { if (selectResult != null) { selectResult.close(); selectResult = null; + selectResultReturned = false; } if (chunkedResult != null) { chunkedResult.close(); diff --git a/src/test/java/org/duckdb/TestClosure.java b/src/test/java/org/duckdb/TestClosure.java index 8f8787e2a..6c4f549e6 100644 --- a/src/test/java/org/duckdb/TestClosure.java +++ b/src/test/java/org/duckdb/TestClosure.java @@ -110,6 +110,18 @@ public static void test_results_auto_closed_on_conn_close() throws Exception { assertTrue(stmt.isClosed()); } + public static void test_results_execute_auto_closed_on_conn_close() throws Exception { + Connection conn = DriverManager.getConnection(JDBC_URL); + Statement stmt = conn.createStatement(); + stmt.execute("select 42"); + ResultSet rs = stmt.getResultSet(); + assertNull(stmt.getResultSet()); + rs.next(); + conn.close(); + assertTrue(rs.isClosed()); + assertTrue(stmt.isClosed()); + } + public static void test_results_auto_closed_on_conn_close_prepared() throws Exception { Connection conn = DriverManager.getConnection(JDBC_URL); PreparedStatement ps = conn.prepareStatement("select 42"); @@ -120,6 +132,18 @@ public static void test_results_auto_closed_on_conn_close_prepared() throws Exce assertTrue(ps.isClosed()); } + public static void test_results_execute_auto_closed_on_conn_close_prepared() throws Exception { + Connection conn = DriverManager.getConnection(JDBC_URL); + PreparedStatement ps = conn.prepareStatement("select 42"); + ps.execute(); + ResultSet rs = ps.getResultSet(); + assertNull(ps.getResultSet()); + rs.next(); + conn.close(); + assertTrue(rs.isClosed()); + assertTrue(ps.isClosed()); + } + public static void test_result_chunked_auto_closed_on_conn_close_prepared() throws Exception { DuckDBConnection conn = DriverManager.getConnection(JDBC_URL).unwrap(DuckDBConnection.class); DuckDBPreparedStatement ps = conn.prepare("select 42");