Creating a PreparedStatement with JDBC Arrow Flight driver causes a Dremio NPE

If I do the following:

  1. Set up a Dremio/MinIO/Nessie container on Docker as described on the Dremio Developer Advocacy site here.
  2. Create a simple table: CREATE TABLE nessie.dummy(id INT);
  3. Run the following Java code to create a PreparedStatement using the Arrow Flight JDBC driver:
final String URL = "jdbc:arrow-flight-sql://localhost:32010?useEncryption=false";
try (final Connection conn = DriverManager.getConnection(URL, "admin", "password");
    // Next line throws an exception.
    final PreparedStatement stmt = conn.prepareStatement("INSERT INTO nessie.dummy (id) VALUES (?)")
) {
    // Code to use the PreparedStatement would follow here but it never gets this far.
}

Then the call to prepareStatement gives rise to a SQLException, where the root cause is:

Caused by: org.apache.arrow.driver.jdbc.shaded.org.apache.arrow.flight.FlightRuntimeException: INTERNAL: NullPointerException
	at org.apache.arrow.driver.jdbc.shaded.org.apache.arrow.flight.CallStatus.toRuntimeException(CallStatus.java:121)
	at org.apache.arrow.driver.jdbc.shaded.org.apache.arrow.flight.grpc.StatusUtils.fromGrpcRuntimeException(StatusUtils.java:161)
	at org.apache.arrow.driver.jdbc.shaded.org.apache.arrow.flight.grpc.StatusUtils$1.next(StatusUtils.java:249)
	at org.apache.arrow.driver.jdbc.shaded.org.apache.arrow.flight.sql.FlightSqlClient$PreparedStatement.<init>(FlightSqlClient.java:1231)
	at org.apache.arrow.driver.jdbc.shaded.org.apache.arrow.flight.sql.FlightSqlClient.prepare(FlightSqlClient.java:901)
	at org.apache.arrow.driver.jdbc.shaded.org.apache.arrow.flight.sql.FlightSqlClient.prepare(FlightSqlClient.java:880)

In the Dremio container logs I see the following error appear:

2025-02-05 18:25:58 2025-02-05 18:25:58,216 [185c52c8-ce73-1c71-7f72-0a7315859c00/0:foreman-planning] ERROR c.d.s.commandpool.CommandWrapper - command 185c52c8-ce73-1c71-7f72-0a7315859c00/0:foreman-planning failed
2025-02-05 18:25:58 java.lang.NullPointerException: null
2025-02-05 18:25:58     at com.dremio.exec.planner.sql.handlers.commands.HandlerToPrepareArrowPlan.execute(HandlerToPrepareArrowPlan.java:45)
2025-02-05 18:25:58     at com.dremio.exec.planner.sql.handlers.commands.HandlerToPrepareArrowPlan.execute(HandlerToPrepareArrowPlan.java:27)
2025-02-05 18:25:58     at com.dremio.exec.work.foreman.AttemptManager.plan(AttemptManager.java:756)
2025-02-05 18:25:58     at com.dremio.exec.work.foreman.AttemptManager.lambda$run$4(AttemptManager.java:584)
2025-02-05 18:25:58     at com.dremio.service.commandpool.ReleasableBoundCommandPool.lambda$getWrappedCommand$1(ReleasableBoundCommandPool.java:156)
2025-02-05 18:25:58     at com.dremio.service.commandpool.CommandWrapper.run(CommandWrapper.java:73)
2025-02-05 18:25:58     at com.dremio.context.RequestContext.run(RequestContext.java:103)
2025-02-05 18:25:58     at com.dremio.common.concurrent.ContextMigratingExecutorService.lambda$decorate$4(ContextMigratingExecutorService.java:246)
2025-02-05 18:25:58     at com.dremio.common.concurrent.ContextMigratingExecutorService$ComparableRunnable.run(ContextMigratingExecutorService.java:222)

The NPE location appears to relate to the following Dremio source code:

I assume one of the chained calls is returning null which leads to an NPE when the next chained call attempts to dereference it.

Am I doing something wrong here?

I’m running on Java Zulu 23 on Windows 11 64bit, and I’m passing the following flag to the JVM:

--add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED

I’m using the following versions (which I believe are the latest versions at the time of writing):

flight-sql-jdbc-driver: 18.1.0
Dremio: 25.2.0-202410241428100111-a963b970
Docker Desktop: 4.37.1

Jon

@jon Support for Prepared statements with JDBC Flight driver is only in 26.0 (yet to be released), it is available in Dremio cloud already

@balaji Same error here

any workaround ?

@aramdas I guess the workaround is don’t use PreparedStatements until you’re on Dremio 26.0.