跳到主要内容

sqllogictest 简介

对于纯 SQL 测试,我们使用从 SQLite 引入并扩展的 SQL logic 测试套件。每个测试都是 test/sql 目录中的单文件自包含脚本。 若要运行默认 test 目录外的测试,请指定 --test-dir <root_directory>,并确保传入测试文件路径相对于该根目录。

测试文件描述一系列 SQL 语句,并配套期望结果、statement ok 标记或 statement error 标记。示例如下:

# name: test/sql/projection/test_simple_projection.test
# group [projection]

# enable query verification
statement ok
PRAGMA enable_verification

# create table
statement ok
CREATE TABLE a (i INTEGER, j INTEGER);

# insertion: 1 affected row
statement ok
INSERT INTO a VALUES (42, 84);

query II
SELECT * FROM a;
----
42 84

在该示例中,共执行三条语句。前两条期望成功(以 statement ok 开头)。第三条期望返回一行两列(由 query II 指示),值为 4284(以制表符分隔)。关于结果校验的更多信息见result verification

每个文件顶部都应包含描述测试名称与分组的注释。测试名称必须是该文件的相对路径,分组通常是文件所在目录。名称和分组很重要,因为可用于在 unittest 中仅执行该测试。例如,只运行上面的测试可执行 unittest test/sql/projection/test_simple_projection.test;运行某目录全部测试可执行 unittest "[projection]"

放在 test 目录下的测试会自动加入测试套件。注意测试文件扩展名有语义:sqllogictest 应使用 .test.test_slow.test_slow 表示测试较慢,仅在显式运行全部测试(unittest *)时执行;.test 会进入快速测试集。

Query Verification

许多简单测试会先启用 query verification,可通过以下 PRAGMA

statement ok
PRAGMA enable_verification

query verification 会执行额外校验,确保底层代码行为正确。最重要的是它会验证优化器不会引入错误:通过分别运行未优化版和优化版查询,并比较两者结果是否一致。

query verification 非常有用,不仅能发现优化器问题,也能发现如 join 实现等错误。原因是未优化版本通常会退化为 cross product 执行。也因此在大数据集上它可能非常慢。建议除大数据集测试(约超过 10-100 行)外,其他单测都开启 query verification。

编辑器与语法高亮

sqllogictest 虽非行业标准,但已被多个系统采用。其语法解析被刻意设计得简单:所有语句必须由空行分隔,因此编写语法高亮并不困难。

Visual Studio Code 已有语法高亮。我们也提供了支持 Goose 方言的 fork:vscode-sqllogictest。使用方式是先安装原扩展,再将 syntaxes/sqllogictest.tmLanguage.json 复制到安装目录(macOS 示例路径:~/.vscode/extensions/benesch.sqllogictest-0.1.1)。

CLion 也有语法高亮插件,可在 IDE Marketplace 搜索 SQLTest 直接安装。另有 GitHub 仓库,欢迎提交扩展和问题反馈。

临时文件

某些测试(如 CSV/Parquet 文件格式测试)需要创建临时文件。所有临时文件都应放在测试临时目录中。可在查询中使用 __TEST_DIR__ 占位符,运行时会替换为临时目录路径。

statement ok
COPY csv_data TO '__TEST_DIR__/output_file.csv.gz' (COMPRESSION gzip);

Require 与扩展

为避免核心系统膨胀,Goose 部分功能仅以扩展形式提供。测试可通过添加 require 字段声明依赖扩展。若扩展未加载,require 之后的语句会被跳过。常见示例:require parquetrequire icu

另一个用途是限制测试所需的 vector size。例如加上 require vector_size 512 后,只有在 vector size >= 512 时才会运行该测试。这很有用,因为某些功能在低 vector size 下不支持,而我们的 CI 里会以 vector size=2 运行部分测试。