google-code-export / h2database

Automatically exported from code.google.com/p/h2database
0 stars 1 forks source link

"Unexpected code path" exception #304

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?

Run the following script in the H2 console:
---------------------------------
drop table OBJECT1;
drop table OBJECT2;
create table OBJECT1 ( ID BIGINT NOT NULL, REFID BIGINT NOT NULL, COL1 BIGINT 
NOT NULL, PRIMARY KEY ( ID ) );
create INDEX OBJECT10 on OBJECT1 ( REFID );
create INDEX OBJECT11 on OBJECT1 ( COL1 );
create table OBJECT2 ( ID BIGINT NOT NULL, PRIMARY KEY ( ID ) );

@LOOP 10001 insert into Object2 values (?);
@LOOP 1050 insert into Object1 values (?,?,422);
@LOOP 9 insert into Object1 values (?+1050,100000000+?,422);
@LOOP 165 insert into Object1 values (?+1059,?,423);

explain analyze select o1.ID
  from OBJECT1 o1
  where o1.COL1 = 422
    and o1.refID not in (select o2.ID from Object2 o2 order by o2.ID);

drop table OBJECT1;
drop table OBJECT2;
---------------------------------

What is the expected output? What do you see instead?

Expected output is "9", actual output is:

What version of the product are you using? On what operating system, file 
system, and virtual machine?

1.3.153, MacOSX, HFS, no VM.

Do you know a workaround?

Don't do the query.

How important/urgent is the problem for you?

This was noticed while trying to diagnose issue 303. I do not think that this 
should ever happen… unexpected is unexpected! Unless it is the Spanish 
Inquisition of course…

Please provide any additional information below.

The stacktrace where the Unexepected code path exception is thrown:

DbException.throwInternalError() line: 239  
ResultDiskBuffer.contains(Value[]) line: 286    
LocalResult.containsDistinct(Value[]) line: 187 
ConditionInSelect.getValue(Session) line: 68    
ConditionNot.getValue(Session) line: 31 
ConditionAndOr.getValue(Session) line: 90   
ConditionAndOr(Expression).getBooleanValue(Session) line: 180   
Select.queryFlat(int, ResultTarget, long) line: 515 
Select.queryWithoutCache(int, ResultTarget) line: 614   
Select(Query).query(int, ResultTarget) line: 269    
Select(Query).query(int) line: 239  
Select(Query).query(int) line: 1    
Explain.query(int) line: 69 
CommandContainer.query(int) line: 78    
CommandContainer(Command).executeQuery(int, boolean) line: 181  
JdbcStatement.executeInternal(String) line: 173 
JdbcStatement.execute(String) line: 152 

Original issue reported on code.google.com by pwagl...@gmail.com on 19 Mar 2011 at 11:56

GoogleCodeExporter commented 9 years ago
If the first loop statement is changed to:

@LOOP 10000 insert into Object2 values (?);

Then the statement works. This is because, by default, the maxMemoryRows 
parameter is set to 10000, so, as soon as the table has more than 10000 rows it 
falls over to using the ResultDiskBuffer. ResultDiskBuffer on the other hand 
does not implement contains(), and so whenever LocalResult.containsDistinct() 
is called, and the backing table that we are checking contains more than 
maxMemoryRows items, then we _will_ get the RuntimeException.

Original comment by pwagl...@gmail.com on 20 Mar 2011 at 12:15

GoogleCodeExporter commented 9 years ago
Potential patch:

——————————————————————————��
�——
~/src/h2database-read-only/h2 $ svn diff src/main/org/h2/result/LocalResult.java
Index: src/main/org/h2/result/LocalResult.java
===================================================================
--- src/main/org/h2/result/LocalResult.java (revision 3518)
+++ src/main/org/h2/result/LocalResult.java (working copy)
@@ -184,7 +184,13 @@
             ValueArray array = ValueArray.get(values);
             return distinctRows.get(array) != null;
         }
-        return external.contains(values);
+       searchingTable: while (next()) {
+           for (int i = 0; i < values.length; i++)
+               if (!values[i].equals(currentRow[i]))
+                   continue searchingTable;
+           return true;
+       }
+       return false;
     }

     public void reset() {
——————————————————————————��
�——

This patch works for the specific case mentioned here. I have not run a full 
regression suite, since I am soliciting feedback on this patch first.

Original comment by pwagl...@gmail.com on 20 Mar 2011 at 1:03

GoogleCodeExporter commented 9 years ago
All of the old tests pass, I have not added any new test for this functionality.

This is mostly since, once issue 303 is fixed, then the only way that this can 
happen is through a union of some form, and I have not looked into the exact 
conditions for the union to fail.

Original comment by pwagl...@gmail.com on 20 Mar 2011 at 11:15

GoogleCodeExporter commented 9 years ago
Thanks a lot! I didn't have time yet to look at the problem or the patch 
unfortunately, and will do that as soon as possible.

Original comment by thomas.t...@gmail.com on 25 Mar 2011 at 7:29

GoogleCodeExporter commented 9 years ago
Committed in revision 3539.

Original comment by thomas.t...@gmail.com on 28 Mar 2011 at 7:13

GoogleCodeExporter commented 9 years ago
Fixed in version 1.3.154.

Original comment by thomas.t...@gmail.com on 4 Apr 2011 at 9:55

GoogleCodeExporter commented 9 years ago
Sorry, but i've still problems using H2 1.3.154 (2011-04-04).
My secondary table contains 36000 entries

--->
select * from player where id not in ( select distinct player_id from items );
see tracedump below

workaround -->
select * from player where id in ( select id from player 
minus select distinct player_id from items )
17 results

select count(distinct player_id) from  items
--> 570 including null

select count(distinct id) from player
--> 587

select count(*) from player
--> 587

org.h2.jdbc.JdbcSQLException: Allgemeiner Fehler: "java.lang.RuntimeException: 
Unexpected code path"
General error: "java.lang.RuntimeException: Unexpected code path"; SQL 
statement:
select * from player
where id not in (
select distinct player_id from items ) [50000-154]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:327)
    at org.h2.message.DbException.get(DbException.java:156)
    at org.h2.message.DbException.convert(DbException.java:279)
    at org.h2.command.Command.executeQuery(Command.java:185)
    at org.h2.server.TcpServerThread.process(TcpServerThread.java:278)
    at org.h2.server.TcpServerThread.run(TcpServerThread.java:137)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.RuntimeException: Unexpected code path
    at org.h2.message.DbException.throwInternalError(DbException.java:226)
    at org.h2.message.DbException.throwInternalError(DbException.java:239)
    at org.h2.result.LocalResult.containsDistinct(LocalResult.java:190)
    at org.h2.expression.ConditionInSelect.getValue(ConditionInSelect.java:68)
    at org.h2.expression.ConditionNot.getValue(ConditionNot.java:31)
    at org.h2.expression.Expression.getBooleanValue(Expression.java:180)
    at org.h2.command.dml.Select.queryFlat(Select.java:514)
    at org.h2.command.dml.Select.queryWithoutCache(Select.java:617)
    at org.h2.command.dml.Query.query(Query.java:290)
    at org.h2.command.dml.Query.query(Query.java:260)
    at org.h2.command.dml.Query.query(Query.java:37)
    at org.h2.command.CommandContainer.query(CommandContainer.java:78)
    at org.h2.command.Command.executeQuery(Command.java:181)
    ... 3 more

    at org.h2.engine.SessionRemote.done(SessionRemote.java:538)
    at org.h2.command.CommandRemote.executeQuery(CommandRemote.java:151)
    at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:173)
    at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:152)
    at org.h2.server.web.WebApp.getResult(WebApp.java:1308)
    at org.h2.server.web.WebApp.query(WebApp.java:994)
    at org.h2.server.web.WebApp$1.next(WebApp.java:957)
    at org.h2.server.web.WebApp$1.next(WebApp.java:960)
    at org.h2.server.web.WebThread.process(WebThread.java:166)
    at org.h2.server.web.WebThread.run(WebThread.java:93)
    at java.lang.Thread.run(Unknown Source) 

Original comment by ralf.ha...@gmail.com on 20 May 2011 at 11:59

GoogleCodeExporter commented 9 years ago
Thanks a lot! This will be fixed in the next release.

Original comment by thomas.t...@gmail.com on 27 May 2011 at 10:08

GoogleCodeExporter commented 9 years ago
This is fixed in version 1.3.155

Original comment by thomas.t...@gmail.com on 27 May 2011 at 10:54