开发者学堂课程【从0到1数据库内核实战教程:MiniOB select - meta 实现解析】学习笔记,与课程紧密连接,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/1083/detail/17321
MiniOB select - meta 实现解析
内容介绍
一、实现解析
本节课讲解的内容是 MiniOB select - meta 实现解析,本节课相较于上节课所学 drop table 更为简单。 MiniOB select - meta 所在的位置处于词法解析直接跳到分解器的阶段,比上节课所讲的执行阶段还要靠前一点,涉及到的模块略少。此题目可以帮助理解 insert 、 delete 、 select 语法的组织结构,本期的代码实现可以满足。
一、实现解析
Resolver 接收到命令之后,需要进行处理,接收到的是语法解析处理后的结果,将 Query 转换成 stmt , Query 是语法解析后的只有字符串信息,比如某张表只具有表名、字段名,此处会将表名转换成真正的表对象,字段名转换成字段对象,在做处理前需要判断是否合法,例如表名是否具有对应的表。实现并非完善,只实现了三个类型的 resolver ,insert 、delete 、select ,还有一些其他的例如 create table 、 drop table 等等,以上目前还未实现 resolver ,实现 resolver 对于做提前判断的帮助不是很大,在建表时,判断某张表是否已经存在是使用调用来处理。
现在来看 stmt 做转换的逻辑,此处有三种类型。
在介绍 delete 时,与 insert 、 select 有一定的重叠,所以在此处重点讲解 insert 和 select ,观看代码之前猜测它是如何实现的,观察 insert 的结构,如下图是 insert 出现语法解析后的对象,
这是一个 sql 语句, relation _ name 是表名, value _ num 与 values 是后面的两个字段,做正确性校验首先看表是否已经存在,其次判断字段的个数和每个字段的类型与实际表里记录的数据是否对应,字段类型要求完全对应是不太符合实际数据库的做法,实际数据库一般都存在演示转换,此处直接做的是简单的处理。
如下图是所做的是参数合法性校验,
接下来判断表是否已经存在,然后将表上的字段信息拉取出,观察字段个数是否对应,在观察每个字段的类型是否一样,如不一样的就要对其进行错误的提示。
此处不讲解 delete ,因为 delete 与 select 存在很大部分的重叠,并且 select 更加全面、语法也更加复杂。首先观察 select 具有什么元素,
上图中,说明查询了什么字段,什么表以及条件。
通常的 select 语句写法如下图所示,这是单表的查询。
如下图是语法写法中多表的查询,
总结校验的逻辑,首先将表取出判断是否存在,接下来判断查询的字段是否合法、是否在表中存在;如查询字段是 * 时,还需对其做展开,将所有的字段都展开;在查询条件判断时,确定当前只查询了一张表并且字段存在于表上,多张表查询是类似的, t . id > 1条件时需判断左右两边的类型是否需要比较,以上就是所需做的判断。
在 from 语句中收集表名,表名字对应的表收集,同时进行做判断,如不存在则直接返回一个错误。
上图是对字段所做的判断,逻辑稍繁琐。若指定了表名时,字段为 * ,将所有的字段按照表上的顺序展开;字段不为 * ,将对应的字段名取出再判断字段名是否存在。
没有写表名的情况下,要求表的个数为一个,不接受有多个的情况,如多个时必须要求写上表名。
过滤字段, filter 在许多地方都是同功能,
filter 就是如上图定义的, where id =1 and name = “ abc ”,此处就是两个条件并列的。需要校验字段是否存在,若是值则是否合法;若两边都是字段,做类似的判断,判断两个是否可以比较。如果是 id 条件,一系列多个时,对每一个进行做判断; id >1 存在一个比较条件,如下图就是做了比较条件的校验。
如下图是左边和右边的校验,此处都将其抽象成了表达式,表达式的值可以在实际的查询出来每一行数据时,计算出再使用实际值做查询。
对应的表中,若没有提供表名,则取出的为默认的表;若是多张表或指定了表名,可以直接查询到表,随后判断字段是否存在,若不存在则直接返回错误。
总结:如是一个字段,就将其抽象成字段的表达式,此时需查询出具体的数据时才能计算出值;如是逻辑值,此时就需判断出一个值。右边是类似的逻辑判断,如下图,此处漏掉了两边类型是否能做比较的判断。
如下图为例,
做提前校验意义不是非常明显。
本课程没有实际代码实操的过程。