提交 52f3bd34 authored 作者: Thomas Mueller's avatar Thomas Mueller

CAST: when converting a string to binary, it is hex encoded (every byte two…

CAST: when converting a string to binary, it is hex encoded (every byte two characters); a hex string can be converted to a number by first converting it to binary.
上级 2c3f2627
......@@ -3229,10 +3229,18 @@ CASEWHEN(ID=1, 'A', 'B')
"Functions (System)","CAST","
CAST(value AS dataType)
","
Converts a value to another data type. When converting a text to a number, the default Java conversion
rules are used (prefixes 0x or # for hexadecimal numbers, prefix 0 for octal numbers).
","
CAST(NAME AS INT)
Converts a value to another data type. The following conversion rules are used:
When converting a number to a boolean, 0 is false and every other value is true.
When converting a boolean to a number, false is 0 and true is 1.
When converting a number to a number of another type, the value is checked for overflow.
When converting a number to binary, the number of bytes matches the precision.
When converting a string to binary, it is hex encoded (every byte two characters);
a hex string can be converted to a number by first converting it to binary.
If a direct conversion is not possible, the value is first converted to a string.
","
CAST(NAME AS INT);
CAST(65535 AS BINARY);
CAST(CAST('FFFF' AS BINARY) AS INT);
"
"Functions (System)","COALESCE","
......
......@@ -25,6 +25,7 @@ import org.h2.store.LobStorage;
import org.h2.tools.SimpleResultSet;
import org.h2.util.IOUtils;
import org.h2.util.StringUtils;
import org.h2.util.Utils;
/**
* This is the base class for all value classes.
......@@ -487,17 +488,17 @@ public abstract class Value {
/**
* Compare a value to the specified type.
*
* @param type the value type
* @return the value
* @param targetType the type of the returned value
* @return the converted value
*/
public Value convertTo(int type) {
// converting NULL done in ValueNull
public Value convertTo(int targetType) {
// converting NULL is done in ValueNull
// converting BLOB to CLOB and vice versa is done in ValueLob
if (getType() == type) {
if (getType() == targetType) {
return this;
}
// decimal conversion
switch (type) {
switch (targetType) {
case BOOLEAN: {
switch (getType()) {
case BYTE:
......@@ -534,6 +535,8 @@ public abstract class Value {
return ValueByte.get(convertToByte(convertToLong(getDouble())));
case FLOAT:
return ValueByte.get(convertToByte(convertToLong(getFloat())));
case BYTES:
return ValueByte.get((byte) Integer.parseInt(getString(), 16));
}
break;
}
......@@ -553,6 +556,8 @@ public abstract class Value {
return ValueShort.get(convertToShort(convertToLong(getDouble())));
case FLOAT:
return ValueShort.get(convertToShort(convertToLong(getFloat())));
case BYTES:
return ValueShort.get((short) Integer.parseInt(getString(), 16));
}
break;
}
......@@ -572,6 +577,8 @@ public abstract class Value {
return ValueInt.get(convertToInt(convertToLong(getDouble())));
case FLOAT:
return ValueInt.get(convertToInt(convertToLong(getFloat())));
case BYTES:
return ValueInt.get((int) Long.parseLong(getString(), 16));
}
break;
}
......@@ -591,6 +598,14 @@ public abstract class Value {
return ValueLong.get(convertToLong(getDouble()));
case FLOAT:
return ValueLong.get(convertToLong(getFloat()));
case BYTES: {
// parseLong doesn't work for ffffffffffffffff
byte[] d = getBytes();
if (d.length == 8) {
return ValueLong.get(Utils.readLong(d, 0));
}
return ValueLong.get(Long.parseLong(getString(), 16));
}
}
break;
}
......@@ -698,6 +713,37 @@ public abstract class Value {
return ValueBytes.getNoCopy(getBytesNoCopy());
case UUID:
return ValueBytes.getNoCopy(getBytes());
case BYTE:
return ValueBytes.getNoCopy(new byte[]{getByte()});
case SHORT: {
int x = getShort();
return ValueBytes.getNoCopy(new byte[]{
(byte) (x >> 8),
(byte) x
});
}
case INT: {
int x = getInt();
return ValueBytes.getNoCopy(new byte[]{
(byte) (x >> 24),
(byte) (x >> 16),
(byte) (x >> 8),
(byte) x
});
}
case LONG: {
long x = getLong();
return ValueBytes.getNoCopy(new byte[]{
(byte) (x >> 56),
(byte) (x >> 48),
(byte) (x >> 40),
(byte) (x >> 32),
(byte) (x >> 24),
(byte) (x >> 16),
(byte) (x >> 8),
(byte) x
});
}
}
break;
}
......@@ -727,7 +773,7 @@ public abstract class Value {
// conversion by parsing the string value
String s = getString();
try {
switch (type) {
switch (targetType) {
case NULL:
return ValueNull.INSTANCE;
case BOOLEAN: {
......@@ -785,7 +831,7 @@ public abstract class Value {
case UUID:
return ValueUuid.get(s);
default:
throw DbException.throwInternalError("type=" + type);
throw DbException.throwInternalError("type=" + targetType);
}
} catch (NumberFormatException e) {
throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, e, s);
......
select cast(128 as binary);
> 00000080;
select cast(65535 as binary);
> 0000ffff;
select cast(cast('ff' as binary) as tinyint) x;
> -1;
select cast(cast('7f' as binary) as tinyint) x;
> 127;
select cast(cast('ff' as binary) as smallint) x;
> 255;
select cast(cast('ff' as binary) as int) x;
> 255;
select cast(cast('ffff' as binary) as long) x;
> 65535;
select cast(cast(65535 as long) as binary);
> 000000000000ffff;
select cast(cast(-1 as tinyint) as binary);
> ff;
select cast(cast(-1 as smallint) as binary);
> ffff;
select cast(cast(-1 as int) as binary);
> ffffffff;
select cast(cast(-1 as long) as binary);
> ffffffffffffffff;
select cast(cast(1 as tinyint) as binary);
> 01;
select cast(cast(1 as smallint) as binary);
> 0001;
select cast(cast(1 as int) as binary);
> 00000001;
select cast(cast(1 as long) as binary);
> 0000000000000001;
select cast(X'ff' as tinyint);
> -1;
select cast(X'ffff' as smallint);
> -1;
select cast(X'ffffffff' as int);
> -1;
select cast(X'ffffffffffffffff' as long);
> -1;
select N'test';
> test;
select cast(' 011 ' as int);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论