Running TestScalarTimeDateFunctions against Firebird 4 results in a reproducible case of "Current statement state (CURSOR_OPEN) does not allow call to prepare". The cause is similar to
, except in this case initialization of the fields in the result set constructor fails due to an unsupported datatype (eg TIMESTAMP WITH TIME ZONE). The failure to create the result set causes the result set to never be closed, and therefor the cursor state is never reset (and the serverside cursor never closed).
We need to carefully check if other types of exception can also lead to not properly closing result sets / cursors. We may also want to consider implementing a stopgap measure that prevents this problem from causing problems outside the driver (eg by forcibly resetting the statement if the state is CURSOR_OPEN). Maybe FBStatement.notifyStatementStarted should call something on FbStatement that forces a close if necessary.