OceanBase 源码解读(十一):表达式和函数

2024年 5月 7日 66.0k 0

OceanBase 源码解读(十一):表达式和函数-1

本文作者:竹翁(杨志丰),毕业于北京大学, OceanBase 内核研发总监。近十年来一直在阿里巴巴/蚂蚁金服自主研发分布式系统和数据库的从事研发工作。

表达式是 SQL 语句的一部分。例如,where employee = lcase('Chang') or id = 1001 中,where 后是一个值类型为 bool 的表达式,其中 lcase 是一个(系统)函数。

在前面《 OceanBase 源码解读(三)SQL 的一生》中讲过,SQL 语句在生成抽象语法树后,经过 resolver 转换解析为 stmt 逻辑执行计划,其中的一个关键部分是表达式的解析。表达式解析类是位于sql/resolver/expr 的ObRawExprResolver,它输入ObParseNode 树,输出表达式树 ObRawExpr 。这个 ObRawExpr 仅用于优化器阶段的语义分析优化,在生成物理执行计划后会被转换为为执行效率优化的 ObExpr 。

OceanBase 源码解读(十一):表达式和函数-2

上图是表达式解析的主函数。可以看到,抽象语法树结点中用 T_XXX 这样的枚举值表示结点类型。这里有一个比较特别的设计,所有形式为 func(arg1, arg2) 的表达式在 parser 里都被解析为 T_FUN_SYS 类型,函数名存在子结点里,待 resolver 阶段处理。这样,新增一个普通内建函数的时候,我们不需要修改语法文件。不过,这也是为什么有时候相关 SQL 函数不存在的报错与 MySQL , Oracle 的行为不完全一致。从上面代码可以看到,如果内建函数中没找到,还会从用户自定义函数(UDF)中查找。

OceanBase 源码解读(十一):表达式和函数-3

上图是 process_fun_sys_node() 片段,可以看到,在做了几个特殊的函数别名处理之后,最后通过查找ObExprOperatorFactory 类决定一个函数是否存在。(看这个类还能发现外部没有公开文档的一些隐藏函数,比如研发查问题时常用的 usec_to_time:)

OceanBase 源码解读(十一):表达式和函数-4

所有内建函数的实现位于 sql/engine/expr 下,类的接口比较清晰,可以照猫画虎。写好实现类后,如上图,用REG_OP 宏把这个类注册一下,表达式解析和代码生成就能自动识别这个新函数。

好了,本期内容到这里就结束了。

那么本系列第二个练习题来了:请你给 OceanBase 社区版实现一个 MySQL 5.7 新增的系统内建函数吧!(这也是 OceanBase SQL 组很多新人入职第一题:)

(未完待续)

附录:前十篇可参考:

1、OceanBase 数据库源码解读(一)引言

2、OceanBase 数据库源码解读(二)目录结构

3、OceanBase 源码解读(三)SQL 的一生

4、OceanBase 源码解读(四)分区的一生

5、OceanBase 源码解读(五)事务的一生

6、OceanBase 源码解读(六)租户的一生

7、OceanBase源码解读(七)带你看透虚拟表

8、OceanBase源码解读(八)OB高性能执行引擎

9、OceanBase源码解读(九)tableAPI和OB多模型

10、OceanBase 源码解读(十)分布式事务

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论