提交 667028c0 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Detect small LOBs in better way

上级 1b1d4465
...@@ -78,15 +78,17 @@ public class ValueLob extends Value { ...@@ -78,15 +78,17 @@ public class ValueLob extends Value {
static int compare(Value v1, Value v2) { static int compare(Value v1, Value v2) {
int valueType = v1.getType(); int valueType = v1.getType();
assert valueType == v2.getType(); assert valueType == v2.getType();
long prec1 = v1.getPrecision(), prec2 = v2.getPrecision(); if (v1 instanceof ValueLobDb && v2 instanceof ValueLobDb) {
if (Math.max(prec1, prec2) <= BLOCK_COMPARISON_SIZE) { byte[] small1 = v1.getSmall(), small2 = v2.getSmall();
if (valueType == Value.BLOB) { if (small1 != null && small2 != null) {
return Bits.compareNotNullSigned(v1.getBytesNoCopy(), v2.getBytesNoCopy()); if (valueType == Value.BLOB) {
} else { return Bits.compareNotNullSigned(small1, small2);
return Integer.signum(v1.getString().compareTo(v2.getString())); } else {
return Integer.signum(v1.getString().compareTo(v2.getString()));
}
} }
} }
long minPrec = Math.min(prec1, prec2); long minPrec = Math.min(v1.getPrecision(), v2.getPrecision());
if (valueType == Value.BLOB) { if (valueType == Value.BLOB) {
try (InputStream is1 = v1.getInputStream(); try (InputStream is1 = v1.getInputStream();
InputStream is2 = v2.getInputStream()) { InputStream is2 = v2.getInputStream()) {
......
...@@ -5,9 +5,13 @@ ...@@ -5,9 +5,13 @@
*/ */
package org.h2.test.unit; package org.h2.test.unit;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.sql.Connection; import java.sql.Connection;
import java.sql.Date; import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
...@@ -20,7 +24,11 @@ import java.util.TimeZone; ...@@ -20,7 +24,11 @@ import java.util.TimeZone;
import java.util.UUID; import java.util.UUID;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.jdbc.JdbcConnection;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.store.DataHandler;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.test.TestDb; import org.h2.test.TestDb;
import org.h2.test.utils.AssertThrows; import org.h2.test.utils.AssertThrows;
...@@ -416,26 +424,29 @@ public class TestValue extends TestDb { ...@@ -416,26 +424,29 @@ public class TestValue extends TestDb {
} }
} }
private void testLobComparison() { private void testLobComparison() throws SQLException {
assertEquals(0, testLobComparisonImpl(Value.BLOB, 0, 0, 0, 0)); assertEquals(0, testLobComparisonImpl(null, Value.BLOB, 0, 0, 0, 0));
assertEquals(0, testLobComparisonImpl(Value.CLOB, 0, 0, 0, 0)); assertEquals(0, testLobComparisonImpl(null, Value.CLOB, 0, 0, 0, 0));
assertEquals(-1, testLobComparisonImpl(Value.BLOB, 1, 1, 200, 210)); assertEquals(-1, testLobComparisonImpl(null, Value.BLOB, 1, 1, 200, 210));
assertEquals(-1, testLobComparisonImpl(Value.CLOB, 1, 1, 'a', 'b')); assertEquals(-1, testLobComparisonImpl(null, Value.CLOB, 1, 1, 'a', 'b'));
assertEquals(1, testLobComparisonImpl(Value.BLOB, 512, 512, 210, 200)); assertEquals(1, testLobComparisonImpl(null, Value.BLOB, 512, 512, 210, 200));
assertEquals(1, testLobComparisonImpl(Value.CLOB, 512, 512, 'B', 'A')); assertEquals(1, testLobComparisonImpl(null, Value.CLOB, 512, 512, 'B', 'A'));
assertEquals(1, testLobComparisonImpl(Value.BLOB, 1_024, 1_024, 210, 200)); try (Connection c = DriverManager.getConnection("jdbc:h2:mem:testValue")) {
assertEquals(1, testLobComparisonImpl(Value.CLOB, 1_024, 1_024, 'B', 'A')); Database dh = ((Session) ((JdbcConnection) c).getSession()).getDatabase();
assertEquals(-1, testLobComparisonImpl(Value.BLOB, 10_000, 10_000, 200, 210)); assertEquals(1, testLobComparisonImpl(dh, Value.BLOB, 1_024, 1_024, 210, 200));
assertEquals(-1, testLobComparisonImpl(Value.CLOB, 10_000, 10_000, 'a', 'b')); assertEquals(1, testLobComparisonImpl(dh, Value.CLOB, 1_024, 1_024, 'B', 'A'));
assertEquals(0, testLobComparisonImpl(Value.BLOB, 10_000, 10_000, 0, 0)); assertEquals(-1, testLobComparisonImpl(dh, Value.BLOB, 10_000, 10_000, 200, 210));
assertEquals(0, testLobComparisonImpl(Value.CLOB, 10_000, 10_000, 0, 0)); assertEquals(-1, testLobComparisonImpl(dh, Value.CLOB, 10_000, 10_000, 'a', 'b'));
assertEquals(-1, testLobComparisonImpl(Value.BLOB, 1_000, 10_000, 0, 0)); assertEquals(0, testLobComparisonImpl(dh, Value.BLOB, 10_000, 10_000, 0, 0));
assertEquals(-1, testLobComparisonImpl(Value.CLOB, 1_000, 10_000, 0, 0)); assertEquals(0, testLobComparisonImpl(dh, Value.CLOB, 10_000, 10_000, 0, 0));
assertEquals(1, testLobComparisonImpl(Value.BLOB, 10_000, 1_000, 0, 0)); assertEquals(-1, testLobComparisonImpl(dh, Value.BLOB, 1_000, 10_000, 0, 0));
assertEquals(1, testLobComparisonImpl(Value.CLOB, 10_000, 1_000, 0, 0)); assertEquals(-1, testLobComparisonImpl(dh, Value.CLOB, 1_000, 10_000, 0, 0));
assertEquals(1, testLobComparisonImpl(dh, Value.BLOB, 10_000, 1_000, 0, 0));
assertEquals(1, testLobComparisonImpl(dh, Value.CLOB, 10_000, 1_000, 0, 0));
}
} }
private static int testLobComparisonImpl(int type, int size1, int size2, int suffix1, int suffix2) { private static int testLobComparisonImpl(DataHandler dh, int type, int size1, int size2, int suffix1, int suffix2) {
byte[] bytes1 = new byte[size1]; byte[] bytes1 = new byte[size1];
byte[] bytes2 = new byte[size2]; byte[] bytes2 = new byte[size2];
if (size1 > 0) { if (size1 > 0) {
...@@ -444,9 +455,21 @@ public class TestValue extends TestDb { ...@@ -444,9 +455,21 @@ public class TestValue extends TestDb {
if (size2 > 0) { if (size2 > 0) {
bytes2[size2 - 1] = (byte) suffix2; bytes2[size2 - 1] = (byte) suffix2;
} }
ValueLobDb lob1 = ValueLobDb.createSmallLob(type, bytes1); Value lob1 = createLob(dh, type, bytes1);
ValueLobDb lob2 = ValueLobDb.createSmallLob(type, bytes2); Value lob2 = createLob(dh, type, bytes2);
return lob1.compareTypeSafe(lob2, null); return lob1.compareTypeSafe(lob2, null);
} }
static Value createLob(DataHandler dh, int type, byte[] bytes) {
if (dh == null) {
return ValueLobDb.createSmallLob(type, bytes);
}
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
if (type == Value.BLOB) {
return dh.getLobStorage().createBlob(in, -1);
} else {
return dh.getLobStorage().createClob(new InputStreamReader(in, StandardCharsets.UTF_8), -1);
}
}
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论