luooofan / miniob-2022 Goto Github PK
View Code? Open in Web Editor NEWhttps://open.oceanbase.com/competition/index
License: Other
https://open.oceanbase.com/competition/index
License: Other
base on: 3130db6
desc:
original order
we reordered as below
base on: e3d383a
desc:
4. SELECT * AND A EXISTENT COLUMN
select *, age from Select_meta;
-ID | AGE | AGE
+FAILURE
base on: 6d7e170
找一些文档看,还有官方的赛前培训
可以做去年的题目,我们开始之前把2021年的题目做了80分
首先要为后续的开发、测试、版本管理构建一些基础模块,比如说编译安装以及测试的 shell 脚本、代码格式化(clang-format)、代码静态检查(clang-tidy)、Gitee 和 Github 的 Issue 和 PR 模板、Github 的 workflow 等等
涉及到的几个提交如下:
clang-format 和 clang-tidy 模块源自bustub/build_support at master · cmu-db/bustub,我们在此基础上禁用了一些 check,并且限制了被检查的目录
这两个工具除了规范编程以外,也有很实际的好处:
e35aeb5 (这个其实没啥用)
主要就三个原则:
rebase 主要是为了让提交历史更清晰,尽可能地线性化
在公布了今年的赛题后,首先有80分的题目我们已经做了:basic、select-meta、drop-table、update、date、select-tables、insert、order-by,虽然有些需要做修改,还有一个改动略大,但起码大体上没啥问题。对于这80分的题目我们基本上是把对应的提交直接 rebase 到了今年的开发分支上,然后做修改提测
然后我们发现对于 update、insert、show-index、multi-index、unique、clog 这几个赛题是一条线上的,这条线交给成林 @Zhang-X0 来做,我只了解一部分,一起调了调 bug,这几个赛题后面就不说了
剩下的由我和琨琨 @yang-jun-kun 做,这部分赛题思路我都熟,以下都会提到
具体的实现可以找对应的 PR 看
先看 create table 和 create index 的流程,在 drop table 的时候要处理好各种资源
有一个要注意的地方是 disk buffer pool 的析构,会在 close file 的时候把自己释放掉,但是 buffer pool manager 中还有信息未删除,会导致问题
先把类型转换的函数单独实现,存一个函数指针的二维数组 cast_to
然后考虑要在哪里用这个模块就行
另外,在 do_predicate 的时候比较的规则是:
总结来说就是不考虑 date,先处理 null,其他情况都先转成 float
Tuple 是算子执行阶段中非常好的一层抽象:
miniob-2022/src/observer/sql/expr/tuple.h
Lines 75 to 96 in 6d7e170
利用好 Tuple 这个抽象,构造一个 CompoundTuple(一开始叫 JoinedTuple)
最初的实现:
后来因为在实现 OrderBy 的时候必须缓存表数据,所以把这里也改成了缓存右表数据:
并且考虑到 JoinOperator 的孩子可能是其他类型的算子(尤其是考虑到 ProjectOperator 这种特殊类型,必须用 ProjectTuple 才能得到正确的信息,虽然今年的赛题里没有这种情况):
实现 InnerJoinOn 的时候,一开始偷懒做的方案是把 on filter 作为 where filter,等所有的表笛卡尔连接后再统一做 filter,结果超时了
最后的方案是在构造 JoinOperator 的时候尽可能地把 filter 推下去,给 JoinOperator 集成了过滤功能
最终,JoinOperator 的 next 流程为:
发现了官方的彩蛋(或者说卡了一个 bug)
直接看 commit msg: 8abfe5a
到这里为止,第一页的基本都做完了,分析后面的赛题的时候发现存在一个 null 测例,其前后的一些测例都要把 null 考虑进去
另外还发现 aggr-func 赛题排在很前面,group-by 赛题排在很后面,但是我觉得这两个应该一起做,仔细考虑之后,重排了一下做题顺序,具体安排见 #14
在语法分析阶段根据优先级构造成树的形式,resolve 阶段保留树的结构,执行阶段后序遍历执行
在语法阶段增加了 UnaryExpr、BinaryExpr、Expr,在 resolve 阶段给 Expression 扩充了 BinaryExpression,具体的运算则是对 TupleCell 做扩展
对表达式的扩充,语法阶段增加了 FuncExpr,对应到 resolve 后的 FuncExpression
重排做题顺序主要是为了把这两一起实现 #14
这块新增了 GroupByUnit GroupByStmt GroupByOperator GroupByTuple,以及 AggrFuncExpr(esssion)
实现的关键在于 GroupByTuple,也是利用了 Tuple 这个抽象
其他的几个点:
具体实现看 #15 过了两周才写这里,忘了不少,但最关键的部分已经写了
关键思路:在 Record 中给每个 nullable 的字段加一个 null 标志
实现上,为了简单,给所有字段都加这个标记,具体来说有两种方案:
我们选择了第二种做法,这样也方便了索引对 null 的支持,把 bitmap 作为 key 的一部分,然后扩展 key compactor 就行
子查询首先要考虑如何区分父子查询的 where 谓词条件、join 谓词条件、投影列、order-by 表达式、group-by 表达式、having 谓词条件等,我们的方案是用涉及到的这些归约节点存一个 length 信息
像这样
miniob-2022/src/observer/sql/parser/yacc_sql.y
Lines 921 to 936 in 54b4154
对于 In 和 Exists 子查询其实也是给表达式做扩充,增加了 ListExpr(ession) 和 SubQueryExpr(ession)
do predicate 的时候:
对于父子查询表关联,我们给每个 Operator 增加了一个 parent tuple,do predicate 的时候把 parent tuple 和子算子的 tuple 拼成一个 CompoundTuple 传下去
最后对于复杂子查询留了一个 and 和 or 条件支持:
给每个表达式存一个别名就行
有了前面子查询的基础,这里语法阶段只需要把 updates 中原来的 values 拓展成 exprs 即可,在 resolve 阶段生成对应的 Expression,执行阶段(UpdateOperator Open)先 get_value 拿到 TupleCell,根据 TupleCell 构造 Value,以适配 table update_record 的接口
basic 挂了:钉钉群里问的镜水老师,说是重启失败了,我们在本地也复现了
本地能过测例,提交后因为段错误 core 了:
此外还可以利用评测系统二分找 bug:
可以看看 alias-debug 和 unique-debug 这两个分支的最后几次提交
编码上主要是内存管理没太做好,第一周还注意着,第二周就不太行了
项目管理上还有不少问题:
在满分之前没好好做文档和问题记录,想着之后补起来,但由于时间原因又隔了一个礼拜,等初赛结束的时候才勉强把这篇总结写完。当时的一些细节好多已经忘了,初赛过程中一些零散的记录也不愿再整理了,之后会和这个总结一起放到 wiki 里保存。就先这样吧
base on: bdb2cdb
desc:
two bugs in primary-drop-table
base on: original unique impl
diff result:
ID1 | ID2 | COL1 | COL2
3. UPDATE-SELECT
UPDATE unique_table2 SET id1=1,id2=4 where id2=2;
-SUCCESS
+FAILURE RECORD_RECORD_NOT_EXIST
SELECT * FROM unique_table2;
1 | 1 | 1 | 1
-1 | 4 | 1 | 1
+2 | 2 | 1 | 1
2 | 3 | 1 | 1
reproduce:
create table t2(c1 int, c2 int, c3 int);
create unique index i2 on t2(c1,c2);
insert into t2 values(1,2,3);
insert into t2 values(1,2,4); -- should fail ①
insert into t2 values(1,3,3);
select * from t2;
update t2 set c1=2,c2=3 where c2=2; -- should success **reproduce here**
select * from t2;
insert into t2 values(1,1,1),(1,3,4); -- should fail
select * from t2;
reason:
at ①:at first, insert record successly, but failed to insert indexes, so delete indexes entrys
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.