⌘+k ctrl+k
1.1.3 (stable)
Search Shortcut cmd + k | ctrl + k
sqllogictest Introduction

为了测试纯SQL,我们使用了一个扩展版本的SQL逻辑测试套件,该套件是从SQLite采用的。每个测试都是一个独立的文件,位于test/sql目录中。 要运行位于默认test目录之外的测试,请指定--test-dir ,并确保提供的测试文件路径相对于该根目录。

测试描述了一系列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组中执行该测试。例如,如果我们想执行上述测试,我们将运行命令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的语法高亮器。我们还创建了一个支持DuckDB方言的sqllogictests的分支。您可以通过安装原始版本,然后将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来运行测试。