GaussDB(DWS) TD和Oracle兼容模式的差异

举报
SELECT * FROM SQL 发表于 2020/06/19 15:17:03 2020/06/19
【摘要】 GaussDB(DWS) TD和Oracle两种兼容模式的差异,以及对每种差异做了举例说明。

GaussDB(DWS)支持两种兼容模式,即TD(Teradata)兼容模式、ORA(Oracle)兼容模式。可以在CREATE DATABASE时通过指定选项DBCOMPATIBILITY进行选择。语法如下:

--创建兼容TD的数据库
postgres=# CREATE DATABASE td_compatible_db DBCOMPATIBILITY 'TD';
CREATE DATABASE
--创建兼容ORA的数据库
postgres=# CREATE DATABASE ora_compatible_db DBCOMPATIBILITY 'ORA';
CREATE DATABASE
postgres=# SELECT datname,datcompatibility FROM PG_DATABASE WHERE datname LIKE '%compatible_db';
      datname      | datcompatibility 
-------------------+------------------
 td_compatible_db  | TD
 ora_compatible_db | ORA
(2 rows)


两种兼容模式的注意差异对比如下表格所示:

兼容项

TD兼容

ORA兼容

数据类型date

只有年月日

date会转为timestamp,包含年月日时分秒

空串

区分空串和NULL

只有NULL

空串转int

转换为0

NULL

超长字符自动截断

支持(GUC参数td_compatible_truncation打开)

不支持

varchar   + int运

转为numeric + numeric计算

转为bigint   + int计算

casecoalesce表达式

兼容TD行为,支持数字和字符串之间的类型转换,比如coalesce参数输入intvarchar类型,解析成varchar类型

报错


下面对每一个兼容性进行举例说明:

-- 切到TD兼容的库下,创建表并插入数据
postgres=# \c td_compatible_db
td_compatible_db=# CREATE TABLE td_table(a INT,b VARCHAR(5),c date);
NOTICE:  The 'DISTRIBUTE BY' clause is not specified. Using 'a' as the distribution column by default.
HINT:  Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column.
CREATE TABLE
td_compatible_db=# INSERT INTO td_table VALUES(1,null,CURRENT_DATE);   
INSERT 0 1
td_compatible_db=# INSERT INTO td_table VALUES(2,'',CURRENT_DATE);  
INSERT 0 1

-- 区分空串和NULL,date类型只显示年月日

td_compatible_db=# SELECT a, b, b IS NULL AS null, c FROM td_table;
 a | b | null |     c      
---+---+------+------------
 1 |   | t    | 2020-06-19
 2 |   | f    | 2020-06-19
(2 rows)
td_compatible_db=# SELECT CURRENT_DATE;
    date    
------------
 2020-06-19
(1 row)


-- 空串转int,转为0。

TD数据库不同于Oracle,Oracle将空串当做NULL进行处理,TD在将空串转换为数值类型的时候,默认将空串转换为0进行处理,因此查询空串会查询到数值为0的数据。同样地,在TD兼容模式下,字符串转换数值的过程中,也会将空串默认转换为相应数值类型的0值进行处理。除此之外,' - '、' + '、' '这些字符串也都会在TD兼容模式下默认转换为0进行处理,但是小数点字符串' . '会报错

td_compatible_db=# SELECT b::int FROM td_table WHERE b = '';   
 b 
---
 0
(1 row)


--超长字符自动截断。

当连接到TD兼容的数据库时,td_compatible_truncation参数设置为on时,将启用超长字符串自动截断功能,在后续的insert语句中(不包含外表的场景下),对目标表中char和varchar类型的列上插入超长字符串时,系统会自动按照目标表中相应列定义的最大长度对超长字符串进行截断。

td_compatible_db=# SHOW td_compatible_truncation;
 td_compatible_truncation 
--------------------------
 on
(1 row)
td_compatible_db=# INSERT INTO td_table VALUES(3,'12345678',CURRENT_DATE);
INSERT 0 1
td_compatible_db=# SELECT * FROM td_table WHERE a = 3;                    
 a |   b   |     c      
---+-------+------------
 3 | 12345 | 2020-06-19
(1 row)


--varchar   + int运算,转为numeric + numeric计算

td_compatible_db=# EXPLAIN VERBOSE SELECT b + a FROM td_table WHERE a = 3;
                                          QUERY PLAN                                           
-----------------------------------------------------------------------------------------------
 Data Node Scan  (cost=0.00..0.00 rows=0 width=0)
   Output: (((td_table.b)::numeric + (td_table.a)::numeric))
   Node/s: datanode7
   Remote query: SELECT b::numeric + a::numeric AS "?column?" FROM public.td_table WHERE a = 3
(4 rows)


-- case和coalesce表达式。

对于case 和coalesce,在TD 兼容模式下的处理

● 如果所有输入都是相同的类型,并且不是unknown类型,那么解析成这种类型。

● 如果所有输入都是unknown类型则解析成text类型。

● 如果输入字符串(包括unknown,unknown当text来处理)和数字类型,那么解析成字符串类型,如果是其他不同的类型范畴,则报错。

● 如果输入类型是同一个类型范畴,则选择该类型的优先级较高的类型。

● 把所有输入转换为所选的类型。如果从给定的输入到所选的类型没有隐式转换则失败。


示例1:Union中的待定类型解析。这里,unknown类型文本'b'将被解析成text类型。

td_compatible_db=# SELECT text 'a' AS "text" UNION SELECT 'b';
text
------
a
b
(2 rows)

示例2:简单Union中的类型解析。文本1.2的类型为numeric,而且integer类型的1可以隐含地转换为numeric,因此使用这个类型。

td_compatible_db=# SELECT 1.2 AS "numeric" UNION SELECT 1;
numeric
---------
1
1.2
(2 rows)

示例3:转置Union中的类型解析。这里,因为类型real不能被隐含转换成integer,但是integer可以隐含转换成real,那么联合的结果类型将是real。

td_compatible_db=# SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL);
real
------
1
2.2
(2 rows)

示例4:TD模式下,coalesce参数输入int和varchar类型,那么解析成varchar类型。ORA模式下会报错。查看coalesce参数输入int和varchar类型的查询语句的执行计划如下

td_compatible_db=# EXPLAIN VERBOSE select coalesce(a, b) FROM td_table;
                                         QUERY PLAN                                          
---------------------------------------------------------------------------------------------
 Data Node Scan  (cost=0.00..0.00 rows=0 width=0)
   Output: (COALESCE((td_table.a)::character varying, td_table.b))
   Node/s: All datanodes
   Remote query: SELECT COALESCE(a::character varying, b) AS "coalesce" FROM public.td_table
(4 rows)


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。