Rewrite sqllogictest framework in rust
Sqllogictest is a program designed to verify that an SQL database engine computes correct results by comparing the results to identical queries from other SQL database engines. Sqllogictest was originally designed to test SQLite[1], but it is database engine neutral and can just as easily be used to test other database products.
在 rust 生态中,https://github.com/risinglightdb/sqllogictest-rs 是一个非常优秀的 sqllogictest 框架实现,得益于此,Databend 才能方便快速的把 sqllogictest 框架从 python 切换到 rust。
背景
由于一些历史原因,Databend 最初的 sqllogictest 框架是 python 版本的,具体可见 https://databend.rs/doc/contributing/rfcs/new_sql_logic_test_framework
出于以下原因,我们决定 Rewrite it in rust
统一 codebase, 全部用 rust, 长期来看可以提高 框架的开发和迭代速度。
sqllogictest-rs[2] crate 逐渐成熟,基于它来构建 Databend 新的 sqllogictest 框架可以节省很多劳动力。
没有严格的 parser 前端,一些错误不能被捕获。
从 python 切换成 rust, 有潜在的性能提升,当前 python 版本的 sqllogictest 运行时间不理想,导致 CI 比较慢,最终结果也比较理想,有约十倍的提升。
现实中遇到的问题
第一版的 sqllogictest 并没有严格按照 sqllogictest wiki[3] 进行实现,所以测试文件的格式需要调整(纯纯的体力活),比如
query and ---- 中间有多余的空行
注释的格式不一样
一些 query 的结果是空的,比如 select '' , 1,就直接用了来展示,在整个测试文件中容易造成困扰,需要用 (empty)来进行显示代替
Databend 支持三种 client handler: mysql, http, clickhouse 具体可见 handlers[4], 每一种协议返回的内容格式是不同的,mysql 比较正常,但是 http 返回 json, clickhouse 返回 tsv。所以需要针对每一种格式进行解析,其中一些特殊符号也需要进行统一,这样才能保证三种协议可以使用同一份测试文件。在 http 和 clickhouse 中,需要做以下一些替换:
inf -> Infinity
nan -> NaN
\\N -> NULL
测试文件之间的隔离。为了可以尽可能的提高并行度(多个测试文件之间可以并行运行),需要对不同的文件进行隔离,防止误用 database 或者 table, 避免 database 或者 table 被错误的 drop, 我们引入了 sandbox tenant,每个 test file 一个独立的沙盒环境,从而文件之间可以并行的运行,大大减少了测试时间。
未解决的问题
如果有效的对查询结果是动态的 query 进行测试?
比如 SHOW TABLE STATUS 结果中会包含 table 的创建时间,这个结果是动态的,如何对这类 sql 进行测试是一个值得讨论的问题。
总结
整体来看,从 python 版本切换到 rust 版本,解决背景中提到的问题,收益还是非常不错的,RIIR 有其合理性!关于 Databend sqllogictest 框架的使用,可参考 README[5]。
未来的一些 todos: sqllogictest tracking[6]。最后也感谢 sqllogictest-rs[7] 的支持!
引用链接
[1]
SQLite: https://www.sqlite.org/index.html
[2]
sqllogictest-rs: https://github.com/risinglightdb/sqllogictest-rs
[3]
sqllogictest wiki: https://www.sqlite.org/sqllogictest/doc/trunk/about.wiki
[4]
handlers: https://databend.rs/doc/reference/api
[5]
README: https://github.com/datafuselabs/databend/blob/main/tests/sqllogictests/README.md
[6]
sqllogictest tracking: https://github.com/datafuselabs/databend/issues/9174
[7]
sqllogictest-rs: https://github.com/risinglightdb/sqllogictest-rs
关于 Databend
Databend 是一款开源、弹性、低成本,基于对象存储也可以做实时分析的新式数仓。期待您的关注,一起探索云原生数仓解决方案,打造新一代开源 Data Cloud。
Databend 文档:https://databend.rs/
Twitter:https://twitter.com/Datafuse_Labs
Slack:https://datafusecloud.slack.com/
Wechat:Databend
GitHub :https://github.com/datafuselabs/databend
评论