FrankChen021 commented on issue #19918: URL: https://github.com/apache/druid/issues/19918#issuecomment-5229213855
I traced this through both Druid and Avatica. The report is valid, and the `PreparedStatement` behavior is primarily an existing Avatica limitation. For a prepared statement, Avatica calls `Meta.prepare(..., -1)` when `Connection.prepareStatement(sql)` creates the statement. Calling `PreparedStatement.setMaxRows(5)` afterward only changes client-side state. At execution time, Avatica calls `Meta.execute(..., statement.getFetchSize())`; it does not transmit `getMaxRows()` to the server. Therefore Druid never receives the value `5`. Avatica already tracks this as [CALCITE-719](https://issues.apache.org/jira/browse/CALCITE-719), “Support setMaxRows for PreparedStatement”. The Jira issue is still Open with no resolution, and Avatica's corresponding test remains ignored: [RemoteDriverTest.java](https://github.com/apache/calcite-avatica/blob/main/server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java#L531). The current execution path can be seen in [AvaticaConnection.java](https://github.com/apache/calcite-avatica/blob/main/core/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java#L550). There are also two relevant Druid-side defects: 1. Ordinary `Statement.setMaxRows()` is independently broken. `DruidMeta.prepareAndExecute` receives `maxRowCount`, but [DruidJdbcStatement](https://github.com/apache/druid/blob/master/sql/src/main/java/org/apache/druid/sql/avatica/DruidJdbcStatement.java#L67-L73) discards it and constructs the result set with `Long.MAX_VALUE`. 2. Before passing that limit through, [DruidJdbcResultSet.ResultFetcher](https://github.com/apache/druid/blob/master/sql/src/main/java/org/apache/druid/sql/avatica/DruidJdbcResultSet.java#L120-L135) must mark the frame complete when the row limit is reached. It currently uses only `yielder.isDone()`; if the underlying query has more rows than the limit, subsequent fetches can return empty frames with `done = false` indefinitely. A complete fix therefore has two parts: - Druid should pass the received limit through for ordinary statements and fix the result-fetcher termination condition. - Avatica must fix CALCITE-719—either enforce the limit client-side or transmit a distinct total-row limit during prepared-statement execution. Druid cannot infer the value from the current protocol because the execute field is being used for first-frame/fetch size. Until CALCITE-719 is addressed, adding an explicit `LIMIT 5` to the SQL is the reliable workaround for the prepared-statement example in this issue. -- 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] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
