概述
背景信息
在SQL语言中,每个数据都与一个决定其行为和用法的数据类型相关。GaussDB(DWS)提供一个可扩展的数据类型系统,该系统比其它SQL实现更具通用性和灵活性。因而,GaussDB(DWS)中大多数类型转换是由通用规则来管理的,这种做法允许使用混合类型的表达式。
GaussDB(DWS)扫描/分析器只将词法元素分解成五个基本种类:整数、浮点数、字符串、标识符和关键字。大多数非数字类型首先表现为字符串。SQL语言的定义允许将常量字符串声明为具体的类型。例,下面查询:
1 2 3 4 5 |
SELECT text 'Origin' AS "label", point '(0,0)' AS "value";
label | value
--------+-------
Origin | (0,0)
(1 row)
|
示例中有两个文本常量,类型分别为text和point。如果没有为字符串文本声明类型,则该文本首先被定义成一个unknown类型。
在GaussDB(DWS)分析器里,有四种基本的SQL结构需要独立的类型转换规则:
- 函数调用
多数SQL类型系统是建筑在一套丰富的函数上的。函数调用可以有一个或多个参数。因为SQL允许函数重载,所以不能通过函数名直接找到要调用的函数,分析器必须根据函数提供的参数类型选择正确的函数。
- 操作符
SQL允许在表达式上使用前缀或后缀(单目)操作符,也允许表达式内部使用双目操作符(两个参数)。像函数一样,操作符也可以被重载,因此操作符的选择也和函数一样取决于参数类型。
- 值存储
- UNION,CASE和相关构造
因为联合SELECT语句中的所有查询结果必须在一列里显示出来,所以每个SELECT子句中的元素类型必须相互匹配并转换成一个统一类型。类似地,一个CASE构造的结果表达式必须转换成统一的类型,这样整个case表达式会有一个统一的输出类型。同样的要求也存在于ARRAY构造以及GREATEST和LEAST函数中。
系统表pg_cast存储了有关数据类型之间的转换关系以及如何执行这些转换的信息。详细信息请参见PG_CAST。
语义分析阶段会决定表达式的返回值类型并选择适当的转换行为。数据类型的基本类型分类,包括:boolean,numeric,string,bitstring,datetime,timespan,geometric和network。每种类型都有一种或多种首选类型用于解决类型选择的问题。根据首选类型和可用的隐含转换,就可能保证有歧义的表达式(那些有多个候选解析方案的)得到有效的方式解决。
所有类型转换规则都是建立在下面几个基本原则上的:
- 隐含转换决不能有奇怪的或不可预见的输出。
- 如果一个查询不需要隐含的类型转换,分析器和执行器不应该进行更多的额外操作。这就是说,任何一个类型匹配、格式清晰的查询不应该在分析器里耗费更多的时间,也不应该向查询中引入任何不必要的隐含类型转换调用。
- 另外,如果一个查询在调用某个函数时需要进行隐式转换,当用户定义了一个有正确参数的函数后,解释器应该选择使用新函数。
TD兼容模式下,空串转换为数值类型的处理
- TD数据库不同于Oracle,Oracle将空串当做NULL进行处理,TD在将空串转换为数值类型的时候,默认将空串转换为0进行处理,因此查询空串会查询到数值为0的数据。同样地,在TD兼容模式下,字符串转换数值的过程中,也会将空串默认转换为相应数值类型的0值进行处理。除此之外,' - '、' + '、' '这些字符串也都会在TD兼容模式下默认转换为0进行处理,但是小数点字符串' . '会报错。例如:
1 2 3 4 5 6 7 8 9 10 11 12 13
create table t1(no int,col varchar); insert into t1 values(1,''); insert into t1 values(2,null); select * from t1 where col is null; no | col ----+----- 2 | (1 row) select * from t1 where col=''; no | col ----+----- 1 | (1 row)
- MySQL兼容模式下对空串转换为数值类型的处理和TD兼容模式相同。