lightdb Oracle 兼容特性升级
背景
目前,lightdb 在兼容 oracle,目标是 oracle 用户不用修改 sql 代码无缝切换到 lightdb 数据库。为此,lightdb 结合开源 orafce 插件和内核级支持,实现用户的良好体验。在 lightdb 版本 LightDB1.0.V202303.00.000
中,新增了以下功能:
- greatest/least 的内核级兼容
- dbms_utility.get_time
- mod 函数兼容
使用案例
以下使用案例都是在 lightdb_syntax_compatible_type = oracle 的情况下执行的。
greatest/least
lightdb/PostgreSQL 内部是支持 greatest/least 函数(确切说是表达式)的,但它的实现和 oracle 不兼容,本次主要实现了以下兼容特性:
- 只要有一个参数为 NULL 结果就返回 NULL
- 把第一个参数作为被比较的类型,其余参数类型强制转换为第一个参数的类型
- 当遇到一个参数为 NULL 时,不再解析其余参数
ldd=# select greatest(1, null, 2);
greatest
----------
(1 row)
ldd=# select greatest(1, null, 2/0);
greatest
----------
(1 row)
ldd=# select * from foo;
a | b | c
---+---+---
| 2 | 0
1 | 0 | 2
(2 rows)
ldd=# select greatest(a, b, c) from foo;
greatest
----------
2
(2 rows)
ldd=# select * from foo2;
a | b | c
---+---+---
x | 1 | 2
(1 row)
ldd=# select greatest(a, b, c) from foo2;
greatest
----------
x
(1 row)
ldd=#
dbms_utility.get_time
该函数结果为百分之一秒。主要用来统计时间差。
DO $$
DECLARE
start_time integer;
end_time integer;
BEGIN
start_time := DBMS_UTILITY.GET_TIME();
PERFORM pg_sleep(2);
end_time := DBMS_UTILITY.GET_TIME();
-- clamp long runtime on slow build machines to the 2s the testsuite is expecting
IF end_time BETWEEN start_time + 300 AND start_time + 1000 THEN end_time := start_time + 250; END IF;
RAISE NOTICE 'Execution time: % seconds', trunc((end_time - start_time)::numeric/100);
END
$$;
mod
当第二个参数为 0 时,返回第一个参数
lightdb@dbora=# select mod(2, 0);
mod
-----
2
(1 row)