Hi,
my group just went through a wild few days with a developer
complaining of a StringIndexOutOfBoundsException in H2. The month
before we had reimaged some linux test machines and started using
1.6.0_18 for first time, and immediately on those machines lots of
tests started failing due to this same error in H2. It was crazy
because the error seemed to happen randomly. Switching back to an
earlier version (1.6.0_13 ) made the problem disappear.
So, to make the story short, last thursday we found a number of tests
that would fail only on Linux 1.6.0_18/20, and they were failing in
the same place. We debugged it and found what was definitely an
optimizer bug, likely a run-time optimization bug.
The code would fail in h2.util.StringUtils.quoteRemarkSQL
Caused by: java.lang.StringIndexOutOfBoundsException: String index out
of range: 723
[junit] at java.lang.String.substring(String.java:1934)
[junit] at
org.h2.util.StringUtils.quoteRemarkSQL(StringUtils.java:804)
[junit] at org.h2.table.TableFilter.getPlanSQL(TableFilter.java:
536)
[junit] at org.h2.command.dml.Select.getPlanSQL(Select.java:883)
[junit] at org.h2.index.ViewIndex.<init>(ViewIndex.java:61)
[junit] at org.h2.table.TableView.getBestPlanItem(TableView.java:
143)
[junit] at org.h2.table.TableView.getScanIndex(TableView.java:
269)
[junit] at
org.h2.table.TableFilter.getBestPlanItem(TableFilter.java:125)
When debugging we would see in StringtUtils.quoteRemarkSQL(),
public static String quoteRemarkSQL(String sql) {
while (true) {
int idx = sql.indexOf("*/");
if (idx < 0) {
break;
}
sql = sql.substring(0, idx) + "++/" + sql.substring(idx +
2);
}
while (true) {
int idx = sql.indexOf("/*");
if (idx < 0) {
break;
}
-->> sql = sql.substring(0, idx) + "/++" +
sql.substring(idx + 2);
}
return sql;
}
really wrong values getting passed to both occurrences of
sql.substring on the line with the "-->>" that made no sense.
Sometimes it was the first one and sometimes the second.
We had to break in the throw of substring() and look up the stack
because if we tried to break in quoteRemarkSQL it wouldn't fail.
Anyway, it was 100% reproducible on Linux only with 1.2.0_20 (didn't
reproduce on windows). Rewriting the routine with a few changes made
the bug go away.
public static String quoteRemarkSQL(String sql) {
String s = sql;
int idx;
while ((idx = s.indexOf("*/")) >= 0) {
s = s.substring(0, idx) + "++/" + s.substring(idx + 2);
}
while ((idx = s.indexOf("/*")) >= 0) {
s = s.substring(0, idx) + "/++" + s.substring(idx + 2);
}
return s;
}
HOWEVER...... 1.6.0_21 was just released a day or two before, so we
downloaded this, and the problem no longer reproduced. I was told by
colleague this version has a lot of fixes and it's labeled as a major
version bump of the VM itself.
Anyway, I wanted to alert H2 users about these two jdks.
As an aside, that routine looks really inefficient. Wouldn't something
like
public static String quoteRemarkSql(String sql) {
return sql.replaceAll("[*]/","++/").replaceAll("/[*]","/++");
}
be much better?
or at least
idx = 0
while ( (idx = sql.indexOf(“*/”, idx)) >= 0) {
…
}
Thanks
Randy
--
You received this message because you are subscribed to the Google Groups "H2
Database" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/h2-database?hl=en.