Chinaunix首页 | 论坛 | 博客
  • 博客访问: 14658
  • 博文数量: 47
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 480
  • 用 户 组: 普通用户
  • 注册时间: 2022-06-02 10:03
个人简介

AntDB电信级核心交易数据库

文章分类
文章存档

2023年(11)

2022年(36)

我的朋友

分类: 数据库开发技术

2022-09-15 16:11:31

在去'O'大背景下,为了减轻用户去'O'成本以及加快去'O'速度,很多国产数据库厂商都会在数据库产品上做Oracle兼容性适配。AntDB作为一款成熟、稳定的国产数据库,自然也兼容Oracle,并且兼容程度高达95%以上。本文将从Oracle的DECODE函数着手,分析一下AntDB的适配方案。

01

Oracle的DECODE函数简介


  • 语法
图1-1 Oracle的DECODE函数语法


  • 功能
DECODE将expr依次与search比较,如果expr与某个search相等,则返回对应的result,如果没有找到相等的search则返回default。如果没有指定default,则返回NULL。


函数含义相当于:

图1-2 Oracle的DECODE函数语义
  • 示例
示例如下
图1-3  Oracle的DECODE函数使用例

02

AntDB适配方案


Oracle的DECODE函数功能和AntDB的CASE表达式的功能非常相似,而AntDB也确实利用CASE表达式适配了DECODE函数的功能。


AntDB的CASE表达式
  • 语法1

图2-1 AntDB的CASE表达式语法1
  • 功能1
CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是符合条件的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的结果就是ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,则CASE表达式结果为空。


  • 示例1

图2-2 AntDB的CASE表达式使用例1
  • 语法2
图2-3 AntDB的CASE表达式语法2
  • 功能2
第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者空值)。这类似于 C 里的switch语句。
  • 示例2

图2-4 AntDB的CASE表达式使用例2
AntDB利用CASE表达式的语法2,对DECODE函数进行了适配。

03

DECODE函数适配概要


3.1 语法分析阶段
AntDB利用CASE表达式的语法2,对DECODE函数进行了适配,在语法分析时将DECODE函数转换成了CASE表达式。


转换前:


图3-1 语法转换前的DECODE语法

转换后:

图3-2 语法转换后CASE表达式语法


3.2 语义解析阶段


AntDB在对CASE表达式的语义解析阶段,添加了对DECODE函数的一些细节处理。


主要添加了以下2个处理:1. DECODE函数的expr参数与search参数比较时,选择合适的比较类型AntDB的CASE表达式选择了expr参数的类型作为与各个search参数比较时使用的类型。为了与ORACLE的行为一致,AntDB在适配DECODE函数时,选择了第一个search参数的类型作为比较时使用的类型。2. search参数为空字符串时作为NULL处理这个是ORACLE的另一个兼容性适配,这里不做详细说明。

04

DECODE函数适配详细


4.1 语法分析阶段
语法分析时,将DECODE函数转成CASE表达式。详细请参考以下代码。


代码文件:src/backend/parser/ora_gram.y


图4-1 语法规则中的适配

在函数的语法规则里追加了对decode函数的特殊处理(参考上述代码中的第一个if块):


  • 对decode函数的参数个数进行检查
由于decode函数的最后一个参数可以省略,则参数个数至少为3。少于3个参数则报语法错误。


  • 通过reparsedecodefunc函数将decode函数转成CaseExpr
在说明reparsedecodefunc函数的转换处理之前,先了解下CASE表达式相关的结构体。
CASE表达式结构体CaseExpr
图4-2 CaseExpr结构体
CaseExpr结构体成员的说明如下。


- casetypeCASE表达式结果类型,在语义解析时才能知道,语法分析时赋值为InvalidOid。- casecollid排序规则的OID,语法层不做处理。- argCASE关键字后面的参数,即DECODE函数的第一个参数expr。- argsWHEN语句列表。每个WHEN语句包含对应的search和result参数。WHEN语句对应的结构体参考如下。
图4-3 CaseWhen结构体
CaseWhen结构体的成员说明如下。


  • expr
条件表达式。CASE关键字后的参数(expr)与WHEN关键字后的参数(search)是否相等的表达式。
  • result
WHEN语句中search对应的result。
  • location
token的位置信息- defresultELSE关键字后参数,即CASE表达式的默认结果。- isdecode标记是否是ORACLE的DECODE函数。- locationtoken的位置信息
reparse_decode_func函数的转换处理
先看下该函数的代码:


图4-4 reparse_decode_func函数实现
reparsedecodefunc()函数的参数args是DECODE函数的参数列表,该函数的主要处理逻辑如下:


1. 新作成一个CaseExpr节点


2. 利用DECODE函数的参数列表,设置CaseExpr的主要成员casetype语法层赋值为InvalidOid。
  • isdecode
只有ORACLE的DECODE函数才会进reparsedecodefunc(),因此设置为true。
  • arg
设置为DECODE函数的第一个参数expr。
  • args
1) 将DECODE函数的每一对search/result参数作成CaseWhen节点设置CaseWhen主要成员:
  • expr
设置为DECODE函数的search参数。注意:语法层并没有作成DECODE函数的第一个参数与search参数的等号表达式,后面的语义解析阶段会做这件事。search参数为NULL时,利用DECODE函数的第一个参数作成IS_NULL表达式,并赋值给CaseWhen的expr成员。
  • result
设置为search参数对应的result参数。2) 将CaseWhen节点追加到args列表defresult设置为DECODE函数的最后一个参数。


3. 返回CaseExpr节点


4.2 语义解析阶段


AntDB的CASE表达式是通过transformCaseExpr()函数进行解析的。语法分析时ORACLE的DECODE函数被转换成了CASE表达式,因此DECODE函数的语义解析也将通过transformCaseExpr()函数进行解析。
transformCaseExpr函数的主要处理流程(红色部分为DECODE函数适配追加)请参考图4-5。
图4-5  语义解析阶段的处理流程
如图所示,语义解析时,为了与ORACLE的行为一致,AntDB为DECODE函数做了一些细节上的处理。

05

DECODE函数适配详细


经过AntDB适配后的DECODE函数,演示结果如下


图5-1 适配后的结果演示



06

总结


Oracle功能适配时,利用AntDB既有的功能,可能起到事半功倍的效果。当然,熟悉和理解AntDB既有的功能,也是必不可少的技能。DECODE函数的适配只是Oracle兼容性开发的冰山一角,AntDB在Oracle兼容上有着深厚的积累和独特的优势,想要去'O'的同学,可以试试AntDB。

关于AntDB数据库

AntDB数据库始于2008年,在运营商的核心系统上,为全国24个省份的10亿多用户提供在线服务,具备高性能、弹性扩展、高可靠等产品特性,峰值每秒可处理百万笔通信核心交易,保障系统持续稳定运行近十年,并在通信、金融、交通、能源、物联网等行业成功商用落地。





阅读(70) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~