提交 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 { ...@@ -249,11 +249,34 @@ public class LobStorage {
*/ */
public class LobInputStream extends InputStream { public class LobInputStream extends InputStream {
private byte[] buffer; /**
* The size of the blob.
*/
private long length; private long length;
private int pos;
/**
* The remaining bytes in the blob.
*/
private long remainingBytes; private long remainingBytes;
/**
* The temporary buffer.
*/
private byte[] buffer;
/**
* The position within the buffer.
*/
private int pos;
/**
* The blob id.
*/
private long lob; private long lob;
/**
* The blob sequence id.
*/
private int seq; private int seq;
public LobInputStream(long lob, long byteCount) { public LobInputStream(long lob, long byteCount) {
...@@ -281,7 +304,9 @@ public class LobStorage { ...@@ -281,7 +304,9 @@ public class LobStorage {
return super.skip(n); return super.skip(n);
} }
seq = (int) seqPos[0]; seq = (int) seqPos[0];
n = toPos - seqPos[1]; long p = seqPos[1];
remainingBytes = length - p;
n = toPos - p;
} catch (SQLException e) { } catch (SQLException e) {
throw DbException.convertToIOException(e); throw DbException.convertToIOException(e);
} }
......
...@@ -53,6 +53,7 @@ public class TestLob extends TestBase { ...@@ -53,6 +53,7 @@ public class TestLob extends TestBase {
} }
public void test() throws Exception { public void test() throws Exception {
testLobSkipPastEnd();
testCreateIndexOnLob(); testCreateIndexOnLob();
testBlobInputStreamSeek(true); testBlobInputStreamSeek(true);
testBlobInputStreamSeek(false); testBlobInputStreamSeek(false);
...@@ -98,6 +99,42 @@ public class TestLob extends TestBase { ...@@ -98,6 +99,42 @@ public class TestLob extends TestBase {
IOUtils.deleteRecursive(TEMP_DIR, true); 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 { private void testCreateIndexOnLob() throws Exception {
if (config.memory) { if (config.memory) {
return; return;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论