Skip to content

feat: Druid JDBC driver. - #19951

Open
gianm wants to merge 2 commits into
apache:masterfrom
gianm:jdbc-driver
Open

feat: Druid JDBC driver.#19951
gianm wants to merge 2 commits into
apache:masterfrom
gianm:jdbc-driver

Conversation

@gianm

@gianm gianm commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

This patch adds a Druid JDBC driver that uses the regular endpoint, /druid/v2/sql/. It is recommended over the Avatica driver for a variety of benefits, including: driver-side connection management that doesn't require sticky load balancing, streaming results, support for SET statements, and support for non-native SqlEngines.

In addition to the new module, there are core changes:

  1. TIMESTAMP parameters to parameterized queries, when provided as strings
    with zone offsets, are now correctly interpreted in the provided zone.

  2. SQL now correctly treats function names in JDBC {fn ...} escapes
    case-insensitively.

  3. SQL now correctly handles the JDBC escape {fn now()}.

@github-actions github-actions Bot added Area - Documentation Area - Batch Ingestion Area - Querying Area - Dependencies Area - MSQ For multi stage queries - https://github.com/apache/druid/issues/12262 labels Aug 10, 2026
This patch adds a Druid JDBC driver that uses the regular endpoint,
/druid/v2/sql/. It is recommended over the Avatica driver for a variety
of benefits, including: driver-side connection management that doesn't
require sticky load balancing, streaming results, support for SET
statements, and support for non-native SqlEngines.

In addition to the new module, there are core changes:

1) TIMESTAMP parameters to parameterized queries, when provided as strings
   with zone offsets, are now correctly interpreted in the provided zone.

2) SQL now correctly treats function names in JDBC {fn ...} escapes
   case-insensitively.

3) SQL now correctly handles the JDBC escape {fn now()}.
Comment thread jdbc-driver/src/main/java/org/apache/druid/jdbc/http/DruidHttpClientImpl.java Dismissed
Comment thread jdbc-driver/src/test/java/org/apache/druid/jdbc/DruidDatabaseMetaDataTest.java Dismissed
Comment thread jdbc-driver/src/main/java/org/apache/druid/jdbc/DruidPreparedStatement.java Dismissed
Comment thread jdbc-driver/src/main/java/org/apache/druid/jdbc/DruidPreparedStatement.java Dismissed
Comment thread jdbc-driver/src/main/java/org/apache/druid/jdbc/DruidPreparedStatement.java Dismissed

@FrankChen021 FrankChen021 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity Findings
P0 0
P1 0
P2 2
P3 0
Total 2

Reviewed 76 of 76 changed files.


This is an automated review by Codex GPT-5.6-Luna(max)

{
if (closed.compareAndSet(false, true)) {
try {
closeCurrentResultSet();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Closing during HTTP startup does not cancel the server query

Statement.close() can race with executeSql() before httpClient.runQuery() returns. With no result set yet, closeCurrentResultSet() only clears currentSqlQueryId; when the request returns, executeSql() closes the new result stream but never calls cancelQuery. The server-side query can remain running after the statement is closed. Preserve and cancel the in-flight query ID, and add a blocked-request test.

// Apply network timeout, if set, to the HTTP connection.
final int networkTimeoutMillisToUse = networkTimeoutMillis;
if (networkTimeoutMillisToUse > 0) {
requestBuilder.timeout(Duration.ofMillis(networkTimeoutMillisToUse));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Network timeout stops at response headers

The request uses BodyHandlers.ofInputStream(), so HttpClient.send() can return after headers arrive while QueryResultsIteratorImpl reads the body later. If the server sends headers and then stalls, ResultSet.next() or hasNext() can block indefinitely despite a finite Connection.setNetworkTimeout(). Enforce a body-read or idle deadline, or cancel the request on expiry, and add a stalled-body test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area - Batch Ingestion Area - Dependencies Area - Documentation Area - MSQ For multi stage queries - https://github.com/apache/druid/issues/12262 Area - Querying

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants