KWDB 语法添加指南

作者:WY
原文链接:https://www.kaiwudb.com/blog/717.html
一、前言
1.1 KWDB 简介
KWDB 是开放原子开源基金会孵化及运营的面向 AIoT 物联网场景的分布式多模数据库项目,并且支持原生 AI 的数据库产品,拥有“就地计算”核心技术,具备千万级设备接入、百万级数据秒级写入、亿级数据秒级读取等数据高效处理能力。
为了便于用户可以快速上手开发 KWDB 项目,本文将指导用户如何动手开发一条新的 SQL 语句,以较为简单直观的 DDL 语句为例,介绍从 sql 语句的解析、编译到执行的整体流程,以及要添加的关键部分,为用户后续开发提供一定的帮助。
1.2 SQL 执行引擎简介
首先对于 KWDB 的 sql 语句执行引擎来说,可以简单分为以下几个部分:
parser 解析器,进行词法解析和语法解析,将输入的 sql 解析成 AST(抽象语法树)。
compile 编译器,进行语义解析和计划构建。
optimize 优化器,对计划进行优化。
exec执行器,执行计划。

1.3 添加语法简介
本篇文章以兼容 MySQL 语法 create event 为例,简单介绍一下在 KWDB 中如何去添加一个新的 ddl 语法。DDL 相对于 DML 语句不需要进行优化,分布式执行,执行流程和添加语法都要相对简单很多,只涉及到上图中的解析器、编译器、执行器部分。
二、语法解析修改
2.1 yacc 文件简介
添加语法的第一步就是修改 sql.y 里面的 yacc 文件,yacc 文件是定义语法规则的一个文件,里面记录了所有的 KWDB 中的关键字和语法规则。语法规则是通过 BNF 的形式进行表示的。它不仅能严格地表示语法规则,而且所描述的语法是与上下文无关的。它具有语法简单,表示明确,便于语法分析和编译的特点。每条规则的左部是一个非终结符,右部是由非终结符和终结符组成的一个符号串。具有相同左部的规则可以共用一个左部,各右部之间以直竖 “|” 隔开。
我们打开 pkg/sql/parser/sql.y 这个文件,这个文件从上到下依次定义的是各种函数,token,statement 类型,运算符(优先级从低到高),以及语法规则。
2.2 yacc 语法添加
yacc 层主要的目的就是将输入的语法定义成 tree 包下面的结构体,这个结构体就是 AST(抽象语法树),参考 MySQL 的 create event 语法,我们首先需要在 sql.y 中定义对应的语法规则。

最上面 %Help 是对语法的一些帮助信息,主要是展示这条语法的一些用法、规则。下面就是对语法的定义,首先它是一条 statement 语句,需要给 create_evevt_stmt 定义成 stmt 类型。

同时它是 DDL 的一条创建语句,可以作为 create_stmt 的子集,添加到 create_stmt 下面。

然后看他的语法部分,本文参考了 MySQL 的语法并进行了简化,对于之前数据库中没有定义过的 token,我们首先要加到 token 定义中,并且加为非保留关键字(可以作为表名列名)或保留关键字(不能作为表名列名)。

event_name 作为一个 name 的定义,同样也需要定义它的类型。

其他没有定义的语法同理。

各种关键字 token 定义好之后,就可以设计结构体的字段了,首先我们需要在 tree 包下面的 pkg/sql/sem/tree/create.go 文件中加上对应的结构体,用于 sql.y 生成对应的结构体。

语法中的第 n 个单词就对应着 $n,将语法中的对应的输入填入到结构体的字段中。最后在下面添加一个语法 error 情况下报错。
CREATE EVENT error // SHOW HELP: CREATE EVENT
这里的 SHOW HELP 就对应着展示对应语法最上面写的 %HELP 帮助信息。
语法添加完成后就可以先进行 make 尝试编译,看看是否有错误并进行修改。
三、语法编译修改
3.1 AST 结构体添加
上面在 yacc 层中介绍说到需要在 tree 包下添加语法对应的结构体,也就是 AST,AST 添加完成后,它需要实现 statement 接口中的所有方法,在 pkg/sql/sem/tree/stmt.go 文件下添加所有要实现的方法。

还需要根据它的语法添加 Format 方法。

3.2 语义解析添加
yacc 生成 AST 后,需要进行语义解析,然后进行执行,在语义解析部分会将 AST 转换成执行对应的 planNode。planNode 执行对应具体的执行逻辑。
添加一个根据 AST 生成 planNode 的方法,并将这个方法添加到 opaque.go 的 buildOpaque 中,在 init 的 statement 中添加 CreateEvent。

CreateEvent 这个方法里面需要进行对应的语义解析,一般会进行判断用户输入的参数是否合法、进行权限校验等,然后生成 planNode 所需要的字段。
四、语法执行修改
首先我们在 pkg/sql/ 下新建 create_event.go 文件。定义 createEventNode,实现 planNode 的接口,结构体里面可以添加执行所需要的相关字段。


在 startExec 方法中就需要添加语法的主体逻辑,本文为了介绍语法的添加并未真正实现该功能。实现了 planNode 的方法后还需要在 walk.go 的 planNodeNames 添加对应的 name。

根据上述所有步骤添加完语法规则、AST、planNode 以及对应的执行方法后就可以进行 make 先检查是否有语法错误或者其他编译问题,没有问题就可以先启动数据库服务测试语法是否有问题。

可以看到成功添加了 CREATE EVENT 语法。
五、总结
本文介绍并顺利添加了 CREATE EVENT 语法,提供了一个快速上手开发 KWDB 语法的方向,同时也展示出了 KWDB 良好的扩展性和易用性,非常适合新手开发者进行开发。同时本文为了展示语法添加,并未添加执行的流程,并且对语法定义进行了简化。如果读者有兴趣可以尝试实现完整的功能,可能涉及到的工作包括对语法的完善、添加 event 系统表、后台定时执行、对 sql 语句的解析执行等,期待各位后续进行完善。
版权声明: 本文为 InfoQ 作者【KaiwuDB】的原创文章。
原文链接:【http://xie.infoq.cn/article/7612b8dc6075d49b2b227626d】。文章转载请联系作者。
评论