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