-
Notifications
You must be signed in to change notification settings - Fork 27
[PECOBLR-954] Close statements based on Execute Statement Response SEA #1109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Add testing section |
src/main/java/com/databricks/jdbc/dbclient/impl/sqlexec/DatabricksSdkClient.java
Show resolved
Hide resolved
src/main/java/com/databricks/jdbc/api/impl/DatabricksStatement.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements server-side statement closure detection for Databricks JDBC connections. When the server returns a CLOSED status in the Execute Statement Response, the driver now soft-closes the statement locally without attempting to close it again on the server.
Key changes:
- Added
markAsClosed()method to mark statements as closed when server indicates closure - Modified statement close logic to skip server-side close calls for already-closed statements
- Added detection of
CLOSEDstatus in execute statement responses
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| DatabricksStatement.java | Added markAsClosed() method and updated close() to handle pre-closed statements |
| DatabricksSdkClient.java | Added detection of CLOSED status in execute responses to trigger markAsClosed() |
| DatabricksStatementTest.java | Added comprehensive test coverage for markAsClosed() scenarios |
| DatabricksSdkClientTest.java | Added tests for execute statement with closed status responses |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (resultSet != null) { | ||
| this.resultSet.close(); | ||
| this.resultSet = null; | ||
| } |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The early return path for isClosed doesn't shut down the executor or remove the statement from session. This creates inconsistent cleanup behavior compared to the normal close path. Consider calling shutdownExecutor() and handling session removal in this branch as well to ensure complete resource cleanup.
| } | |
| } | |
| if (removeFromSession) { | |
| this.connection.closeStatement(this); | |
| } | |
| shutDownExecutor(); | |
| this.isClosed = true; | |
| return; |
| this.resultSet.close(); | ||
| this.resultSet = null; |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When resultSet.close() throws an exception in the isClosed branch, the exception propagates without setting isClosed flag or logging. The normal close path has better error handling. Consider wrapping this in a try-catch to ensure the statement remains in a consistent state even if result set closure fails.
| this.resultSet.close(); | |
| this.resultSet = null; | |
| try { | |
| this.resultSet.close(); | |
| } catch (Exception e) { | |
| LOGGER.warn("Exception while closing resultSet in already closed statement", e); | |
| warnings = WarningUtil.addWarning(warnings, "Exception while closing resultSet: " + e.getMessage()); | |
| } finally { | |
| this.resultSet = null; | |
| this.isClosed = true; | |
| } |
| public void markAsClosed() { | ||
| LOGGER.debug("Marking statement {} as closed (server already closed)", statementId); | ||
| this.connection.closeStatement(this); | ||
| DatabricksThreadContextHolder.clearStatementInfo(); | ||
| this.isClosed = true; | ||
| } |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The markAsClosed() method is not synchronized, but it modifies shared state (isClosed) and calls methods that may have concurrency implications. If this method can be called from multiple threads (e.g., during statement execution and timeout handling), it could lead to race conditions. Consider adding synchronization or documenting thread-safety assumptions.
Description
Close statements based on Execute Statement Response SEA
Flow:
executeQueryexecuteInternalinDatabricksStatementis called, and creates direct same thread executorgetResultFromClientstatus: CLOSED, we detect the state and callmarkAsClosedwhich soft closes the statement (does not shut down the executor)statement.close()DatabricksStatementseesisClosed=true, skips the server close (since it's already closed), closes result set and shuts down the executor.Testing
Additional Notes to the Reviewer