隐式类型转换
InCloud ZNBASE支持隐式类型转换,在执行插入或更新、二元运算、比较、union、case语句以及充当条件表达式时,如果操作数的类型不相同,则有可能发生隐式类型转换使操作数与操作符相符合。
插入或更新
插入或更新语句中,如果表达式数据类型和插入列类型不一致,则此表达式可能发生隐式类型转换。需要注意,对于同样的表达式,不同的列类型对于表达式的处理可能会不同。例如字符串’2019.123’分别插入INT、FLOAT、DECIMAL(10,4)、DATE列,插入的结果分别是2019,2019.123, 2019.1230和2019-05-03 00:00:00+00:00。
CREATE TABLE test(intCol INT, floatCol FLOAT, decimalCol DECIMAL(10, 4), dateCol DATE);
CREATE TABLE
INSERT INTO test VALUES (‘2019.123’, ‘2019.123’, ‘2019.123’, ‘2019.123’);
INSERT 1
SELECT * FROM test;
intcol | floatcol | decimalcol | datecol
+———-+——————-+———————-+———————————————————+
2019 | 2019.123 | 2019.1230 | 2019-05-03 00:00:00+00:00
不同的类型之间的类型转换采用不同的规则,具体规则详见上述不同类型的类型转换。
注:UPDATE语句中,涉及string类型转换为数值类型时,string参数必须为纯数字串。
目前插入、更新语句支持的类型转换如下表所示:
To Int | To Float | To Decimal | To Bool | To String | To Date | To Time | To Timestamp | To TimestampTZ | To Bitarray | |
---|---|---|---|---|---|---|---|---|---|---|
Int | — | √ | √ | √ | √ | √ | √ | √ | √ | √ |
Float | √ | — | √ | √ | √ | √ | √ | √ | √ | √ |
Decimal | √ | √ | — | √ | √ | √ | √ | √ | √ | √ |
Bool | √ | √ | √ | — | √ | × | × | × | × | √ |
String | √ | √ | √ | √ | — | √ | √ | √ | √ | √ |
Date | √ | √ | √ | √ | √ | — | × | √ | √ | × |
Time | √ | √ | √ | √ | √ | × | — | √ | √ | × |
Timestamp | √ | √ | √ | √ | √ | √ | √ | — | √ | × |
TimestampTZ | √ | √ | √ | √ | √ | √ | √ | √ | — | × |
Bitarray | √ | √ | √ | √ | √ | × | × | × | × | — |
二元运算
部分二元运算支持隐式类型转换的二元运算包括:加法、减法、乘法、除法、向下取整除法、模运算、连接、乘方。
一般来说,两个不同类型的表达式在进行二元运算时,会优先尝试把类型精度低或者表示范围小的参数转换为精度更高或者表示范围更大的参数类型。例如,select 1+2.5左边参数为整型右边参数为浮点型,这种情况下就会隐式把整型1转换为浮点数类型,计算得到的结果也是浮点类型,诸如此类。
特殊说明:
- 在四则运算以及模运算时,bool类型参数总是隐式转换为int类型,true对应1,false对应0。
- Concat连接运算在参数类型不匹配或者没有找到正确的重载时,默认转换为string类型进行运算
- string类型与时间类型(date、time、interval、timestamp、timestampTZ)之间的二元运算不进行隐式类型转换。其中的特例:加法中,当第一个参数是timestamp或timestampTZ类型以及减法中第一个参数为interval类型是,会隐式把第二个string类型的参数转换为interval类型。
- timestamp interval、timestampTZ + interval 返回类型分别为timestamp、timestampTZ,interval - interval返回类型为interval。
上述条件均不满足且类型可转换时,以decimal作为默认转换类型。
二元运算支持的类型转换如下表所示:
Type Right Type Left | Int | Float | Decimal | Bool | String | Date | Time | Timestamp | TimestampTZ | Bitarray |
---|---|---|---|---|---|---|---|---|---|---|
Int | — | √ | √ | √ | √ | √ | √ | √ | √ | √ |
Float | √ | — | √ | √ | √ | √ | √ | √ | √ | √ |
Decimal | √ | √ | — | √ | √ | √ | √ | √ | √ | √ |
Bool | √ | √ | √ | — | √ | √ | √ | √ | √ | √ |
String | √ | √ | √ | √ | — | × | × | × | × | √ |
Date | √ | √ | √ | √ | × | — | √ | √ | √ | √ |
Time | √ | √ | √ | √ | × | √ | — | √ | √ | √ |
Timestamp | √ | √ | √ | √ | × | √ | √ | — | √ | √ |
TimestampTZ | √ | √ | √ | √ | × | √ | √ | √ | — | √ |
Bitarray | √ | √ | √ | √ | √ | √ | √ | √ | √ | — |
比较运算
String类型在与非数值类型进行比较时,以另一个参数的类型作为参考类型进行比较;与数值参数比较时,将二者作为浮点数进行比较;
Bool类型与其他类型参数进行比较时,除与string类型比较时以bool类型进行比较,其他情况下,true取数值1,false取数值0与其他类型参数进行比较;
Bitarray类型参数与其他除string类型参数进行比较时,二者均转为数值类型进行比较,在与string类型参数比较时,string需转为bitarray类型再进行后续比较;
String类型与时间类型(date、time、interval、timestamp、timestampTZ)之间的比较运算不进行隐式类型转换。其中的特例:当string可以转为与其比较的时间类型时,string可以转为时间类型与另一参数进行比较,例如,date类型的‘2016-01-01’与string类型的‘2016-01-01’或者‘20160101’进行比较判断时,字符串是可正常转为date类型的,所以比较操作正常进行,但是如果是类似于‘123abc’等字符串,则会报错,不支持string类型和date类型之间的比较。
上述情况之外且类型可转换时,decimal类型作为比较运算时参数的基准类型。
比较运算支持的类型转换如下表所示:
TypeRight Type Left | Int | Float | Decimal | Bool | String | Date | Time | Timestamp | TimestampTZ | Bitarray |
---|---|---|---|---|---|---|---|---|---|---|
Int | — | √ | √ | √ | √ | √ | √ | √ | √ | √ |
Float | √ | — | √ | √ | √ | √ | √ | √ | √ | √ |
Decimal | √ | √ | — | √ | √ | √ | √ | √ | √ | √ |
Bool | √ | √ | √ | — | √ | √ | √ | √ | √ | √ |
String | √ | √ | √ | √ | — | × | × | × | × | √ |
Date | √ | √ | √ | √ | × | — | √ | √ | √ | √ |
Time | √ | √ | √ | √ | × | √ | — | √ | √ | √ |
Timestamp | √ | √ | √ | √ | × | √ | √ | — | √ | √ |
TimestampTZ | √ | √ | √ | √ | × | √ | √ | √ | — | √ |
Bitarray | √ | √ | √ | √ | √ | √ | √ | √ | √ | — |
UNION
bool型参数与数值类型参数union时以数值1或0参与union运算,与bitarray型参数union时以bitarray类型以基准转换类型,其他情况下转换为string类型参与union;
如果两个参数都是数值类型,则union返回类型为其中表示范围更大的数值类型;如果两个参数均为时间类型,则union返回类型为timestamp或timestampTZ类型;
除此之外,默认union返回类型为string类型。union运算隐式的类型转换如下表所示:
Type Right Type Left | Int | Float | Decimal (Dec) | Bool | String | Date | Time | Interval | Time stamp(T) | TimestampTZ(TZ) | Bitarray |
---|---|---|---|---|---|---|---|---|---|---|---|
Int | — | Float | Dec | Int | String | String | String | String | String | String | Int |
Float | Float | — | Dec | Float | String | String | String | String | String | String | Float |
Decimal (Dec) | Dec | Dec | — | Dec | String | String | String | String | String | String | Dec |
Bool | Int | Float | Dec | — | String | String | String | String | String | String | Bitarray |
String | String | String | String | String | — | String | String | String | String | String | String |
Date | String | String | String | String | String | — | T | String | T | TZ | String |
Time | String | String | String | String | String | T | — | String | T | TZ | String |
Interval | String | String | String | String | String | String | String | — | String | String | String |
Timestamp(T) | String | String | String | String | String | T | T | String | — | T | String |
TimestampTZ (TZ) | String | String | String | String | String | TZ | TZ | String | T | — | String |
Bitarray | Int | Float | Dec | Bitarray | String | String | String | String | String | String | — |
CASE
Case中的隐式类型转换仅允许case…when…中when的结果值在类型不相同时在有限程度上进行隐式类型转换。在值的类型不完全相同时,允许的三种情况,如下:
- 所有的值的类型为数值类型,返回类型为所有数值类型中精度最高类型,如int,decimal,int,则返回类型为decimal;
- 所有的值类型为时间日期类型,返回类型为timestamp类型;
- 所有的值类型为字符串相关类型,返回类型为string类型。
条件表达式
条件表达式总是期望一个bool类型的参数或者表达式,当一个实际类型非bool类型的表达式作为条件表达式时,总是将实际参数作为bool类型进行计算。例如,
SELECT IF(123.456, ‘true’, ‘false’);
if
+————-+
True
SELECT IF(‘0’, ‘true’, ‘false’);
if
+———-+
false
总体转换规则与插入BOOL列相似,string转BOOL有所区别,插入或更新时允许纯数字串转为BOOL,条件表达式的隐式转换中不允许纯数字串转为BOOL。
目前条件语句支持的类型转换如下表所示:
Int | Float | Decimal | Bool | String | Date | Time | Timestamp | TimestampTZ | Bitarray | |
---|---|---|---|---|---|---|---|---|---|---|
TO BOOL | √ | √ | √ | — | √ | √ | √ | √ | √ | √ |