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]

Reply via email to