提交 5f4b6f23 authored 作者: Thomas Mueller's avatar Thomas Mueller

When using InputStream.skip, trying to read past the end of a BLOB failed with…

When using InputStream.skip, trying to read past the end of a BLOB failed with the exception "IO Exception: Missing lob entry: ..." [90028-...].
上级 a5046b58
......@@ -249,11 +249,34 @@ public class LobStorage {
*/
public class LobInputStream extends InputStream {
private byte[] buffer;
/**
* The size of the blob.
*/
private long length;
private int pos;
/**
* The remaining bytes in the blob.
*/
private long remainingBytes;
/**
* The temporary buffer.
*/
private byte[] buffer;
/**
* The position within the buffer.
*/
private int pos;
/**
* The blob id.
*/
private long lob;
/**
* The blob sequence id.
*/
private int seq;
public LobInputStream(long lob, long byteCount) {
......@@ -281,7 +304,9 @@ public class LobStorage {
return super.skip(n);
}
seq = (int) seqPos[0];
n = toPos - seqPos[1];
long p = seqPos[1];
remainingBytes = length - p;
n = toPos - p;
} catch (SQLException e) {
throw DbException.convertToIOException(e);
}
......
......@@ -53,6 +53,7 @@ public class TestLob extends TestBase {
}
public void test() throws Exception {
testLobSkipPastEnd();
testCreateIndexOnLob();
testBlobInputStreamSeek(true);
testBlobInputStreamSeek(false);
......@@ -98,6 +99,42 @@ public class TestLob extends TestBase {
IOUtils.deleteRecursive(TEMP_DIR, true);
}
private void testLobSkipPastEnd() throws Exception {
if (config.memory) {
return;
}
deleteDb("lob");
Connection conn;
conn = getConnection("lob");
Statement stat = conn.createStatement();
stat.execute("create table test(id int, data blob)");
byte[] data = new byte[150000];
new Random(0).nextBytes(data);
PreparedStatement prep = conn.prepareStatement("insert into test values(1, ?)");
prep.setBytes(1, data);
prep.execute();
ResultSet rs = stat.executeQuery("select data from test");
rs.next();
for (int blockSize = 1; blockSize < 100000; blockSize *= 10) {
for (int i = 0; i < data.length; i += 1000) {
InputStream in = rs.getBinaryStream(1);
in.skip(i);
byte[] d2 = new byte[data.length];
int l = in.read(d2, i, blockSize);
if (i >= data.length) {
assertEquals(-1, l);
} else if (i + blockSize >= data.length) {
assertEquals(data.length - i, l);
}
for (int j = i; j < blockSize && j < d2.length; j++) {
assertEquals(data[j], d2[j]);
}
}
}
stat.execute("drop table test");
conn.close();
}
private void testCreateIndexOnLob() throws Exception {
if (config.memory) {
return;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论