提交 42e2ac30 authored 作者: Thomas Mueller's avatar Thomas Mueller

If a CLOB or BLOB was copied into the same table using INSERT INTO X ... SELECT…

If a CLOB or BLOB was copied into the same table using INSERT INTO X ... SELECT ... FROM X, and then the original row was deleted, then the copied value was also deleted. This could also result in an ArrayIndexOutOfBoundsException on checkpoint or when closing the database.
上级 f45d1853
......@@ -141,13 +141,12 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo
public Value link(DataHandler h, int tabId) {
if (small == null) {
if (tabId != tableId) {
if (tableId != LobStorage.TABLE_TEMP) {
return lobStorage.copyLob(type, lobId, tabId, getPrecision());
}
if (tableId == LobStorage.TABLE_TEMP) {
lobStorage.setTable(lobId, tabId);
this.tableId = tabId;
}
return lobStorage.copyLob(type, lobId, tabId, getPrecision());
} else if (small.length > h.getMaxLengthInplaceLob()) {
LobStorage s = h.getLobStorage();
Value v;
......
......@@ -49,11 +49,13 @@ public class TestLob extends TestBase {
public static void main(String... a) throws Exception {
System.setProperty("h2.lobInDatabase", "true");
TestBase test = TestBase.createCaller().init();
test.config.big = true;
// test.config.big = true;
test.test();
}
public void test() throws Exception {
testCopyManyLobs();
testCopyLob();
testConcurrentCreate();
testLobInLargeResult();
testUniqueIndex();
......@@ -93,6 +95,39 @@ public class TestLob extends TestBase {
IOUtils.deleteRecursive(TEMP_DIR, true);
}
private void testCopyManyLobs() throws Exception {
deleteDb("lob");
Connection conn = getConnection("lob");
Statement stat = conn.createStatement();
stat.execute("create table test(id identity, data clob) as select 1, space(10000)");
stat.execute("insert into test(id, data) select null, data from test");
stat.execute("insert into test(id, data) select null, data from test");
stat.execute("insert into test(id, data) select null, data from test");
stat.execute("insert into test(id, data) select null, data from test");
stat.execute("delete from test where id < 10");
stat.execute("shutdown compact");
conn.close();
}
private void testCopyLob() throws Exception {
deleteDb("lob");
Connection conn;
Statement stat;
ResultSet rs;
conn = getConnection("lob");
stat = conn.createStatement();
stat.execute("create table test(id identity, data clob) as select 1, space(10000)");
stat.execute("insert into test(id, data) select 2, data from test");
stat.execute("delete from test where id = 1");
conn.close();
conn = getConnection("lob");
stat = conn.createStatement();
rs = stat.executeQuery("select * from test");
rs.next();
assertEquals(10000, rs.getString(2).length());
conn.close();
}
private void testConcurrentCreate() throws Exception {
deleteDb("lob");
final JdbcConnection conn1 = (JdbcConnection) getConnection("lob");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论