提交 be8a9a43 authored 作者: Thomas Mueller's avatar Thomas Mueller

ArrayIndexOutOfBoundsException when adding rows

上级 95c8936d
...@@ -18,7 +18,9 @@ Change Log ...@@ -18,7 +18,9 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>Microsoft Windows Vista: when using the the installer, Vista wrote <ul><li>In some situations, an ArrayIndexOutOfBoundsException was thrown when adding rows.
This was caused by a bug in the b-tree code.
</li><li>Microsoft Windows Vista: when using the the installer, Vista wrote
"This program may not have installed correctly." This message should no longer appear "This program may not have installed correctly." This message should no longer appear
(in the h2.nsi file, the line 'RequestExecutionLevel highest' was added). (in the h2.nsi file, the line 'RequestExecutionLevel highest' was added).
</li><li>The Recover tool did not always work when the database contains </li><li>The Recover tool did not always work when the database contains
......
...@@ -100,7 +100,9 @@ public class BtreeNode extends BtreePage { ...@@ -100,7 +100,9 @@ public class BtreeNode extends BtreePage {
ObjectArray<SearchRow> empty = ObjectArray.newInstance(); ObjectArray<SearchRow> empty = ObjectArray.newInstance();
BtreeLeaf newLeaf = new BtreeLeaf(index, empty); BtreeLeaf newLeaf = new BtreeLeaf(index, empty);
index.addPage(session, newLeaf); index.addPage(session, newLeaf);
index.deletePage(session, this);
pageChildren.add(newLeaf.getPos()); pageChildren.add(newLeaf.getPos());
index.updatePage(session, this);
} }
BtreePage page = index.getPage(session, pageChildren.get(at)); BtreePage page = index.getPage(session, pageChildren.get(at));
int splitPoint = page.add(newRow, session); int splitPoint = page.add(newRow, session);
......
...@@ -301,39 +301,13 @@ public class IntArray { ...@@ -301,39 +301,13 @@ public class IntArray {
size = newSize; size = newSize;
} }
// ArrayList data = new ArrayList(); public String toString() {
// StatementBuilder buff = new StatementBuilder("{");
// public IntArray() { for (int i = 0; i < size; i++) {
// } buff.appendExceptFirst(", ");
// buff.append(data[i]);
// public IntArray(int[] data) { }
// for (int i = 0; i < data.length; i++) { return buff.append('}').toString();
// this.data.add(new Integer(data[i])); }
// }
// }
//
// public void add(int value) {
// this.data.add(new Integer(value));
// }
//
// public int get(int i) {
// return ((Integer) data.get(i)).intValue();
// }
//
// public void remove(int i) {
// data.remove(i);
// }
//
// public void add(int i, int value) {
// data.add(i, new Integer(value));
// }
//
// public void set(int i, int value) {
// data.set(i, new Integer(value));
// }
//
// public int size() {
// return data.size();
// }
} }
...@@ -353,4 +353,14 @@ public class ObjectArray<T> implements Iterable<T> { ...@@ -353,4 +353,14 @@ public class ObjectArray<T> implements Iterable<T> {
// } // }
// } // }
public String toString() {
StatementBuilder buff = new StatementBuilder("{");
for (int i = 0; i < size; i++) {
buff.appendExceptFirst(", ");
T t = get(i);
buff.append(t == null ? "" : t.toString());
}
return buff.append('}').toString();
}
} }
...@@ -46,6 +46,7 @@ public class TestCases extends TestBase { ...@@ -46,6 +46,7 @@ public class TestCases extends TestBase {
if (config.memory || config.logMode == 0) { if (config.memory || config.logMode == 0) {
return; return;
} }
testEmptyBtreeIndex();
testReservedKeywordReconnect(); testReservedKeywordReconnect();
testSpecialSQL(); testSpecialSQL();
testUpperCaseLowerCaseDatabase(); testUpperCaseLowerCaseDatabase();
...@@ -70,6 +71,23 @@ public class TestCases extends TestBase { ...@@ -70,6 +71,23 @@ public class TestCases extends TestBase {
deleteDb("cases"); deleteDb("cases");
} }
private void testEmptyBtreeIndex() throws SQLException {
deleteDb("cases");
Connection conn;
conn = getConnection("cases");
conn.createStatement().execute("CREATE TABLE test(id int PRIMARY KEY);");
conn.createStatement().execute("INSERT INTO test SELECT X FROM SYSTEM_RANGE(1, 77)");
conn.createStatement().execute("DELETE from test");
conn.close();
conn = getConnection("cases");
conn.createStatement().execute("INSERT INTO test (id) VALUES (1)");
conn.close();
conn = getConnection("cases");
conn.createStatement().execute("DELETE from test");
conn.createStatement().execute("drop table test");
conn.close();
}
private void testJoinWithView() throws SQLException { private void testJoinWithView() throws SQLException {
deleteDb("cases"); deleteDb("cases");
Connection conn = getConnection("cases"); Connection conn = getConnection("cases");
......
...@@ -35,6 +35,8 @@ public class TestIndex extends TestBase { ...@@ -35,6 +35,8 @@ public class TestIndex extends TestBase {
} }
public void test() throws SQLException { public void test() throws SQLException {
deleteDb("index");
testRandomized();
testDescIndex(); testDescIndex();
testHashIndex(); testHashIndex();
...@@ -81,6 +83,33 @@ public class TestIndex extends TestBase { ...@@ -81,6 +83,33 @@ public class TestIndex extends TestBase {
deleteDb("index"); deleteDb("index");
} }
private void testRandomized() throws SQLException {
boolean reopen = !config.memory;
Random random = new Random(1);
reconnect();
stat.execute("CREATE TABLE TEST(ID identity)");
int len = getSize(100, 1000);
for (int i = 0; i < len; i++) {
switch (random.nextInt(4)) {
case 0:
if (reopen) {
reconnect();
}
break;
case 1:
stat.execute("insert into test(id) values(null)");
break;
case 2:
stat.execute("delete from test");
break;
case 3:
stat.execute("insert into test select null from system_range(1, 100)");
break;
}
}
stat.execute("drop table test");
}
private void testHashIndex() throws SQLException { private void testHashIndex() throws SQLException {
reconnect(); reconnect();
stat.execute("create table testA(id int primary key, name varchar)"); stat.execute("create table testA(id int primary key, name varchar)");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论