Materialize项目中的SQL逻辑测试(SQLLogicTest)深度指南
概述
SQL逻辑测试(SQLLogicTest)是Materialize项目中用于验证SQL功能正确性的重要测试框架。本文将深入解析Materialize项目中SQLLogicTest的扩展功能和使用技巧,帮助开发者编写高质量的SQL测试用例。
测试编写规范
函数测试要点
在Materialize中测试新函数时,需要特别注意以下几点:
-
NULL值处理:必须测试两种NULL场景
- 直接NULL输入:
select func(NULL)
- 表中包含NULL的列:
select func(col) from atable
- 直接NULL输入:
-
数值边界测试:对于数值型参数,必须测试:
- 0值情况
- 负数情况
- 特殊值如1、±∞等
类型验证最佳实践
避免使用预期数据类型来验证结果列的数据类型,因为SQLLogicTest会尝试将结果强制转换为预期类型。推荐做法是使用SHOW COLUMNS
命令来验证实际数据类型。
对于布尔值结果,虽然支持转换为T(文本)、B(布尔)和I(整数)三种类型,但建议新测试统一使用T类型。
错误测试方法
Materialize扩展了错误测试语法:
statement error <可选错误信息>
<你的SQL语句>
或
query error <可选错误信息>
<你的查询语句>
区别在于:
query error
仅适用于SELECT、CREATE VIEW和SHOW INDEXES语句statement error
适用于任何类型的语句
主键支持
虽然Materialize本身暂不支持创建带主键的表,但在SQLLogictest中可以声明主键,优化器会考虑这些主键约束。
语法示例:
CREATE TABLE foo (a INT PRIMARY KEY, b INT)
或
CREATE TABLE bar (
a smallint,
b integer,
c char(10),
d char(20),
PRIMARY KEY (a, b)
)
Materialize特有扩展功能
服务器重置
默认情况下,SQLLogicTest会创建一个Materialize实例并运行所有测试。使用reset-server
指令可以创建新的干净实例,特别适用于:
- 涉及对象ID的测试(如EXPLAIN测试)
- 需要访问内省表的测试
simple扩展指令
Materialize扩展了simple
指令,用于执行简单查询(使用pgwire协议),特别适合测试:
- 多语句查询
- 隐式事务
示例:
simple conn=mz_system,user=mz_system
<SQL语句>
支持可选参数:
conn
:指定连接名称(支持多连接测试)user
:指定连接用户multiline
:支持多行输出
copy扩展指令
copy
指令用于测试COPY FROM功能:
copy table path/to/file.csv
等效于执行:
COPY table FROM STDIN
测试模式详解
Materialize支持两种测试模式:
- standard模式:兼容SQLite测试
- cockroach模式:兼容CockroachDB测试
模式差异对比
-
空格处理:
- standard模式:仅列名中的空格作为分隔符
- cockroach模式:除单列外,所有空格都作为分隔符
- 特殊字符:使用␠(U+2420)表示需要保留的空格
-
数值精度处理:
- standard模式:
- Decimal类型:scale=0时显示4位小数,否则显示3位
- Float类型:固定显示3位小数
- cockroach模式:
- 严格遵循Decimal的scale定义
- Float显示完整精度
- standard模式:
-
数值舍入规则:
- standard模式:向下取整
- cockroach模式:四舍五入(中间值向上舍入)
多行文本支持
使用multiline
关键字可以测试包含换行符的文本输出:
query T multiline
select 'hello
world'
----
hello
world
EOF
实用技巧
-
结果重写:使用
--rewrite-results
参数自动更新预期结果bin/sqllogictest -- --rewrite-results <测试文件路径>
-
调试方法:可以通过LLDB或GDB调试测试
bin/sqllogictest --wrapper 'rust-lldb --' -- <测试文件路径>
-
语法高亮:VS Code用户可以使用专门的sqllogictest语法高亮插件
不支持的指令
Materialize的SQLLogicTest会跳过以下不支持的指令:
CREATE UNIQUE INDEX
REINDEX
对于CockroachDB的partialsort
扩展,目前会转换为rowsort
处理。
内部实现参考
如需修改SQLLogicTest相关代码,可参考以下关键部分:
-
测试运行器:处理查询传递和结果处理
- 不应修改结果格式化逻辑(确保兼容性)
- 新数据类型应强制转换为现有结果类型
-
协调器:处理来自PostgreSQL的变更日志
- 关键点:
Plan::CreateTable
和Plan::SendDiffs
- 关键点:
通过本文的详细介绍,开发者可以更有效地为Materialize项目编写SQL逻辑测试,确保SQL功能的正确性和稳定性。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考