apatrida commented on issue #1439: URL: https://github.com/apache/arrow-java/issues/1439#issuecomment-6586551115
### Where it happens [`AvaticaParameterBinder`](https://github.com/apache/arrow-java/blob/b410fb26d01c7cefc4c6e3443a53562164001371/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java#L71-L108) creates the parameter `VectorSchemaRoot` and fills it one value at a time. It hands the root to `preparedStatement.setParameters()` only after every value succeeds. If a value throws, nothing owns the root and nothing closes it. Closing the root before rethrowing would fix it. We have no patch. ### Reproducer `localBinder()` in [`FlightFailureProbe.java`](https://github.com/brikk/brikk-sql/blob/7e0db9a/tools/datafusion-reference/FlightFailureProbe.java) reproduces it without a server. A regression test could bind a valid value then a failing one (NULL into a non-nullable field, or a wrong type), repeat it, and assert the allocator is empty afterwards. <details> <summary>Server-free reproducer (Java)</summary> Tested with the classes shaded inside `flight-sql-jdbc-driver-19.0.0.jar`; imports are shown unshaded. No server or connection is needed. ```java static void failedBindLeaks() { var allocator = new RootAllocator(); Schema schema = new Schema(List.of( new Field("text", FieldType.notNullable(new ArrowType.Utf8()), null), new Field("number", FieldType.notNullable(new ArrowType.Int(64, true)), null))); var stub = new ArrowFlightSqlClientHandler.PreparedStatement() { VectorSchemaRoot owned; public FlightInfo executeQuery() { throw new UnsupportedOperationException(); } public long executeUpdate() { throw new UnsupportedOperationException(); } public Meta.StatementType getType() { return Meta.StatementType.SELECT; } public Schema getDataSetSchema() { return new Schema(List.of()); } public Schema getParameterSchema() { return schema; } public void setParameters(VectorSchemaRoot root) { owned = root; } public void close() { if (owned != null) owned.close(); } }; try { new AvaticaParameterBinder(stub, allocator) .bind(Arrays.asList(TypedValue.ofLocal(ColumnMetaData.Rep.STRING, "text"), null)); } catch (UnsupportedOperationException e) { System.out.println("bind: " + e.getMessage()); // Can't set null on non-nullable parameter } stub.close(); System.out.println("still allocated: " + allocator.getAllocatedMemory()); // 16388 in our run try { allocator.close(); } catch (IllegalStateException e) { System.out.println("close: " + e.getMessage().lines().findFirst().orElse("")); // Memory was leaked } } ``` </details> ### Related #156 tracks broader parameter-binding improvements, including NULL handling. This leak is a separate issue. The non-nullable parameter schema in the example comes from spiceai/spiceai#15950. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
