Skip to content

Auto-close result returned from getResultSet - #781

Merged
staticlibs merged 1 commit into
duckdb:mainfrom
staticlibs:result_autoclose
Aug 3, 2026
Merged

Auto-close result returned from getResultSet#781
staticlibs merged 1 commit into
duckdb:mainfrom
staticlibs:result_autoclose

Conversation

@staticlibs

Copy link
Copy Markdown
Member

ResultSet objects returned from Statement#executeQuery() is closed automatically, when its parent statement is closed.

Per JDBC specification:

When a Statement object is closed, its current ResultSet object, if one exists, is also closed.

Though, when a ResultSet is obtained from Statement#execute() + Statement.getResultSet(), such ResultSet was not considered to be a "current ResultSet object" because, according to the spec:

This method [Statement.getResultSet()] should be called only once per result.

Thus such result set was not closed automatically.

Such code is used in practice and it has started to cause a memory leak (of the full materialized result set) after #533 was added.

This PR fixes the leak by retaining the ResultSet, returned from Statement.getResultSet(), as a "current ResultSet object" and closing it automatically on Statement close.

Testing: new tests added to TestClosure

Fixes: #780

`ResultSet` objects returned from `Statement#executeQuery()` is closed
automatically, when its parent statement is closed.

Per JDBC specification:

> When a Statement object is closed, its current ResultSet object, if
> one exists, is also closed.

Though, when a `ResultSet` is obtained from `Statement#execute()` +
`Statement.getResultSet()`, such `ResultSet` was not considered to be a
"current ResultSet object" because, according to the spec:

> This method [`Statement.getResultSet()`] should be called only once per
> result.

Thus such result set was not closed automatically.

Such code is used in practice and it has started to cause a memory leak
(of the full materialized result set) after duckdb#533 was added.

This PR fixes the leak by retaining the `ResultSet`, returned from
`Statement.getResultSet()`, as a "current ResultSet object" and closing
it automatically on `Statement` close.

Testing: new tests added to `TestClosure`

Fixes: duckdb#780
@staticlibs
staticlibs merged commit fc5cb0d into duckdb:main Aug 3, 2026
29 of 30 checks passed
@staticlibs
staticlibs deleted the result_autoclose branch August 3, 2026 21:15
staticlibs added a commit that referenced this pull request Aug 3, 2026
This is a backport of the PR #781 to `v1.5-variegata` stable branch.

`ResultSet` objects returned from `Statement#executeQuery()` is closed
automatically, when its parent statement is closed.

Per JDBC specification:

> When a Statement object is closed, its current ResultSet object, if
> one exists, is also closed.

Though, when a `ResultSet` is obtained from `Statement#execute()` +
`Statement.getResultSet()`, such `ResultSet` was not considered to be a
"current ResultSet object" because, according to the spec:

> This method [`Statement.getResultSet()`] should be called only once per
> result.

Thus such result set was not closed automatically.

Such code is used in practice and it has started to cause a memory leak
(of the full materialized result set) after #533 was added.

This PR fixes the leak by retaining the `ResultSet`, returned from
`Statement.getResultSet()`, as a "current ResultSet object" and closing
it automatically on `Statement` close.

Testing: new tests added to `TestClosure`

Fixes: #780
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.

Memory leak: Statement.getResultSet() result never freed when statement is closed

1 participant