此实现解析有往届选手提供。具体代码实现已经有所变更,因此仅供参考。
miniob-date 测试解说
本篇文章针对在miniob中增加date字段类型做解析,希望可以帮助参加比赛的同学能够顺利通过。
date测试不会超过2038年2月,不会小于1970年1月1号。注意处理非法的date输入,需要返回FAILURE。
create table t(id int, birthday date);
insert into t values(1, '2020-09-10');
insert into t values(2, '2021-1-2');
select * from t;
注意:所有的字符都是英文。浏览器如果将英文字符转成中文字符,请留意。
当前已经有的字段类型有:INTS/FLOATS/CHARS,这几个字段的内存大小都是4个字节。而题目中要求 date 类型,时间范围在1970年1月1日和2038年2月之间,说明date 字段也可以用4个字段来存储。这个原理可以参考time函数的说明,4个字节存储的时间戳,如果起始时间是1970年1月1日,那么将会在2038年某一天越界,而这一天是在2038年2月之后的。因此 date 字段也可以使用 4 字节
存储。
使用4字节存储的好处还有,可以将4字节数据直接当做一个整数来处理,这样做比较运算时,也可以直接使用整数运算。
date作为一个关键字,可以直接在lex文件中添加。
[Dd][Aa][Tt][Ee] RETURN_TOKEN(DATE);
当然也需要增加token DATE。
对于日期数据,比如"2021-10-25",建议不要在词法解析和语法解析模块中写正则表达式来解析,因为它本身就是一个字符串。如果写正则表达式来解析,那就不能再将它作为普通字符串来处理,另外,正则表达式规则将会非常复杂,难以维护和扩展。比如我想让日期支持更多的格式:"2021/10/25","2021年10月25日";对与普通的字符串字段,理论上是能够接收"2021-10-25",这样的字符串作为参数去更新或插入的,如果在词法/语法解析中处理,那还需要处理使用日期更新字符串字段的场景。
需要判断类型为日期的地方,都需要按照一定格式去解析日期。当前输入格式年月日是按照'-'来分隔的,这样就非常简单了。将字符串分割为3个字符串,然后分别当成数字解析就可以。
用字符串表示日期是有合法性要求的。比如2021-02-30,就不能算是正确的日期。
可能出现日期的地方有(不一定全面):
-
插入数据的值;
-
更新数据的值;
-
比较条件中的日期;
考虑再周全一点,可以支持一下聚合函数中有date数据类型。
建表需要支持date类型字段
当前Miniob默认支持了B+-Tree索引,需要对这个索引做扩展。
查询条件中可能有日期,查询可能是通过索引查询,也可能只是普通的查询。
注意按照题目提示来输出 "YYYY-mm-dd",位数不够,需要用'0'填充。