当需要多次执行相同的查询但常量值略有修改时,可以在sqllogictests中使用循环。例如,假设我们想要触发100个查询,检查表中是否存在值0..100
:
# create the table 'integers' with values 0..100
statement ok
CREATE TABLE integers AS SELECT * FROM range(0, 100, 1) t1(i);
# verify individually that all 100 values are there
loop i 0 100
# execute the query, replacing the value
query I
SELECT count(*) FROM integers WHERE i = ${i};
----
1
# end the loop (note that multiple statements can be part of a loop)
endloop
同样地,foreach
可以用来遍历一组值。
foreach partcode millennium century decade year quarter month day hour minute second millisecond microsecond epoch
query III
SELECT i, date_part('${partcode}', i) AS p, date_part(['${partcode}'], i) AS st
FROM intervals
WHERE p <> st['${partcode}'];
----
endloop
foreach
还有一些预设的组合,在需要时应使用这些组合。这样,当新的组合被添加到预设中时,旧的测试将自动获取这些新的组合。
预设 | 扩展 |
---|---|
⟨compression⟩ | none uncompressed rle bitpacking dictionary fsst chimp patas |
⟨signed⟩ | tinyint smallint integer bigint hugeint |
⟨unsigned⟩ | utinyint usmallint uinteger ubigint uhugeint |
⟨integral⟩ | ⟨signed⟩ ⟨unsigned⟩ |
⟨数值⟩ | ⟨整数⟩ 浮点数 双精度 |
⟨alltypes⟩ | ⟨numeric⟩ bool interval varchar json |
谨慎使用大循环。执行数十万条SQL语句会不必要地减慢测试速度。不要使用循环来插入数据。
无循环数据生成
循环应谨慎使用。虽然使用循环通过插入语句插入数据可能很诱人,但这会显著减慢测试用例的速度。相反,最好使用内置的range
和repeat
函数生成数据。
要创建包含值 [0, 1, .., 98, 99]
的表 integers
,请运行:
CREATE TABLE integers AS SELECT * FROM range(0, 100, 1) t1(i);
要创建包含100次值hello
的表strings
,请运行:
CREATE TABLE strings AS SELECT * FROM repeat('hello', 100) t1(s);
使用这两个函数,结合巧妙的交叉积和其他表达式,可以高效生成许多不同类型的数据集。random()
函数也可以用于生成随机数据。
另一种选择是从现有的CSV或Parquet文件中读取数据。可以使用COPY INTO
语句或read_csv_auto
函数从目录test/sql/copy/csv/data/real
加载几个大型CSV文件。
TPC-H 和 TPC-DS 扩展也可以用于生成合成数据,例如使用 CALL dbgen(sf = 1)
或 CALL dsdgen(sf = 1)
。