⌘+k ctrl+k
1.3 (稳定版)
搜索快捷键 cmd + k | ctrl + k
sqllogictest 介绍

对于测试纯 SQL,我们使用 SQL 逻辑测试套件的扩展版本,该版本改编自 SQLite。每个测试都是一个独立的自包含文件,位于 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(由制表符分隔)。有关查询结果验证的更多信息,请参阅结果验证部分

每个文件的顶部应包含描述测试名称和分组的注释。测试的名称始终是文件的相对文件路径。分组是文件所在的文件夹。测试的名称和分组非常重要,因为它们可以用于在单元测试组中执行该测试。例如,如果我们要执行上述测试,我们将运行命令 unittest test/sql/projection/test_simple_projection.test。如果我们要运行特定目录中的所有测试,我们将运行命令 unittest "[projection]"

任何放置在 test 目录中的测试都会自动添加到测试套件中。请注意,测试的扩展名很重要。sqllogictests 应该使用 .test 扩展名或 .test_slow 扩展名。.test_slow 扩展名表示测试运行时间较长,并且只有在使用 unittest * 显式运行所有测试时才会运行。扩展名为 .test 的测试将包含在快速测试集中。

查询验证

许多简单的测试通过启用查询验证开始。这可以通过以下 PRAGMA 语句完成

statement ok
PRAGMA enable_verification

查询验证执行额外的验证,以确保底层代码正确运行。其中最重要的一部分是验证优化器不会导致查询中的错误。它通过运行查询的未优化版本和优化版本,并验证这些查询的结果是否相同来实现这一点。

查询验证非常有用,因为它不仅能发现优化器中的错误,还能发现例如连接实现中的错误。这是因为未优化版本通常会使用交叉乘积运行。因此,在处理大型数据集时,查询验证可能会非常慢。因此,建议对所有单元测试开启查询验证,除了那些涉及大型数据集(超过约 10-100 行)的测试。

编辑器与语法高亮

sqllogictests 并非严格意义上的行业标准,但其他几个系统也采用了它们。解析 sqllogictests 的过程有意保持简单。所有语句都必须用空行分隔。因此,编写语法高亮工具并非极其困难。

存在一个适用于 Visual Studio Code 的语法高亮工具。我们还创建了一个支持 sqllogictests 的 DuckDB 方言的分支。您可以通过安装原始版本,然后将 syntaxes/sqllogictest.tmLanguage.json 复制到已安装的扩展中来使用该分支(在 macOS 上,它位于 ~/.vscode/extensions/benesch.sqllogictest-0.1.1)。

还有一个适用于 CLion 的语法高亮工具。您可以通过在市场上搜索 SQLTest 直接在 IDE 上安装它。一个 GitHub 仓库也可用,欢迎提供扩展和错误报告。

临时文件

对于某些测试(例如,CSV/Parquet 文件格式测试),需要创建临时文件。任何临时文件都应在临时测试目录中创建。通过在查询中放置字符串 __TEST_DIR__ 可以使用此目录。此字符串将被替换为临时测试目录的路径。

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

需求与扩展

为避免核心系统臃肿,DuckDB 的某些功能仅作为扩展提供。可以通过在测试中添加 require 字段来为这些扩展构建测试。如果未加载扩展,require 字段之后出现的任何语句都将被跳过。例如 require parquetrequire icu

另一种用法是将测试限制为特定的向量大小。例如,在测试中添加 require vector_size 512 将阻止该测试运行,除非向量大小大于或等于 512。这很有用,因为某些功能不支持低向量大小,但我们在 CI 中使用向量大小为 2 的测试运行。