目 录CONTENT

文章目录

【openGauss】openGauss补完计划一之ORACLE兼容函数

DarkAthena
2021-12-28 / 0 评论 / 0 点赞 / 1306 阅读 / 0 字

一、前言

2021年12月23号到2021年12月24号的数据技术嘉年华直播中,不少国产数据库厂商都在说兼容oracle的语法到了百分之多少。我想着,既然都说兼容,那我能不能直接把我之前写的一些奇奇怪怪的功能给移植到这些数据库上去?
稍微研究了一下这些国产数据库,发现很多都是基于mysql或者postgresql。也就是说,理论上,只要某个基于postgresql的数据库做了兼容oracle的相关对象,那么理论上也应该能移植到另一个基于postgresql的数据库上去。
但一个人去对比这么多数据库扣那几百上千个对象的代码,工程量巨大,还不如自己针对某一个数据库,挑几个它缺的写写。
刚好近期有报道,openGauss进入了国家计算机等级考试
重磅消息,openGauss纳入全国计算机等级考试!

所以我开了这个新坑,打算给openGauss写写兼容oracle的sql的函数及过程。

另外,由于不清楚是否有人在做和我同样的事,如果有,为避免重复造轮子,请及时和我联系。

注意,本计划目的为个人学习,不涉及商业行为,可能最后无法100%完成。

二、分析

首先,openGauss官方有提供ORACLE语法的兼容包compat-tools,包含了oracle里有的静态视图及大部分函数,还有几个dbms包。
compat-tools开源地址https://gitee.com/enmotech/compat-tools

所以,我可以参考着这个项目的写法,补上一些我以前有用过但compat-tools里没有的东西。

但是要注意的是,这种兼容包的目的是sql兼容,原理只是使用plsql代码,利用现有pg数据库内自带的函数进行转换,在逻辑上符合oracle输出的结果,是没有底层的专用优化算法的,所以查询效率不一定会快。要效率快,不能仅仅是在plsql层面来模拟逻辑,而应该在数据库进行内置(即全局可用的那种函数,而非仅仅是一个模式下的对象)或者用C函数。刚刚才开始看pg的内容,我暂时还做不到那个层面。

我在本地docker里开了个openGauss,然后打上compat-tools,查询dba_objects中的所有function名称,导出成表格。然后从oracle官网的21c-sql参考文档,把function名称全部复制下来,放到xlsx表格里,用vlookup函数匹配oracle有但openGauss没有的函数。

在比较过程中发现,有些postgresql自带的函数,在dba_objects中查不到,比如cast、least、greast、nullif、nvl等,所以需要剔除了这些函数后再进行比较。一比,发现有两百个函数在openGauss中是缺少的。然后我逐个去看这些函数,

  1. 一堆json和xml的相关处理函数,这些需要统一分析,先排除,
  2. 一堆近似算法的函数,这个属于底层机制,不能在plsql层面上实现,所以也剔除
  3. 有很多oracle内部对象的专用处理函数,这些在openGauss里也用不上
  4. 有很多机器学习的函数,但openGauss里有另一套机制,所以也用不上

经过一系列排除后,得到以下清单

ANY_VALUE
ASCIISTR
BFILENAME
BIN_TO_NUM
COSH
KURTOSIS_POP
KURTOSIS_SAMP
LNNVL
NUMTOYMINTERVAL
RATIO_TO_REPORT
ROUND_TIES_TO_EVEN (number)
SINH
SKEWNESS_POP
SKEWNESS_SAMP
SOUNDEX
STANDARD_HASH
SYSTIMESTAMP
TANH
UNISTR

可以发现,这些函数里有不少是我的系列文章“收集一些较为少见但很有用的SQL函数及写法”中有提到的

这里面有不少函数要全新写逻辑会相当复杂,所以我会先从简单的开始写起。

另外,还有对dbms包的兼容,这个会更麻烦,之后会另起一篇文章进行介绍。

三、计划进度

如果本计划进度有更新,会优先在本文的原文地址先更新

函数名称 功能描述 进度 完成日期
ANY_VALUE 聚合函数,取任意值 完成 20220101
ASCIISTR 获得字符串的ascii码 完成 20211229
BFILENAME 获得操作系统上的一个文件作为对象
BIN_TO_NUM 二进制转数字 完成 20211229
COSH 双曲余弦 完成 20211230
KURTOSIS_POP 总体峰态 完成 20220103
KURTOSIS_SAMP 样本峰态 完成 20220103
LNNVL 避免表达式中有空值导致统计遗漏的一个函数 完成 20220101
NUMTOYMINTERVAL 将数字转换成年月INTERVAL 完成 20211230
RATIO_TO_REPORT 分析函数,取本值占分组的百分比
ROUND_TIES_TO_EVEN (number) 区别于round的另一种四舍五入 完成 20211229
SINH 双曲正弦 完成 20211230
SKEWNESS_POP 总体偏度 完成 20220103
SKEWNESS_SAMP 样本偏度 完成 20220103
SOUNDEX 发音相似 完成 20211230
STANDARD_HASH 标准哈希 完成 20211229
SYSTIMESTAMP 当前时间戳 完成 20211229
TANH 双曲正切 完成 20211230
UNISTR 将unicode编码转换成文字字符串 完成 20211229
以下为相较于第一版的新增部分
BIT_AND_AGG 位与聚合 完成 20211231
BIT_OR_AGG 位或聚合 完成 20211231
BIT_XOR_AGG 位异或聚合 完成 20211231
REMAINDER 取任何数相除的余数(和mod不一样,不会进行floor) 完成 20220102
BITOR 位或 完成 20211231
BITXOR 位异或 完成 20211231

待研究问题

  1. ratio_to_report不是常规的聚合函数,而是开窗函数,需要写c++函数,目前暂不确定是否需要重新编译数据库。2022-01-02,参考源码中avg的聚合及lag的默认值取法,修改最终函数为当前窗口当前值除以汇总image.png但单独编译的时候一堆error,主要不清楚应该去掉哪些依赖,毕竟源码就像个蜘蛛网;如果编译整个数据库这动作又太大了,所以暂时放弃这个函数。
  2. 峰度和偏度,在网上找的公式和oracle计算出来的不一样,暂不清楚公式.2022-01-03凌晨睡不着,在国外网站上搜到一个用excel手动计算偏度的案例,已实测和oracle计算一致
  3. BFILENAME的两个参数,目录和文件名,其中目录这个对象在pg里没有,达不到100%复刻,可以使用pg_read_binary_file这个函数,传入文件全路径达到同样的效果。但需要使用初始化账号,这个可以通过由初始化账号建立使用本账号权限的函数,来实现访问

[SQLErrorCode : 10527][127.0.0.1:54611/ocalhost/127.0.0.1:5432] ERROR: must be initial account to read files

项目代码下载

https://gitee.com/darkathena/opengauss-oracle

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin
博主关闭了所有页面的评论