-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Closed
Description
After we updated H2 from version 2.2.224 to 2.3.230 a StackOverflowException occurs when having multiple SELECT statements in one query, like this:
SELECT c1 FROM table1;
SELECT c2 FROM table1;
We are executing the query like this:
String sqlStatement = "SELECT c1 FROM table1;\r\nSELECT c2 FROM table1;"
java.sql.Connection con = // .. get DB connection
try (final Statement testStatement = con.createStatement()) {
testStatement.execute(sqlStatement);
} catch (SQLException e) {
// org.h2.jdbc.JdbcSQLNonTransientException: GeneralError;
} finally {
//... free DB connection
}
With debugging we found out that the cause is a StackOverflowException:

The reason for that is this change 925a188 (Issue: #4012).
Looking into the code the following happens here:
- a
Commandis build inorg.h2.command.Parser#prepareCommandList
with "SELECT c1 FROM table1" as "command" (CommandContainer) and
"commands" (ArrayList<Prepared>) containing aSelect"SELECT c2 FROM table1" - calling
CommandList.query(int) - calls
query(int)on theCommandContainer"command" - calls
org.h2.command.CommandList#executeRemaining() - this calls
org.h2.command.Command#executeQuery(int, boolean)for eachPreparedinArrayList<Prepared>"commands" - this calls
org.h2.command.Command#query(int)in line 196 - since we called
executeQuery(int, boolean)ofCommandListin step 5 the implementation ofCommandList(and notCommandContainer) is used here and we are starting at step 2 again --> endless loop.
I guess the executeQuery(int, boolean) in line 48 of org.h2.command.CommandList#executeRemaining should be called on the created CommandContainer of line 45, but I'm not sure about that.
for (Prepared prepared : commands) {
CommandContainer commandContainer = new CommandContainer(session, prepared.getSQL(), prepared);
prepared.prepare();
if (prepared.isQuery()) {
executeQuery(0, false); // --> instead use commandContainer.executeQuery(0, false);
} else {
commandContainer.executeUpdate(null);
}
}
Hope this helps!
Regards, jacquipre.
Metadata
Metadata
Assignees
Labels
No labels