Unverified 提交 db3622d0 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1690 from katzyn/value

Use own constants for value types in storage backends and Transfer
...@@ -21,6 +21,12 @@ Change Log ...@@ -21,6 +21,12 @@ Change Log
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul> <ul>
<li>Issue #1689: Use separate constants for data types in Data, ValueDataType, and Transfer
</li>
<li>PR #1687: MVMap minor cleanup
</li>
<li>PR #1686: Fix a regression with ENUM data type
</li>
<li>PR #1685: Fix CHAR in PostgreSQL mode and refactor some code <li>PR #1685: Fix CHAR in PostgreSQL mode and refactor some code
</li> </li>
<li>Issue #1681: IN () doesn't work with row values when data types are not exactly the same <li>Issue #1681: IN () doesn't work with row values when data types are not exactly the same
......
...@@ -60,22 +60,44 @@ import org.h2.value.ValueUuid; ...@@ -60,22 +60,44 @@ import org.h2.value.ValueUuid;
*/ */
public class ValueDataType implements DataType { public class ValueDataType implements DataType {
/** private static final byte NULL = 0;
* Storage type for ValueRow. private static final byte BYTE = 2;
*/ private static final byte SHORT = 3;
private static final int ROW = 27; private static final byte INT = 4;
private static final int INT_0_15 = 32; private static final byte LONG = 5;
private static final int LONG_0_7 = 48; private static final byte DECIMAL = 6;
private static final int DECIMAL_0_1 = 56; private static final byte DOUBLE = 7;
private static final int DECIMAL_SMALL_0 = 58; private static final byte FLOAT = 8;
private static final int DECIMAL_SMALL = 59; private static final byte TIME = 9;
private static final int DOUBLE_0_1 = 60; private static final byte DATE = 10;
private static final int FLOAT_0_1 = 62; private static final byte TIMESTAMP = 11;
private static final int BOOLEAN_FALSE = 64; private static final byte BYTES = 12;
private static final int BOOLEAN_TRUE = 65; private static final byte STRING = 13;
private static final int INT_NEG = 66; private static final byte STRING_IGNORECASE = 14;
private static final int LONG_NEG = 67; private static final byte BLOB = 15;
private static final int STRING_0_31 = 68; private static final byte CLOB = 16;
private static final byte ARRAY = 17;
private static final byte RESULT_SET = 18;
private static final byte JAVA_OBJECT = 19;
private static final byte UUID = 20;
private static final byte STRING_FIXED = 21;
private static final byte GEOMETRY = 22;
private static final byte TIMESTAMP_TZ = 24;
private static final byte ENUM = 25;
private static final byte INTERVAL = 26;
private static final byte ROW = 27;
private static final byte INT_0_15 = 32;
private static final byte LONG_0_7 = 48;
private static final byte DECIMAL_0_1 = 56;
private static final byte DECIMAL_SMALL_0 = 58;
private static final byte DECIMAL_SMALL = 59;
private static final byte DOUBLE_0_1 = 60;
private static final byte FLOAT_0_1 = 62;
private static final byte BOOLEAN_FALSE = 64;
private static final byte BOOLEAN_TRUE = 65;
private static final byte INT_NEG = 66;
private static final byte LONG_NEG = 67;
private static final byte STRING_0_31 = 68;
private static final int BYTES_0_31 = 100; private static final int BYTES_0_31 = 100;
private static final int SPATIAL_KEY_2D = 132; private static final int SPATIAL_KEY_2D = 132;
private static final int CUSTOM_DATA_TYPE = 133; private static final int CUSTOM_DATA_TYPE = 133;
...@@ -210,41 +232,41 @@ public class ValueDataType implements DataType { ...@@ -210,41 +232,41 @@ public class ValueDataType implements DataType {
int type = v.getValueType(); int type = v.getValueType();
switch (type) { switch (type) {
case Value.BOOLEAN: case Value.BOOLEAN:
buff.put((byte) (v.getBoolean() ? BOOLEAN_TRUE : BOOLEAN_FALSE)); buff.put(v.getBoolean() ? BOOLEAN_TRUE : BOOLEAN_FALSE);
break; break;
case Value.BYTE: case Value.BYTE:
buff.put((byte) type).put(v.getByte()); buff.put(BYTE).put(v.getByte());
break; break;
case Value.SHORT: case Value.SHORT:
buff.put((byte) type).putShort(v.getShort()); buff.put(SHORT).putShort(v.getShort());
break; break;
case Value.ENUM: case Value.ENUM:
case Value.INT: { case Value.INT: {
int x = v.getInt(); int x = v.getInt();
if (x < 0) { if (x < 0) {
buff.put((byte) INT_NEG).putVarInt(-x); buff.put(INT_NEG).putVarInt(-x);
} else if (x < 16) { } else if (x < 16) {
buff.put((byte) (INT_0_15 + x)); buff.put((byte) (INT_0_15 + x));
} else { } else {
buff.put((byte) type).putVarInt(x); buff.put(type == Value.INT ? INT : ENUM).putVarInt(x);
} }
break; break;
} }
case Value.LONG: { case Value.LONG: {
long x = v.getLong(); long x = v.getLong();
if (x < 0) { if (x < 0) {
buff.put((byte) LONG_NEG).putVarLong(-x); buff.put(LONG_NEG).putVarLong(-x);
} else if (x < 8) { } else if (x < 8) {
buff.put((byte) (LONG_0_7 + x)); buff.put((byte) (LONG_0_7 + x));
} else { } else {
buff.put((byte) type).putVarLong(x); buff.put(LONG).putVarLong(x);
} }
break; break;
} }
case Value.DECIMAL: { case Value.DECIMAL: {
BigDecimal x = v.getBigDecimal(); BigDecimal x = v.getBigDecimal();
if (BigDecimal.ZERO.equals(x)) { if (BigDecimal.ZERO.equals(x)) {
buff.put((byte) DECIMAL_0_1); buff.put(DECIMAL_0_1);
} else if (BigDecimal.ONE.equals(x)) { } else if (BigDecimal.ONE.equals(x)) {
buff.put((byte) (DECIMAL_0_1 + 1)); buff.put((byte) (DECIMAL_0_1 + 1));
} else { } else {
...@@ -253,16 +275,16 @@ public class ValueDataType implements DataType { ...@@ -253,16 +275,16 @@ public class ValueDataType implements DataType {
int bits = b.bitLength(); int bits = b.bitLength();
if (bits <= 63) { if (bits <= 63) {
if (scale == 0) { if (scale == 0) {
buff.put((byte) DECIMAL_SMALL_0). buff.put(DECIMAL_SMALL_0).
putVarLong(b.longValue()); putVarLong(b.longValue());
} else { } else {
buff.put((byte) DECIMAL_SMALL). buff.put(DECIMAL_SMALL).
putVarInt(scale). putVarInt(scale).
putVarLong(b.longValue()); putVarLong(b.longValue());
} }
} else { } else {
byte[] bytes = b.toByteArray(); byte[] bytes = b.toByteArray();
buff.put((byte) type). buff.put(DECIMAL).
putVarInt(scale). putVarInt(scale).
putVarInt(bytes.length). putVarInt(bytes.length).
put(bytes); put(bytes);
...@@ -275,14 +297,14 @@ public class ValueDataType implements DataType { ...@@ -275,14 +297,14 @@ public class ValueDataType implements DataType {
long nanos = t.getNanos(); long nanos = t.getNanos();
long millis = nanos / 1000000; long millis = nanos / 1000000;
nanos -= millis * 1000000; nanos -= millis * 1000000;
buff.put((byte) type). buff.put(TIME).
putVarLong(millis). putVarLong(millis).
putVarLong(nanos); putVarLong(nanos);
break; break;
} }
case Value.DATE: { case Value.DATE: {
long x = ((ValueDate) v).getDateValue(); long x = ((ValueDate) v).getDateValue();
buff.put((byte) type).putVarLong(x); buff.put(DATE).putVarLong(x);
break; break;
} }
case Value.TIMESTAMP: { case Value.TIMESTAMP: {
...@@ -291,7 +313,7 @@ public class ValueDataType implements DataType { ...@@ -291,7 +313,7 @@ public class ValueDataType implements DataType {
long nanos = ts.getTimeNanos(); long nanos = ts.getTimeNanos();
long millis = nanos / 1000000; long millis = nanos / 1000000;
nanos -= millis * 1000000; nanos -= millis * 1000000;
buff.put((byte) type). buff.put(TIMESTAMP).
putVarLong(dateValue). putVarLong(dateValue).
putVarLong(millis). putVarLong(millis).
putVarLong(nanos); putVarLong(nanos);
...@@ -303,7 +325,7 @@ public class ValueDataType implements DataType { ...@@ -303,7 +325,7 @@ public class ValueDataType implements DataType {
long nanos = ts.getTimeNanos(); long nanos = ts.getTimeNanos();
long millis = nanos / 1000000; long millis = nanos / 1000000;
nanos -= millis * 1000000; nanos -= millis * 1000000;
buff.put((byte) type). buff.put(TIMESTAMP_TZ).
putVarLong(dateValue). putVarLong(dateValue).
putVarLong(millis). putVarLong(millis).
putVarLong(nanos). putVarLong(nanos).
...@@ -312,7 +334,7 @@ public class ValueDataType implements DataType { ...@@ -312,7 +334,7 @@ public class ValueDataType implements DataType {
} }
case Value.JAVA_OBJECT: { case Value.JAVA_OBJECT: {
byte[] b = v.getBytesNoCopy(); byte[] b = v.getBytesNoCopy();
buff.put((byte) type). buff.put(JAVA_OBJECT).
putVarInt(b.length). putVarInt(b.length).
put(b); put(b);
break; break;
...@@ -324,7 +346,7 @@ public class ValueDataType implements DataType { ...@@ -324,7 +346,7 @@ public class ValueDataType implements DataType {
buff.put((byte) (BYTES_0_31 + len)). buff.put((byte) (BYTES_0_31 + len)).
put(b); put(b);
} else { } else {
buff.put((byte) type). buff.put(BYTES).
putVarInt(b.length). putVarInt(b.length).
put(b); put(b);
} }
...@@ -332,7 +354,7 @@ public class ValueDataType implements DataType { ...@@ -332,7 +354,7 @@ public class ValueDataType implements DataType {
} }
case Value.UUID: { case Value.UUID: {
ValueUuid uuid = (ValueUuid) v; ValueUuid uuid = (ValueUuid) v;
buff.put((byte) type). buff.put(UUID).
putLong(uuid.getHigh()). putLong(uuid.getHigh()).
putLong(uuid.getLow()); putLong(uuid.getLow());
break; break;
...@@ -344,14 +366,17 @@ public class ValueDataType implements DataType { ...@@ -344,14 +366,17 @@ public class ValueDataType implements DataType {
buff.put((byte) (STRING_0_31 + len)). buff.put((byte) (STRING_0_31 + len)).
putStringData(s, len); putStringData(s, len);
} else { } else {
buff.put((byte) type); buff.put(STRING);
writeString(buff, s); writeString(buff, s);
} }
break; break;
} }
case Value.STRING_IGNORECASE: case Value.STRING_IGNORECASE:
buff.put(STRING_IGNORECASE);
writeString(buff, v.getString());
break;
case Value.STRING_FIXED: case Value.STRING_FIXED:
buff.put((byte) type); buff.put(STRING_FIXED);
writeString(buff, v.getString()); writeString(buff, v.getString());
break; break;
case Value.DOUBLE: { case Value.DOUBLE: {
...@@ -361,9 +386,9 @@ public class ValueDataType implements DataType { ...@@ -361,9 +386,9 @@ public class ValueDataType implements DataType {
} else { } else {
long d = Double.doubleToLongBits(x); long d = Double.doubleToLongBits(x);
if (d == ValueDouble.ZERO_BITS) { if (d == ValueDouble.ZERO_BITS) {
buff.put((byte) DOUBLE_0_1); buff.put(DOUBLE_0_1);
} else { } else {
buff.put((byte) type). buff.put(DOUBLE).
putVarLong(Long.reverse(d)); putVarLong(Long.reverse(d));
} }
} }
...@@ -376,9 +401,9 @@ public class ValueDataType implements DataType { ...@@ -376,9 +401,9 @@ public class ValueDataType implements DataType {
} else { } else {
int f = Float.floatToIntBits(x); int f = Float.floatToIntBits(x);
if (f == ValueFloat.ZERO_BITS) { if (f == ValueFloat.ZERO_BITS) {
buff.put((byte) FLOAT_0_1); buff.put(FLOAT_0_1);
} else { } else {
buff.put((byte) type). buff.put(FLOAT).
putVarInt(Integer.reverse(f)); putVarInt(Integer.reverse(f));
} }
} }
...@@ -386,7 +411,7 @@ public class ValueDataType implements DataType { ...@@ -386,7 +411,7 @@ public class ValueDataType implements DataType {
} }
case Value.BLOB: case Value.BLOB:
case Value.CLOB: { case Value.CLOB: {
buff.put((byte) type); buff.put(type == Value.BLOB ? BLOB : CLOB);
ValueLobDb lob = (ValueLobDb) v; ValueLobDb lob = (ValueLobDb) v;
byte[] small = lob.getSmall(); byte[] small = lob.getSmall();
if (small == null) { if (small == null) {
...@@ -403,7 +428,7 @@ public class ValueDataType implements DataType { ...@@ -403,7 +428,7 @@ public class ValueDataType implements DataType {
case Value.ARRAY: case Value.ARRAY:
case Value.ROW: { case Value.ROW: {
Value[] list = ((ValueCollectionBase) v).getList(); Value[] list = ((ValueCollectionBase) v).getList();
buff.put((byte) (type == Value.ARRAY ? Value.ARRAY : /* Special storage type for ValueRow */ ROW)) buff.put(type == Value.ARRAY ? ARRAY : ROW)
.putVarInt(list.length); .putVarInt(list.length);
for (Value x : list) { for (Value x : list) {
writeValue(buff, x); writeValue(buff, x);
...@@ -411,7 +436,7 @@ public class ValueDataType implements DataType { ...@@ -411,7 +436,7 @@ public class ValueDataType implements DataType {
break; break;
} }
case Value.RESULT_SET: { case Value.RESULT_SET: {
buff.put((byte) type); buff.put(RESULT_SET);
ResultInterface result = ((ValueResultSet) v).getResult(); ResultInterface result = ((ValueResultSet) v).getResult();
int columnCount = result.getVisibleColumnCount(); int columnCount = result.getVisibleColumnCount();
buff.putVarInt(columnCount); buff.putVarInt(columnCount);
...@@ -436,7 +461,7 @@ public class ValueDataType implements DataType { ...@@ -436,7 +461,7 @@ public class ValueDataType implements DataType {
case Value.GEOMETRY: { case Value.GEOMETRY: {
byte[] b = v.getBytes(); byte[] b = v.getBytes();
int len = b.length; int len = b.length;
buff.put((byte) type). buff.put(GEOMETRY).
putVarInt(len). putVarInt(len).
put(b); put(b);
break; break;
...@@ -451,7 +476,7 @@ public class ValueDataType implements DataType { ...@@ -451,7 +476,7 @@ public class ValueDataType implements DataType {
if (interval.isNegative()) { if (interval.isNegative()) {
ordinal = ~ordinal; ordinal = ~ordinal;
} }
buff.put((byte) Value.INTERVAL_YEAR). buff.put(INTERVAL).
put((byte) ordinal). put((byte) ordinal).
putVarLong(interval.getLeading()); putVarLong(interval.getLeading());
break; break;
...@@ -469,7 +494,7 @@ public class ValueDataType implements DataType { ...@@ -469,7 +494,7 @@ public class ValueDataType implements DataType {
if (interval.isNegative()) { if (interval.isNegative()) {
ordinal = ~ordinal; ordinal = ~ordinal;
} }
buff.put((byte) Value.INTERVAL_YEAR). buff.put(INTERVAL).
put((byte) (ordinal)). put((byte) (ordinal)).
putVarLong(interval.getLeading()). putVarLong(interval.getLeading()).
putVarLong(interval.getRemaining()); putVarLong(interval.getRemaining());
...@@ -501,7 +526,7 @@ public class ValueDataType implements DataType { ...@@ -501,7 +526,7 @@ public class ValueDataType implements DataType {
private Object readValue(ByteBuffer buff) { private Object readValue(ByteBuffer buff) {
int type = buff.get() & 255; int type = buff.get() & 255;
switch (type) { switch (type) {
case Value.NULL: case NULL:
return ValueNull.INSTANCE; return ValueNull.INSTANCE;
case BOOLEAN_TRUE: case BOOLEAN_TRUE:
return ValueBoolean.TRUE; return ValueBoolean.TRUE;
...@@ -509,16 +534,16 @@ public class ValueDataType implements DataType { ...@@ -509,16 +534,16 @@ public class ValueDataType implements DataType {
return ValueBoolean.FALSE; return ValueBoolean.FALSE;
case INT_NEG: case INT_NEG:
return ValueInt.get(-readVarInt(buff)); return ValueInt.get(-readVarInt(buff));
case Value.ENUM: case ENUM:
case Value.INT: case INT:
return ValueInt.get(readVarInt(buff)); return ValueInt.get(readVarInt(buff));
case LONG_NEG: case LONG_NEG:
return ValueLong.get(-readVarLong(buff)); return ValueLong.get(-readVarLong(buff));
case Value.LONG: case LONG:
return ValueLong.get(readVarLong(buff)); return ValueLong.get(readVarLong(buff));
case Value.BYTE: case BYTE:
return ValueByte.get(buff.get()); return ValueByte.get(buff.get());
case Value.SHORT: case SHORT:
return ValueShort.get(buff.getShort()); return ValueShort.get(buff.getShort());
case DECIMAL_0_1: case DECIMAL_0_1:
return ValueDecimal.ZERO; return ValueDecimal.ZERO;
...@@ -532,7 +557,7 @@ public class ValueDataType implements DataType { ...@@ -532,7 +557,7 @@ public class ValueDataType implements DataType {
return ValueDecimal.get(BigDecimal.valueOf( return ValueDecimal.get(BigDecimal.valueOf(
readVarLong(buff), scale)); readVarLong(buff), scale));
} }
case Value.DECIMAL: { case DECIMAL: {
int scale = readVarInt(buff); int scale = readVarInt(buff);
int len = readVarInt(buff); int len = readVarInt(buff);
byte[] buff2 = Utils.newBytes(len); byte[] buff2 = Utils.newBytes(len);
...@@ -540,45 +565,45 @@ public class ValueDataType implements DataType { ...@@ -540,45 +565,45 @@ public class ValueDataType implements DataType {
BigInteger b = new BigInteger(buff2); BigInteger b = new BigInteger(buff2);
return ValueDecimal.get(new BigDecimal(b, scale)); return ValueDecimal.get(new BigDecimal(b, scale));
} }
case Value.DATE: { case DATE: {
return ValueDate.fromDateValue(readVarLong(buff)); return ValueDate.fromDateValue(readVarLong(buff));
} }
case Value.TIME: { case TIME: {
long nanos = readVarLong(buff) * 1000000 + readVarLong(buff); long nanos = readVarLong(buff) * 1000000 + readVarLong(buff);
return ValueTime.fromNanos(nanos); return ValueTime.fromNanos(nanos);
} }
case Value.TIMESTAMP: { case TIMESTAMP: {
long dateValue = readVarLong(buff); long dateValue = readVarLong(buff);
long nanos = readVarLong(buff) * 1000000 + readVarLong(buff); long nanos = readVarLong(buff) * 1000000 + readVarLong(buff);
return ValueTimestamp.fromDateValueAndNanos(dateValue, nanos); return ValueTimestamp.fromDateValueAndNanos(dateValue, nanos);
} }
case Value.TIMESTAMP_TZ: { case TIMESTAMP_TZ: {
long dateValue = readVarLong(buff); long dateValue = readVarLong(buff);
long nanos = readVarLong(buff) * 1000000 + readVarLong(buff); long nanos = readVarLong(buff) * 1000000 + readVarLong(buff);
short tz = (short) readVarInt(buff); short tz = (short) readVarInt(buff);
return ValueTimestampTimeZone.fromDateValueAndNanos(dateValue, nanos, tz); return ValueTimestampTimeZone.fromDateValueAndNanos(dateValue, nanos, tz);
} }
case Value.BYTES: { case BYTES: {
int len = readVarInt(buff); int len = readVarInt(buff);
byte[] b = Utils.newBytes(len); byte[] b = Utils.newBytes(len);
buff.get(b, 0, len); buff.get(b, 0, len);
return ValueBytes.getNoCopy(b); return ValueBytes.getNoCopy(b);
} }
case Value.JAVA_OBJECT: { case JAVA_OBJECT: {
int len = readVarInt(buff); int len = readVarInt(buff);
byte[] b = Utils.newBytes(len); byte[] b = Utils.newBytes(len);
buff.get(b, 0, len); buff.get(b, 0, len);
return ValueJavaObject.getNoCopy(null, b, handler); return ValueJavaObject.getNoCopy(null, b, handler);
} }
case Value.UUID: case UUID:
return ValueUuid.get(buff.getLong(), buff.getLong()); return ValueUuid.get(buff.getLong(), buff.getLong());
case Value.STRING: case STRING:
return ValueString.get(readString(buff)); return ValueString.get(readString(buff));
case Value.STRING_IGNORECASE: case STRING_IGNORECASE:
return ValueStringIgnoreCase.get(readString(buff)); return ValueStringIgnoreCase.get(readString(buff));
case Value.STRING_FIXED: case STRING_FIXED:
return ValueStringFixed.get(readString(buff)); return ValueStringFixed.get(readString(buff));
case Value.INTERVAL_YEAR: { case INTERVAL: {
int ordinal = buff.get(); int ordinal = buff.get();
boolean negative = ordinal < 0; boolean negative = ordinal < 0;
if (negative) { if (negative) {
...@@ -595,41 +620,38 @@ public class ValueDataType implements DataType { ...@@ -595,41 +620,38 @@ public class ValueDataType implements DataType {
return ValueDouble.ZERO; return ValueDouble.ZERO;
case DOUBLE_0_1 + 1: case DOUBLE_0_1 + 1:
return ValueDouble.ONE; return ValueDouble.ONE;
case Value.DOUBLE: case DOUBLE:
return ValueDouble.get(Double.longBitsToDouble( return ValueDouble.get(Double.longBitsToDouble(Long.reverse(readVarLong(buff))));
Long.reverse(readVarLong(buff)))); case FLOAT:
case Value.FLOAT: return ValueFloat.get(Float.intBitsToFloat(Integer.reverse(readVarInt(buff))));
return ValueFloat.get(Float.intBitsToFloat( case BLOB:
Integer.reverse(readVarInt(buff)))); case CLOB: {
case Value.BLOB:
case Value.CLOB: {
int smallLen = readVarInt(buff); int smallLen = readVarInt(buff);
if (smallLen >= 0) { if (smallLen >= 0) {
byte[] small = Utils.newBytes(smallLen); byte[] small = Utils.newBytes(smallLen);
buff.get(small, 0, smallLen); buff.get(small, 0, smallLen);
return ValueLobDb.createSmallLob(type, small); return ValueLobDb.createSmallLob(type == BLOB ? Value.BLOB : Value.CLOB, small);
} else if (smallLen == -3) { } else if (smallLen == -3) {
int tableId = readVarInt(buff); int tableId = readVarInt(buff);
long lobId = readVarLong(buff); long lobId = readVarLong(buff);
long precision = readVarLong(buff); long precision = readVarLong(buff);
return ValueLobDb.create(type, return ValueLobDb.create(type == BLOB ? Value.BLOB : Value.CLOB,
handler, tableId, lobId, null, precision); handler, tableId, lobId, null, precision);
} else { } else {
throw DbException.get(ErrorCode.FILE_CORRUPTED_1, throw DbException.get(ErrorCode.FILE_CORRUPTED_1,
"lob type: " + smallLen); "lob type: " + smallLen);
} }
} }
case Value.ARRAY: case ARRAY:
case ROW: // Special storage type for ValueRow case ROW: {
{
int len = readVarInt(buff); int len = readVarInt(buff);
Value[] list = new Value[len]; Value[] list = new Value[len];
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
list[i] = (Value) readValue(buff); list[i] = (Value) readValue(buff);
} }
return type == Value.ARRAY ? ValueArray.get(list) : ValueRow.get(list); return type == ARRAY ? ValueArray.get(list) : ValueRow.get(list);
} }
case Value.RESULT_SET: { case RESULT_SET: {
SimpleResult rs = new SimpleResult(); SimpleResult rs = new SimpleResult();
int columns = readVarInt(buff); int columns = readVarInt(buff);
for (int i = 0; i < columns; i++) { for (int i = 0; i < columns; i++) {
...@@ -645,7 +667,7 @@ public class ValueDataType implements DataType { ...@@ -645,7 +667,7 @@ public class ValueDataType implements DataType {
} }
return ValueResultSet.get(rs); return ValueResultSet.get(rs);
} }
case Value.GEOMETRY: { case GEOMETRY: {
int len = readVarInt(buff); int len = readVarInt(buff);
byte[] b = Utils.newBytes(len); byte[] b = Utils.newBytes(len);
buff.get(b, 0, len); buff.get(b, 0, len);
......
...@@ -76,27 +76,49 @@ public class Data { ...@@ -76,27 +76,49 @@ public class Data {
*/ */
public static final int LENGTH_LONG = 8; public static final int LENGTH_LONG = 8;
/** private static final byte NULL = 0;
* Storage type for ValueRow. private static final byte BYTE = 2;
*/ private static final byte SHORT = 3;
private static final int ROW = 27; private static final byte INT = 4;
private static final int INT_0_15 = 32; private static final byte LONG = 5;
private static final int LONG_0_7 = 48; private static final byte DECIMAL = 6;
private static final int DECIMAL_0_1 = 56; private static final byte DOUBLE = 7;
private static final int DECIMAL_SMALL_0 = 58; private static final byte FLOAT = 8;
private static final int DECIMAL_SMALL = 59; private static final byte TIME = 9;
private static final int DOUBLE_0_1 = 60; private static final byte DATE = 10;
private static final int FLOAT_0_1 = 62; private static final byte TIMESTAMP = 11;
private static final int BOOLEAN_FALSE = 64; private static final byte BYTES = 12;
private static final int BOOLEAN_TRUE = 65; private static final byte STRING = 13;
private static final int INT_NEG = 66; private static final byte STRING_IGNORECASE = 14;
private static final int LONG_NEG = 67; private static final byte BLOB = 15;
private static final int STRING_0_31 = 68; private static final byte CLOB = 16;
private static final byte ARRAY = 17;
private static final byte RESULT_SET = 18;
private static final byte JAVA_OBJECT = 19;
private static final byte UUID = 20;
private static final byte STRING_FIXED = 21;
private static final byte GEOMETRY = 22;
private static final byte TIMESTAMP_TZ = 24;
private static final byte ENUM = 25;
private static final byte INTERVAL = 26;
private static final byte ROW = 27;
private static final byte INT_0_15 = 32;
private static final byte LONG_0_7 = 48;
private static final byte DECIMAL_0_1 = 56;
private static final byte DECIMAL_SMALL_0 = 58;
private static final byte DECIMAL_SMALL = 59;
private static final byte DOUBLE_0_1 = 60;
private static final byte FLOAT_0_1 = 62;
private static final byte BOOLEAN_FALSE = 64;
private static final byte BOOLEAN_TRUE = 65;
private static final byte INT_NEG = 66;
private static final byte LONG_NEG = 67;
private static final byte STRING_0_31 = 68;
private static final int BYTES_0_31 = 100; private static final int BYTES_0_31 = 100;
private static final int LOCAL_TIME = 132; private static final int LOCAL_TIME = 132;
private static final int LOCAL_DATE = 133; private static final int LOCAL_DATE = 133;
private static final int LOCAL_TIMESTAMP = 134; private static final int LOCAL_TIMESTAMP = 134;
private static final byte CUSTOM_DATA_TYPE = (byte)135; private static final int CUSTOM_DATA_TYPE = 135;
private static final long MILLIS_PER_MINUTE = 1000 * 60; private static final long MILLIS_PER_MINUTE = 1000 * 60;
...@@ -421,32 +443,32 @@ public class Data { ...@@ -421,32 +443,32 @@ public class Data {
public void writeValue(Value v) { public void writeValue(Value v) {
int start = pos; int start = pos;
if (v == ValueNull.INSTANCE) { if (v == ValueNull.INSTANCE) {
data[pos++] = 0; data[pos++] = NULL;
return; return;
} }
int type = v.getValueType(); int type = v.getValueType();
switch (type) { switch (type) {
case Value.BOOLEAN: case Value.BOOLEAN:
writeByte((byte) (v.getBoolean() ? BOOLEAN_TRUE : BOOLEAN_FALSE)); writeByte(v.getBoolean() ? BOOLEAN_TRUE : BOOLEAN_FALSE);
break; break;
case Value.BYTE: case Value.BYTE:
writeByte((byte) type); writeByte(BYTE);
writeByte(v.getByte()); writeByte(v.getByte());
break; break;
case Value.SHORT: case Value.SHORT:
writeByte((byte) type); writeByte(SHORT);
writeShortInt(v.getShort()); writeShortInt(v.getShort());
break; break;
case Value.ENUM: case Value.ENUM:
case Value.INT: { case Value.INT: {
int x = v.getInt(); int x = v.getInt();
if (x < 0) { if (x < 0) {
writeByte((byte) INT_NEG); writeByte(INT_NEG);
writeVarInt(-x); writeVarInt(-x);
} else if (x < 16) { } else if (x < 16) {
writeByte((byte) (INT_0_15 + x)); writeByte((byte) (INT_0_15 + x));
} else { } else {
writeByte((byte) type); writeByte(type == Value.INT ? INT : ENUM);
writeVarInt(x); writeVarInt(x);
} }
break; break;
...@@ -454,12 +476,12 @@ public class Data { ...@@ -454,12 +476,12 @@ public class Data {
case Value.LONG: { case Value.LONG: {
long x = v.getLong(); long x = v.getLong();
if (x < 0) { if (x < 0) {
writeByte((byte) LONG_NEG); writeByte(LONG_NEG);
writeVarLong(-x); writeVarLong(-x);
} else if (x < 8) { } else if (x < 8) {
writeByte((byte) (LONG_0_7 + x)); writeByte((byte) (LONG_0_7 + x));
} else { } else {
writeByte((byte) type); writeByte(LONG);
writeVarLong(x); writeVarLong(x);
} }
break; break;
...@@ -467,7 +489,7 @@ public class Data { ...@@ -467,7 +489,7 @@ public class Data {
case Value.DECIMAL: { case Value.DECIMAL: {
BigDecimal x = v.getBigDecimal(); BigDecimal x = v.getBigDecimal();
if (BigDecimal.ZERO.equals(x)) { if (BigDecimal.ZERO.equals(x)) {
writeByte((byte) DECIMAL_0_1); writeByte(DECIMAL_0_1);
} else if (BigDecimal.ONE.equals(x)) { } else if (BigDecimal.ONE.equals(x)) {
writeByte((byte) (DECIMAL_0_1 + 1)); writeByte((byte) (DECIMAL_0_1 + 1));
} else { } else {
...@@ -476,15 +498,15 @@ public class Data { ...@@ -476,15 +498,15 @@ public class Data {
int bits = b.bitLength(); int bits = b.bitLength();
if (bits <= 63) { if (bits <= 63) {
if (scale == 0) { if (scale == 0) {
writeByte((byte) DECIMAL_SMALL_0); writeByte(DECIMAL_SMALL_0);
writeVarLong(b.longValue()); writeVarLong(b.longValue());
} else { } else {
writeByte((byte) DECIMAL_SMALL); writeByte(DECIMAL_SMALL);
writeVarInt(scale); writeVarInt(scale);
writeVarLong(b.longValue()); writeVarLong(b.longValue());
} }
} else { } else {
writeByte((byte) type); writeByte(DECIMAL);
writeVarInt(scale); writeVarInt(scale);
byte[] bytes = b.toByteArray(); byte[] bytes = b.toByteArray();
writeVarInt(bytes.length); writeVarInt(bytes.length);
...@@ -503,7 +525,7 @@ public class Data { ...@@ -503,7 +525,7 @@ public class Data {
writeVarLong(millis); writeVarLong(millis);
writeVarLong(nanos); writeVarLong(nanos);
} else { } else {
writeByte((byte) type); writeByte(TIME);
writeVarLong(DateTimeUtils.getTimeLocalWithoutDst(v.getTime())); writeVarLong(DateTimeUtils.getTimeLocalWithoutDst(v.getTime()));
} }
break; break;
...@@ -513,7 +535,7 @@ public class Data { ...@@ -513,7 +535,7 @@ public class Data {
long x = ((ValueDate) v).getDateValue(); long x = ((ValueDate) v).getDateValue();
writeVarLong(x); writeVarLong(x);
} else { } else {
writeByte((byte) type); writeByte(DATE);
long x = DateTimeUtils.getTimeLocalWithoutDst(v.getDate()); long x = DateTimeUtils.getTimeLocalWithoutDst(v.getDate());
writeVarLong(x / MILLIS_PER_MINUTE); writeVarLong(x / MILLIS_PER_MINUTE);
} }
...@@ -532,7 +554,7 @@ public class Data { ...@@ -532,7 +554,7 @@ public class Data {
writeVarLong(nanos); writeVarLong(nanos);
} else { } else {
Timestamp ts = v.getTimestamp(); Timestamp ts = v.getTimestamp();
writeByte((byte) type); writeByte(TIMESTAMP);
writeVarLong(DateTimeUtils.getTimeLocalWithoutDst(ts)); writeVarLong(DateTimeUtils.getTimeLocalWithoutDst(ts));
writeVarInt(ts.getNanos() % 1_000_000); writeVarInt(ts.getNanos() % 1_000_000);
} }
...@@ -540,7 +562,7 @@ public class Data { ...@@ -540,7 +562,7 @@ public class Data {
} }
case Value.TIMESTAMP_TZ: { case Value.TIMESTAMP_TZ: {
ValueTimestampTimeZone ts = (ValueTimestampTimeZone) v; ValueTimestampTimeZone ts = (ValueTimestampTimeZone) v;
writeByte((byte) type); writeByte(TIMESTAMP_TZ);
writeVarLong(ts.getDateValue()); writeVarLong(ts.getDateValue());
writeVarLong(ts.getTimeNanos()); writeVarLong(ts.getTimeNanos());
writeVarInt(ts.getTimeZoneOffsetMins()); writeVarInt(ts.getTimeZoneOffsetMins());
...@@ -549,7 +571,7 @@ public class Data { ...@@ -549,7 +571,7 @@ public class Data {
case Value.GEOMETRY: case Value.GEOMETRY:
// fall though // fall though
case Value.JAVA_OBJECT: { case Value.JAVA_OBJECT: {
writeByte((byte) type); writeByte(type == Value.GEOMETRY ? GEOMETRY : JAVA_OBJECT);
byte[] b = v.getBytesNoCopy(); byte[] b = v.getBytesNoCopy();
int len = b.length; int len = b.length;
writeVarInt(len); writeVarInt(len);
...@@ -563,14 +585,14 @@ public class Data { ...@@ -563,14 +585,14 @@ public class Data {
writeByte((byte) (BYTES_0_31 + len)); writeByte((byte) (BYTES_0_31 + len));
write(b, 0, len); write(b, 0, len);
} else { } else {
writeByte((byte) type); writeByte(BYTES);
writeVarInt(len); writeVarInt(len);
write(b, 0, len); write(b, 0, len);
} }
break; break;
} }
case Value.UUID: { case Value.UUID: {
writeByte((byte) type); writeByte(UUID);
ValueUuid uuid = (ValueUuid) v; ValueUuid uuid = (ValueUuid) v;
writeLong(uuid.getHigh()); writeLong(uuid.getHigh());
writeLong(uuid.getLow()); writeLong(uuid.getLow());
...@@ -583,14 +605,17 @@ public class Data { ...@@ -583,14 +605,17 @@ public class Data {
writeByte((byte) (STRING_0_31 + len)); writeByte((byte) (STRING_0_31 + len));
writeStringWithoutLength(s, len); writeStringWithoutLength(s, len);
} else { } else {
writeByte((byte) type); writeByte(STRING);
writeString(s); writeString(s);
} }
break; break;
} }
case Value.STRING_IGNORECASE: case Value.STRING_IGNORECASE:
writeByte(STRING_IGNORECASE);
writeString(v.getString());
break;
case Value.STRING_FIXED: case Value.STRING_FIXED:
writeByte((byte) type); writeByte(STRING_FIXED);
writeString(v.getString()); writeString(v.getString());
break; break;
case Value.DOUBLE: { case Value.DOUBLE: {
...@@ -600,9 +625,9 @@ public class Data { ...@@ -600,9 +625,9 @@ public class Data {
} else { } else {
long d = Double.doubleToLongBits(x); long d = Double.doubleToLongBits(x);
if (d == ValueDouble.ZERO_BITS) { if (d == ValueDouble.ZERO_BITS) {
writeByte((byte) DOUBLE_0_1); writeByte(DOUBLE_0_1);
} else { } else {
writeByte((byte) type); writeByte(DOUBLE);
writeVarLong(Long.reverse(d)); writeVarLong(Long.reverse(d));
} }
} }
...@@ -615,9 +640,9 @@ public class Data { ...@@ -615,9 +640,9 @@ public class Data {
} else { } else {
int f = Float.floatToIntBits(x); int f = Float.floatToIntBits(x);
if (f == ValueFloat.ZERO_BITS) { if (f == ValueFloat.ZERO_BITS) {
writeByte((byte) FLOAT_0_1); writeByte(FLOAT_0_1);
} else { } else {
writeByte((byte) type); writeByte(FLOAT);
writeVarInt(Integer.reverse(f)); writeVarInt(Integer.reverse(f));
} }
} }
...@@ -625,7 +650,7 @@ public class Data { ...@@ -625,7 +650,7 @@ public class Data {
} }
case Value.BLOB: case Value.BLOB:
case Value.CLOB: { case Value.CLOB: {
writeByte((byte) type); writeByte(type == Value.BLOB ? BLOB : CLOB);
if (v instanceof ValueLob) { if (v instanceof ValueLob) {
ValueLob lob = (ValueLob) v; ValueLob lob = (ValueLob) v;
byte[] small = lob.getSmall(); byte[] small = lob.getSmall();
...@@ -663,7 +688,7 @@ public class Data { ...@@ -663,7 +688,7 @@ public class Data {
} }
case Value.ARRAY: case Value.ARRAY:
case Value.ROW: { case Value.ROW: {
writeByte((byte) (type == Value.ARRAY ? Value.ARRAY : /* Special storage type for ValueRow */ ROW)); writeByte(type == Value.ARRAY ? ARRAY : ROW);
Value[] list = ((ValueCollectionBase) v).getList(); Value[] list = ((ValueCollectionBase) v).getList();
writeVarInt(list.length); writeVarInt(list.length);
for (Value x : list) { for (Value x : list) {
...@@ -672,7 +697,7 @@ public class Data { ...@@ -672,7 +697,7 @@ public class Data {
break; break;
} }
case Value.RESULT_SET: { case Value.RESULT_SET: {
writeByte((byte) type); writeByte(RESULT_SET);
ResultInterface result = ((ValueResultSet) v).getResult(); ResultInterface result = ((ValueResultSet) v).getResult();
result.reset(); result.reset();
int columnCount = result.getVisibleColumnCount(); int columnCount = result.getVisibleColumnCount();
...@@ -705,7 +730,7 @@ public class Data { ...@@ -705,7 +730,7 @@ public class Data {
if (interval.isNegative()) { if (interval.isNegative()) {
ordinal = ~ordinal; ordinal = ~ordinal;
} }
writeByte((byte) Value.INTERVAL_YEAR); writeByte(INTERVAL);
writeByte((byte) ordinal); writeByte((byte) ordinal);
writeVarLong(interval.getLeading()); writeVarLong(interval.getLeading());
break; break;
...@@ -723,7 +748,7 @@ public class Data { ...@@ -723,7 +748,7 @@ public class Data {
if (interval.isNegative()) { if (interval.isNegative()) {
ordinal = ~ordinal; ordinal = ~ordinal;
} }
writeByte((byte) Value.INTERVAL_YEAR); writeByte(INTERVAL);
writeByte((byte) ordinal); writeByte((byte) ordinal);
writeVarLong(interval.getLeading()); writeVarLong(interval.getLeading());
writeVarLong(interval.getRemaining()); writeVarLong(interval.getRemaining());
...@@ -732,7 +757,7 @@ public class Data { ...@@ -732,7 +757,7 @@ public class Data {
default: default:
if (JdbcUtils.customDataTypesHandler != null) { if (JdbcUtils.customDataTypesHandler != null) {
byte[] b = v.getBytesNoCopy(); byte[] b = v.getBytesNoCopy();
writeByte(CUSTOM_DATA_TYPE); writeByte((byte) CUSTOM_DATA_TYPE);
writeVarInt(type); writeVarInt(type);
writeVarInt(b.length); writeVarInt(b.length);
write(b, 0, b.length); write(b, 0, b.length);
...@@ -752,7 +777,7 @@ public class Data { ...@@ -752,7 +777,7 @@ public class Data {
public Value readValue() { public Value readValue() {
int type = data[pos++] & 255; int type = data[pos++] & 255;
switch (type) { switch (type) {
case Value.NULL: case NULL:
return ValueNull.INSTANCE; return ValueNull.INSTANCE;
case BOOLEAN_TRUE: case BOOLEAN_TRUE:
return ValueBoolean.TRUE; return ValueBoolean.TRUE;
...@@ -760,16 +785,16 @@ public class Data { ...@@ -760,16 +785,16 @@ public class Data {
return ValueBoolean.FALSE; return ValueBoolean.FALSE;
case INT_NEG: case INT_NEG:
return ValueInt.get(-readVarInt()); return ValueInt.get(-readVarInt());
case Value.ENUM: case ENUM:
case Value.INT: case INT:
return ValueInt.get(readVarInt()); return ValueInt.get(readVarInt());
case LONG_NEG: case LONG_NEG:
return ValueLong.get(-readVarLong()); return ValueLong.get(-readVarLong());
case Value.LONG: case Value.LONG:
return ValueLong.get(readVarLong()); return ValueLong.get(readVarLong());
case Value.BYTE: case BYTE:
return ValueByte.get(readByte()); return ValueByte.get(readByte());
case Value.SHORT: case SHORT:
return ValueShort.get(readShortInt()); return ValueShort.get(readShortInt());
case DECIMAL_0_1: case DECIMAL_0_1:
return (ValueDecimal) ValueDecimal.ZERO; return (ValueDecimal) ValueDecimal.ZERO;
...@@ -781,7 +806,7 @@ public class Data { ...@@ -781,7 +806,7 @@ public class Data {
int scale = readVarInt(); int scale = readVarInt();
return ValueDecimal.get(BigDecimal.valueOf(readVarLong(), scale)); return ValueDecimal.get(BigDecimal.valueOf(readVarLong(), scale));
} }
case Value.DECIMAL: { case DECIMAL: {
int scale = readVarInt(); int scale = readVarInt();
int len = readVarInt(); int len = readVarInt();
byte[] buff = Utils.newBytes(len); byte[] buff = Utils.newBytes(len);
...@@ -792,7 +817,7 @@ public class Data { ...@@ -792,7 +817,7 @@ public class Data {
case LOCAL_DATE: { case LOCAL_DATE: {
return ValueDate.fromDateValue(readVarLong()); return ValueDate.fromDateValue(readVarLong());
} }
case Value.DATE: { case DATE: {
long x = readVarLong() * MILLIS_PER_MINUTE; long x = readVarLong() * MILLIS_PER_MINUTE;
return ValueDate.fromMillis(DateTimeUtils.getTimeUTCWithoutDst(x)); return ValueDate.fromMillis(DateTimeUtils.getTimeUTCWithoutDst(x));
} }
...@@ -800,7 +825,7 @@ public class Data { ...@@ -800,7 +825,7 @@ public class Data {
long nanos = readVarLong() * 1_000_000 + readVarLong(); long nanos = readVarLong() * 1_000_000 + readVarLong();
return ValueTime.fromNanos(nanos); return ValueTime.fromNanos(nanos);
} }
case Value.TIME: case TIME:
// need to normalize the year, month and day // need to normalize the year, month and day
return ValueTime.fromMillis( return ValueTime.fromMillis(
DateTimeUtils.getTimeUTCWithoutDst(readVarLong())); DateTimeUtils.getTimeUTCWithoutDst(readVarLong()));
...@@ -809,42 +834,42 @@ public class Data { ...@@ -809,42 +834,42 @@ public class Data {
long nanos = readVarLong() * 1_000_000 + readVarLong(); long nanos = readVarLong() * 1_000_000 + readVarLong();
return ValueTimestamp.fromDateValueAndNanos(dateValue, nanos); return ValueTimestamp.fromDateValueAndNanos(dateValue, nanos);
} }
case Value.TIMESTAMP: { case TIMESTAMP: {
return ValueTimestamp.fromMillisNanos( return ValueTimestamp.fromMillisNanos(
DateTimeUtils.getTimeUTCWithoutDst(readVarLong()), DateTimeUtils.getTimeUTCWithoutDst(readVarLong()),
readVarInt() % 1_000_000); readVarInt() % 1_000_000);
} }
case Value.TIMESTAMP_TZ: { case TIMESTAMP_TZ: {
long dateValue = readVarLong(); long dateValue = readVarLong();
long nanos = readVarLong(); long nanos = readVarLong();
short tz = (short) readVarInt(); short tz = (short) readVarInt();
return ValueTimestampTimeZone.fromDateValueAndNanos(dateValue, nanos, tz); return ValueTimestampTimeZone.fromDateValueAndNanos(dateValue, nanos, tz);
} }
case Value.BYTES: { case BYTES: {
int len = readVarInt(); int len = readVarInt();
byte[] b = Utils.newBytes(len); byte[] b = Utils.newBytes(len);
read(b, 0, len); read(b, 0, len);
return ValueBytes.getNoCopy(b); return ValueBytes.getNoCopy(b);
} }
case Value.GEOMETRY: { case GEOMETRY: {
int len = readVarInt(); int len = readVarInt();
byte[] b = Utils.newBytes(len); byte[] b = Utils.newBytes(len);
read(b, 0, len); read(b, 0, len);
return ValueGeometry.get(b); return ValueGeometry.get(b);
} }
case Value.JAVA_OBJECT: { case JAVA_OBJECT: {
int len = readVarInt(); int len = readVarInt();
byte[] b = Utils.newBytes(len); byte[] b = Utils.newBytes(len);
read(b, 0, len); read(b, 0, len);
return ValueJavaObject.getNoCopy(null, b, handler); return ValueJavaObject.getNoCopy(null, b, handler);
} }
case Value.UUID: case UUID:
return ValueUuid.get(readLong(), readLong()); return ValueUuid.get(readLong(), readLong());
case Value.STRING: case STRING:
return ValueString.get(readString()); return ValueString.get(readString());
case Value.STRING_IGNORECASE: case STRING_IGNORECASE:
return ValueStringIgnoreCase.get(readString()); return ValueStringIgnoreCase.get(readString());
case Value.STRING_FIXED: case STRING_FIXED:
return ValueStringFixed.get(readString()); return ValueStringFixed.get(readString());
case FLOAT_0_1: case FLOAT_0_1:
return ValueFloat.ZERO; return ValueFloat.ZERO;
...@@ -854,24 +879,22 @@ public class Data { ...@@ -854,24 +879,22 @@ public class Data {
return ValueDouble.ZERO; return ValueDouble.ZERO;
case DOUBLE_0_1 + 1: case DOUBLE_0_1 + 1:
return ValueDouble.ONE; return ValueDouble.ONE;
case Value.DOUBLE: case DOUBLE:
return ValueDouble.get(Double.longBitsToDouble( return ValueDouble.get(Double.longBitsToDouble(Long.reverse(readVarLong())));
Long.reverse(readVarLong()))); case FLOAT:
case Value.FLOAT: return ValueFloat.get(Float.intBitsToFloat(Integer.reverse(readVarInt())));
return ValueFloat.get(Float.intBitsToFloat( case BLOB:
Integer.reverse(readVarInt()))); case CLOB: {
case Value.BLOB:
case Value.CLOB: {
int smallLen = readVarInt(); int smallLen = readVarInt();
if (smallLen >= 0) { if (smallLen >= 0) {
byte[] small = Utils.newBytes(smallLen); byte[] small = Utils.newBytes(smallLen);
read(small, 0, smallLen); read(small, 0, smallLen);
return ValueLobDb.createSmallLob(type, small); return ValueLobDb.createSmallLob(type == BLOB ? Value.BLOB : Value.CLOB, small);
} else if (smallLen == -3) { } else if (smallLen == -3) {
int tableId = readVarInt(); int tableId = readVarInt();
long lobId = readVarLong(); long lobId = readVarLong();
long precision = readVarLong(); long precision = readVarLong();
return ValueLobDb.create(type, handler, tableId, return ValueLobDb.create(type == BLOB ? Value.BLOB : Value.CLOB, handler, tableId,
lobId, null, precision); lobId, null, precision);
} else { } else {
int tableId = readVarInt(); int tableId = readVarInt();
...@@ -886,14 +909,14 @@ public class Data { ...@@ -886,14 +909,14 @@ public class Data {
} }
if (smallLen == -2) { if (smallLen == -2) {
String filename = readString(); String filename = readString();
return ValueLob.openUnlinked(type, handler, tableId, return ValueLob.openUnlinked(type == BLOB ? Value.BLOB : Value.CLOB, handler, tableId,
objectId, precision, compression, filename); objectId, precision, compression, filename);
} }
return ValueLob.openLinked(type, handler, tableId, return ValueLob.openLinked(type == BLOB ? Value.BLOB : Value.CLOB, handler, tableId,
objectId, precision, compression); objectId, precision, compression);
} }
} }
case Value.ARRAY: case ARRAY:
case ROW: // Special storage type for ValueRow case ROW: // Special storage type for ValueRow
{ {
int len = readVarInt(); int len = readVarInt();
...@@ -901,9 +924,9 @@ public class Data { ...@@ -901,9 +924,9 @@ public class Data {
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
list[i] = readValue(); list[i] = readValue();
} }
return type == Value.ARRAY ? ValueArray.get(list) : ValueRow.get(list); return type == ARRAY ? ValueArray.get(list) : ValueRow.get(list);
} }
case Value.RESULT_SET: { case RESULT_SET: {
SimpleResult rs = new SimpleResult(); SimpleResult rs = new SimpleResult();
int columns = readVarInt(); int columns = readVarInt();
for (int i = 0; i < columns; i++) { for (int i = 0; i < columns; i++) {
...@@ -918,7 +941,7 @@ public class Data { ...@@ -918,7 +941,7 @@ public class Data {
} }
return ValueResultSet.get(rs); return ValueResultSet.get(rs);
} }
case Value.INTERVAL_YEAR: { case INTERVAL: {
int ordinal = readByte(); int ordinal = readByte();
boolean negative = ordinal < 0; boolean negative = ordinal < 0;
if (negative) { if (negative) {
......
...@@ -42,6 +42,34 @@ public class Transfer { ...@@ -42,6 +42,34 @@ public class Transfer {
private static final int LOB_MAGIC = 0x1234; private static final int LOB_MAGIC = 0x1234;
private static final int LOB_MAC_SALT_LENGTH = 16; private static final int LOB_MAC_SALT_LENGTH = 16;
private static final int NULL = 0;
private static final int BOOLEAN = 1;
private static final int BYTE = 2;
private static final int SHORT = 3;
private static final int INT = 4;
private static final int LONG = 5;
private static final int DECIMAL = 6;
private static final int DOUBLE = 7;
private static final int FLOAT = 8;
private static final int TIME = 9;
private static final int DATE = 10;
private static final int TIMESTAMP = 11;
private static final int BYTES = 12;
private static final int STRING = 13;
private static final int STRING_IGNORECASE = 14;
private static final int BLOB = 15;
private static final int CLOB = 16;
private static final int ARRAY = 17;
private static final int RESULT_SET = 18;
private static final int JAVA_OBJECT = 19;
private static final int UUID = 20;
private static final int STRING_FIXED = 21;
private static final int GEOMETRY = 22;
private static final int TIMESTAMP_TZ = 24;
private static final int ENUM = 25;
private static final int INTERVAL = 26;
private static final int ROW = 27;
private Socket socket; private Socket socket;
private DataInputStream in; private DataInputStream in;
private DataOutputStream out; private DataOutputStream out;
...@@ -322,45 +350,48 @@ public class Transfer { ...@@ -322,45 +350,48 @@ public class Transfer {
int type = v.getValueType(); int type = v.getValueType();
switch (type) { switch (type) {
case Value.NULL: case Value.NULL:
writeInt(Value.NULL); writeInt(NULL);
break; break;
case Value.BYTES: case Value.BYTES:
writeInt(BYTES);
writeBytes(v.getBytesNoCopy());
break;
case Value.JAVA_OBJECT: case Value.JAVA_OBJECT:
writeInt(type); writeInt(JAVA_OBJECT);
writeBytes(v.getBytesNoCopy()); writeBytes(v.getBytesNoCopy());
break; break;
case Value.UUID: { case Value.UUID: {
writeInt(Value.UUID); writeInt(UUID);
ValueUuid uuid = (ValueUuid) v; ValueUuid uuid = (ValueUuid) v;
writeLong(uuid.getHigh()); writeLong(uuid.getHigh());
writeLong(uuid.getLow()); writeLong(uuid.getLow());
break; break;
} }
case Value.BOOLEAN: case Value.BOOLEAN:
writeInt(Value.BOOLEAN); writeInt(BOOLEAN);
writeBoolean(v.getBoolean()); writeBoolean(v.getBoolean());
break; break;
case Value.BYTE: case Value.BYTE:
writeInt(Value.BYTE); writeInt(BYTE);
writeByte(v.getByte()); writeByte(v.getByte());
break; break;
case Value.TIME: case Value.TIME:
writeInt(Value.TIME); writeInt(TIME);
writeLong(((ValueTime) v).getNanos()); writeLong(((ValueTime) v).getNanos());
break; break;
case Value.DATE: case Value.DATE:
writeInt(Value.DATE); writeInt(DATE);
writeLong(((ValueDate) v).getDateValue()); writeLong(((ValueDate) v).getDateValue());
break; break;
case Value.TIMESTAMP: { case Value.TIMESTAMP: {
writeInt(Value.TIMESTAMP); writeInt(TIMESTAMP);
ValueTimestamp ts = (ValueTimestamp) v; ValueTimestamp ts = (ValueTimestamp) v;
writeLong(ts.getDateValue()); writeLong(ts.getDateValue());
writeLong(ts.getTimeNanos()); writeLong(ts.getTimeNanos());
break; break;
} }
case Value.TIMESTAMP_TZ: { case Value.TIMESTAMP_TZ: {
writeInt(Value.TIMESTAMP_TZ); writeInt(TIMESTAMP_TZ);
ValueTimestampTimeZone ts = (ValueTimestampTimeZone) v; ValueTimestampTimeZone ts = (ValueTimestampTimeZone) v;
writeLong(ts.getDateValue()); writeLong(ts.getDateValue());
writeLong(ts.getTimeNanos()); writeLong(ts.getTimeNanos());
...@@ -368,37 +399,43 @@ public class Transfer { ...@@ -368,37 +399,43 @@ public class Transfer {
break; break;
} }
case Value.DECIMAL: case Value.DECIMAL:
writeInt(Value.DECIMAL); writeInt(DECIMAL);
writeString(v.getString()); writeString(v.getString());
break; break;
case Value.DOUBLE: case Value.DOUBLE:
writeInt(Value.DOUBLE); writeInt(DOUBLE);
writeDouble(v.getDouble()); writeDouble(v.getDouble());
break; break;
case Value.FLOAT: case Value.FLOAT:
writeInt(Value.FLOAT); writeInt(FLOAT);
writeFloat(v.getFloat()); writeFloat(v.getFloat());
break; break;
case Value.INT: case Value.INT:
writeInt(Value.INT); writeInt(INT);
writeInt(v.getInt()); writeInt(v.getInt());
break; break;
case Value.LONG: case Value.LONG:
writeInt(Value.LONG); writeInt(LONG);
writeLong(v.getLong()); writeLong(v.getLong());
break; break;
case Value.SHORT: case Value.SHORT:
writeInt(Value.SHORT); writeInt(SHORT);
writeInt(v.getShort()); writeInt(v.getShort());
break; break;
case Value.STRING: case Value.STRING:
writeInt(STRING);
writeString(v.getString());
break;
case Value.STRING_IGNORECASE: case Value.STRING_IGNORECASE:
writeInt(STRING_IGNORECASE);
writeString(v.getString());
break;
case Value.STRING_FIXED: case Value.STRING_FIXED:
writeInt(type); writeInt(STRING_FIXED);
writeString(v.getString()); writeString(v.getString());
break; break;
case Value.BLOB: { case Value.BLOB: {
writeInt(Value.BLOB); writeInt(BLOB);
if (version >= Constants.TCP_PROTOCOL_VERSION_11) { if (version >= Constants.TCP_PROTOCOL_VERSION_11) {
if (v instanceof ValueLobDb) { if (v instanceof ValueLobDb) {
ValueLobDb lob = (ValueLobDb) v; ValueLobDb lob = (ValueLobDb) v;
...@@ -429,7 +466,7 @@ public class Transfer { ...@@ -429,7 +466,7 @@ public class Transfer {
break; break;
} }
case Value.CLOB: { case Value.CLOB: {
writeInt(Value.CLOB); writeInt(CLOB);
if (version >= Constants.TCP_PROTOCOL_VERSION_11) { if (version >= Constants.TCP_PROTOCOL_VERSION_11) {
if (v instanceof ValueLobDb) { if (v instanceof ValueLobDb) {
ValueLobDb lob = (ValueLobDb) v; ValueLobDb lob = (ValueLobDb) v;
...@@ -457,7 +494,7 @@ public class Transfer { ...@@ -457,7 +494,7 @@ public class Transfer {
break; break;
} }
case Value.ARRAY: { case Value.ARRAY: {
writeInt(Value.ARRAY); writeInt(ARRAY);
ValueArray va = (ValueArray) v; ValueArray va = (ValueArray) v;
Value[] list = va.getList(); Value[] list = va.getList();
int len = list.length; int len = list.length;
...@@ -474,7 +511,7 @@ public class Transfer { ...@@ -474,7 +511,7 @@ public class Transfer {
break; break;
} }
case Value.ROW: { case Value.ROW: {
writeInt(version >= Constants.TCP_PROTOCOL_VERSION_18 ? Value.ROW : Value.ARRAY); writeInt(version >= Constants.TCP_PROTOCOL_VERSION_18 ? ROW : ARRAY);
ValueRow va = (ValueRow) v; ValueRow va = (ValueRow) v;
Value[] list = va.getList(); Value[] list = va.getList();
int len = list.length; int len = list.length;
...@@ -485,13 +522,13 @@ public class Transfer { ...@@ -485,13 +522,13 @@ public class Transfer {
break; break;
} }
case Value.ENUM: { case Value.ENUM: {
writeInt(Value.ENUM); writeInt(ENUM);
writeInt(v.getInt()); writeInt(v.getInt());
writeString(v.getString()); writeString(v.getString());
break; break;
} }
case Value.RESULT_SET: { case Value.RESULT_SET: {
writeInt(Value.RESULT_SET); writeInt(RESULT_SET);
ResultInterface result = ((ValueResultSet) v).getResult(); ResultInterface result = ((ValueResultSet) v).getResult();
int columnCount = result.getVisibleColumnCount(); int columnCount = result.getVisibleColumnCount();
writeInt(columnCount); writeInt(columnCount);
...@@ -520,7 +557,7 @@ public class Transfer { ...@@ -520,7 +557,7 @@ public class Transfer {
break; break;
} }
case Value.GEOMETRY: case Value.GEOMETRY:
writeInt(Value.GEOMETRY); writeInt(GEOMETRY);
if (version >= Constants.TCP_PROTOCOL_VERSION_14) { if (version >= Constants.TCP_PROTOCOL_VERSION_14) {
writeBytes(v.getBytesNoCopy()); writeBytes(v.getBytesNoCopy());
} else { } else {
...@@ -533,12 +570,16 @@ public class Transfer { ...@@ -533,12 +570,16 @@ public class Transfer {
case Value.INTERVAL_HOUR: case Value.INTERVAL_HOUR:
case Value.INTERVAL_MINUTE: case Value.INTERVAL_MINUTE:
if (version >= Constants.TCP_PROTOCOL_VERSION_18) { if (version >= Constants.TCP_PROTOCOL_VERSION_18) {
writeInt(type);
ValueInterval interval = (ValueInterval) v; ValueInterval interval = (ValueInterval) v;
writeBoolean(interval.isNegative()); int ordinal = type - Value.INTERVAL_YEAR;
if (interval.isNegative()) {
ordinal = ~ordinal;
}
writeInt(INTERVAL);
writeByte((byte) ordinal);
writeLong(interval.getLeading()); writeLong(interval.getLeading());
} else { } else {
writeInt(Value.STRING); writeInt(STRING);
writeString(v.getString()); writeString(v.getString());
} }
break; break;
...@@ -551,13 +592,17 @@ public class Transfer { ...@@ -551,13 +592,17 @@ public class Transfer {
case Value.INTERVAL_HOUR_TO_SECOND: case Value.INTERVAL_HOUR_TO_SECOND:
case Value.INTERVAL_MINUTE_TO_SECOND: case Value.INTERVAL_MINUTE_TO_SECOND:
if (version >= Constants.TCP_PROTOCOL_VERSION_18) { if (version >= Constants.TCP_PROTOCOL_VERSION_18) {
writeInt(type);
ValueInterval interval = (ValueInterval) v; ValueInterval interval = (ValueInterval) v;
writeBoolean(interval.isNegative()); int ordinal = type - Value.INTERVAL_YEAR;
if (interval.isNegative()) {
ordinal = ~ordinal;
}
writeInt(INTERVAL);
writeByte((byte) ordinal);
writeLong(interval.getLeading()); writeLong(interval.getLeading());
writeLong(interval.getRemaining()); writeLong(interval.getRemaining());
} else { } else {
writeInt(Value.STRING); writeInt(STRING);
writeString(v.getString()); writeString(v.getString());
} }
break; break;
...@@ -579,51 +624,51 @@ public class Transfer { ...@@ -579,51 +624,51 @@ public class Transfer {
public Value readValue() throws IOException { public Value readValue() throws IOException {
int type = readInt(); int type = readInt();
switch (type) { switch (type) {
case Value.NULL: case NULL:
return ValueNull.INSTANCE; return ValueNull.INSTANCE;
case Value.BYTES: case BYTES:
return ValueBytes.getNoCopy(readBytes()); return ValueBytes.getNoCopy(readBytes());
case Value.UUID: case UUID:
return ValueUuid.get(readLong(), readLong()); return ValueUuid.get(readLong(), readLong());
case Value.JAVA_OBJECT: case JAVA_OBJECT:
return ValueJavaObject.getNoCopy(null, readBytes(), session.getDataHandler()); return ValueJavaObject.getNoCopy(null, readBytes(), session.getDataHandler());
case Value.BOOLEAN: case BOOLEAN:
return ValueBoolean.get(readBoolean()); return ValueBoolean.get(readBoolean());
case Value.BYTE: case BYTE:
return ValueByte.get(readByte()); return ValueByte.get(readByte());
case Value.DATE: case DATE:
return ValueDate.fromDateValue(readLong()); return ValueDate.fromDateValue(readLong());
case Value.TIME: case TIME:
return ValueTime.fromNanos(readLong()); return ValueTime.fromNanos(readLong());
case Value.TIMESTAMP: case TIMESTAMP:
return ValueTimestamp.fromDateValueAndNanos(readLong(), readLong()); return ValueTimestamp.fromDateValueAndNanos(readLong(), readLong());
case Value.TIMESTAMP_TZ: { case TIMESTAMP_TZ: {
return ValueTimestampTimeZone.fromDateValueAndNanos(readLong(), readLong(), (short) readInt()); return ValueTimestampTimeZone.fromDateValueAndNanos(readLong(), readLong(), (short) readInt());
} }
case Value.DECIMAL: case DECIMAL:
return ValueDecimal.get(new BigDecimal(readString())); return ValueDecimal.get(new BigDecimal(readString()));
case Value.DOUBLE: case DOUBLE:
return ValueDouble.get(readDouble()); return ValueDouble.get(readDouble());
case Value.FLOAT: case FLOAT:
return ValueFloat.get(readFloat()); return ValueFloat.get(readFloat());
case Value.ENUM: { case ENUM: {
final int ordinal = readInt(); final int ordinal = readInt();
final String label = readString(); final String label = readString();
return ValueEnumBase.get(label, ordinal); return ValueEnumBase.get(label, ordinal);
} }
case Value.INT: case INT:
return ValueInt.get(readInt()); return ValueInt.get(readInt());
case Value.LONG: case LONG:
return ValueLong.get(readLong()); return ValueLong.get(readLong());
case Value.SHORT: case SHORT:
return ValueShort.get((short) readInt()); return ValueShort.get((short) readInt());
case Value.STRING: case STRING:
return ValueString.get(readString()); return ValueString.get(readString());
case Value.STRING_IGNORECASE: case STRING_IGNORECASE:
return ValueStringIgnoreCase.get(readString()); return ValueStringIgnoreCase.get(readString());
case Value.STRING_FIXED: case STRING_FIXED:
return ValueStringFixed.get(readString()); return ValueStringFixed.get(readString());
case Value.BLOB: { case BLOB: {
long length = readLong(); long length = readLong();
if (version >= Constants.TCP_PROTOCOL_VERSION_11) { if (version >= Constants.TCP_PROTOCOL_VERSION_11) {
if (length == -1) { if (length == -1) {
...@@ -648,7 +693,7 @@ public class Transfer { ...@@ -648,7 +693,7 @@ public class Transfer {
} }
return v; return v;
} }
case Value.CLOB: { case CLOB: {
long length = readLong(); long length = readLong();
if (version >= Constants.TCP_PROTOCOL_VERSION_11) { if (version >= Constants.TCP_PROTOCOL_VERSION_11) {
if (length == -1) { if (length == -1) {
...@@ -678,7 +723,7 @@ public class Transfer { ...@@ -678,7 +723,7 @@ public class Transfer {
} }
return v; return v;
} }
case Value.ARRAY: { case ARRAY: {
int len = readInt(); int len = readInt();
Class<?> componentType = Object.class; Class<?> componentType = Object.class;
if (len < 0) { if (len < 0) {
...@@ -691,7 +736,7 @@ public class Transfer { ...@@ -691,7 +736,7 @@ public class Transfer {
} }
return ValueArray.get(componentType, list); return ValueArray.get(componentType, list);
} }
case Value.ROW: { case ROW: {
int len = readInt(); int len = readInt();
Value[] list = new Value[len]; Value[] list = new Value[len];
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
...@@ -699,7 +744,7 @@ public class Transfer { ...@@ -699,7 +744,7 @@ public class Transfer {
} }
return ValueRow.get(list); return ValueRow.get(list);
} }
case Value.RESULT_SET: { case RESULT_SET: {
SimpleResult rs = new SimpleResult(); SimpleResult rs = new SimpleResult();
int columns = readInt(); int columns = readInt();
for (int i = 0; i < columns; i++) { for (int i = 0; i < columns; i++) {
...@@ -719,28 +764,20 @@ public class Transfer { ...@@ -719,28 +764,20 @@ public class Transfer {
} }
return ValueResultSet.get(rs); return ValueResultSet.get(rs);
} }
case Value.GEOMETRY: case GEOMETRY:
if (version >= Constants.TCP_PROTOCOL_VERSION_14) { if (version >= Constants.TCP_PROTOCOL_VERSION_14) {
return ValueGeometry.get(readBytes()); return ValueGeometry.get(readBytes());
} }
return ValueGeometry.get(readString()); return ValueGeometry.get(readString());
case Value.INTERVAL_YEAR: case INTERVAL: {
case Value.INTERVAL_MONTH: int ordinal = readByte();
case Value.INTERVAL_DAY: boolean negative = ordinal < 0;
case Value.INTERVAL_HOUR: if (negative) {
case Value.INTERVAL_MINUTE: ordinal = ~ordinal;
return ValueInterval.from(IntervalQualifier.valueOf(type - Value.INTERVAL_YEAR), readBoolean(), readLong(), }
0L); return ValueInterval.from(IntervalQualifier.valueOf(ordinal), negative, readLong(),
case Value.INTERVAL_SECOND: ordinal < 5 ? 0 : readLong());
case Value.INTERVAL_YEAR_TO_MONTH: }
case Value.INTERVAL_DAY_TO_HOUR:
case Value.INTERVAL_DAY_TO_MINUTE:
case Value.INTERVAL_DAY_TO_SECOND:
case Value.INTERVAL_HOUR_TO_MINUTE:
case Value.INTERVAL_HOUR_TO_SECOND:
case Value.INTERVAL_MINUTE_TO_SECOND:
return ValueInterval.from(IntervalQualifier.valueOf(type - Value.INTERVAL_YEAR), readBoolean(), readLong(),
readLong());
default: default:
if (JdbcUtils.customDataTypesHandler != null) { if (JdbcUtils.customDataTypesHandler != null) {
return JdbcUtils.customDataTypesHandler.convert( return JdbcUtils.customDataTypesHandler.convert(
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论