Skip to content

Fix optimizer crash in JDBC by ensuring active_query is set during prepare#551

Closed
thijs-s wants to merge 2 commits intoduckdb:mainfrom
ilum-cloud:fix/jdbc-optimizer
Closed

Fix optimizer crash in JDBC by ensuring active_query is set during prepare#551
thijs-s wants to merge 2 commits intoduckdb:mainfrom
ilum-cloud:fix/jdbc-optimizer

Conversation

@thijs-s
Copy link

@thijs-s thijs-s commented Jan 30, 2026

This PR fixes a crash/NPE encountered when using optimizer extensions with the JDBC driver.

Issue

When Connection.prepareStatement() is called, ClientContext::PrepareInternal is executed. Previously, active_query was not set in the ClientContext during this phase. If an optimizer extension (hooked into PreparedStatement creation) attempted to access context.GetCurrentQuery(), it would dereference a null pointer (or hit an assertion in debug builds), causing a crash.

Solution

The ClientContext requires an initialized active_query state for the optimizer to function correctly (e.g., to access the query string). This state was previously missing during the JDBC prepare phase (PrepareInternal), which caused the crash.

We now correctly initialize active_query within PrepareInternal using a new RAII helper struct ActiveQueryGuard. This ensures the context is fully populated for the duration of the preparation, satisfying the requirements of optimizer extensions.

  • The ActiveQueryGuard sets active_query upon initialization.
  • It guarantees active_query is reset to nullptr when the scope exits, preserving ClientContext invariants.
  • The implementation is exception-safe: even if an exception occurs during statement preparation or memory allocation, the destructor ensures proper cleanup.

Initialize `active_query` in `ClientContext::PrepareInternal` to ensure the optimizer has a valid context during statement preparation. This fixes a null pointer dereference encountered by optimizer extensions when accessing `GetCurrentQuery()` via the JDBC driver.

The implementation uses a new `ActiveQueryGuard` RAII helper to ensure strict exception safety and proper resource cleanup.

Added regression tests in `TestOptimizerCrash.java`.
@staticlibs
Copy link
Collaborator

Hi, thanks for the PR! Please note, that sources in src/duckdb are periodically copied from the https://github.com/duckdb/duckdb repo, so such changes should be submitted there. As the engine sources are copied (not forked) it is not possible to move this PR there. So I suggest to open a new PR with these changes in duckdb/duckdb (it may still be acceptable to target it to v1.5-variegata branch to be included into the upcoming 1.5.0 release).

@thijs-s
Copy link
Author

thijs-s commented Jan 31, 2026

thanks for the info! Done. duckdb/duckdb#20755

@thijs-s thijs-s closed this Jan 31, 2026
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.

2 participants