⌘+k ctrl+k
1.3 (稳定版)
搜索快捷键 cmd + k | ctrl + k
结果验证

验证查询结果的标准方法是使用 query 语句,后面跟着字母 I 乘以结果中预期的列数。查询之后,预期是四个破折号 (----),然后是使用制表符分隔的结果值。例如,

query II
SELECT 42, 84 UNION ALL SELECT 10, 20;
----
42	84
10	20

出于历史原因,字母 RT 也可用于表示列。

已弃用 DuckDB 已弃用在 sqllogictest 中使用类型。DuckDB 测试运行器内部不使用或不需要它们——因此,只能使用 I 来表示列。

NULL 值和空字符串

空行对 SQLLogic 测试运行器具有特殊意义:它们表示当前语句或查询的结束。因此,空字符串和 NULL 值在结果验证中必须使用特殊语法。NULL 值应使用字符串 NULL,空字符串应使用字符串 (empty),例如:

query II
SELECT NULL, ''
----
NULL
(empty)

错误验证

为了表示预期会发生错误,可以使用 statement error 指示符。statement error 还接受一个可选的预期结果——这被解释为预期错误消息。与 query 类似,预期错误应放在查询后面的四个破折号 (----) 之后。如果错误消息包含 statement error 下方的文本,则测试通过——无需提供整个错误消息。建议您只使用错误消息的一部分,这样即使错误消息的格式发生更改,测试也不会不必要地中断。

statement error
SELECT * FROM non_existent_table;
----
Table with name non_existent_table does not exist!

正则表达式

在某些情况下,结果值可能非常大或复杂,而我们可能只关心结果是否包含某段文本。在这种情况下,我们可以使用 <REGEX>: 修饰符,后面跟着特定的正则表达式。如果结果值匹配正则表达式,则测试通过。这主要用于查询计划分析。

query II
EXPLAIN SELECT tbl.a FROM 'data/parquet-testing/arrow/alltypes_plain.parquet' tbl(a) WHERE a = 1 OR a = 2
----
physical_plan	<REGEX>:.*PARQUET_SCAN.*Filters: a=1 OR a=2.*

如果我们想让结果包含某段文本,则可以使用 <!REGEX>: 修饰符。

文件

由于结果可能变得非常大,并且我们可能希望在多个文件中重复使用结果,因此也可以使用 <FILE> 命令从文件中读取预期结果。预期结果将从给定文件中读取。按照惯例,文件路径应相对于 GitHub 仓库的根目录提供。

query I
PRAGMA tpch(1)
----
<FILE>:extension/tpch/dbgen/answers/sf1/q01.csv

按行排序与按值排序的结果顺序

查询的结果值可以按行顺序提供,其中各个值用制表符分隔;也可以按值顺序提供。在按值顺序中,查询的单个必须按行、列顺序显示,每个值占一行。考虑以下按行和按值顺序的示例:

# row-wise
query II
SELECT 42, 84 UNION ALL SELECT 10, 20;
----
42	84
10	20

# value-wise
query II
SELECT 42, 84 UNION ALL SELECT 10, 20;
----
42
84
10
20

哈希和输出值

除了直接结果验证,sqllogic 测试套件还提供了使用 MD5 哈希进行值比较的选项。使用哈希进行结果验证的测试示例如下:

query I
SELECT g, string_agg(x,',') FROM strings GROUP BY g
----
200 values hashing to b8126ea73f21372cdb3f2dc483106a12

当结果有许多输出行时,此方法有助于减小测试文件的大小。但是,应谨慎使用,因为哈希值会使测试在出现问题时更难调试。

确保系统输出正确结果后,可以通过向测试文件添加 mode output_hash 来计算测试文件中查询的哈希值。例如:

mode output_hash

query II
SELECT 42, 84 UNION ALL SELECT 10, 20;
----
42	84
10	20

测试文件中每个查询的预期输出哈希值将打印到终端,如下所示:

================================================================================
SQL Query
SELECT 42, 84 UNION ALL SELECT 10, 20;
================================================================================
4 values hashing to 498c69da8f30c24da3bd5b322a2fd455
================================================================================

同样,可以使用 mode output_result 来强制程序将测试文件中运行的每个查询的结果打印到终端。

结果排序

查询可以有一个可选字段,指示结果应以特定方式排序。此字段的位置与连接标签相同。因此,连接标签和结果排序不能混合使用。

此字段的可能值为 nosortrowsortvaluesort。以下是其使用示例:

query I rowsort
SELECT 'world' UNION ALL SELECT 'hello'
----
hello
world

通常,我们倾向于不使用此字段,而是依赖查询中的 ORDER BY 来生成确定性的查询结果。然而,现有的 sqllogictest 广泛使用此字段,因此了解其存在很重要。

查询标签

可用于结果验证的另一个特性是 query labels(查询标签)。它们可用于验证不同查询是否提供相同的结果。这对于比较逻辑上等价但表述不同的查询很有用。查询标签在连接标签或排序指定符之后提供。

带有查询标签的查询无需提供结果。相反,具有相同标签的每个查询的结果将相互比较。例如,以下脚本验证查询 SELECT 42+1SELECT 44-1 提供相同的结果:

query I nosort r43
SELECT 42+1;
----

query I nosort r43
SELECT 44-1;
----