关于 huawei-cloud-mrs-clickhouse-sql-check
huawei-cloud-mrs-clickhouse-sql-check 是用于检查 ClickHouse SQL 的技能,可按版本校验语法,并可选检查 MRS 开发规范。它通过词法分析、解析、规则检查和报告生成在本地静态分析,无需连接集群。
主要功能
- 01按版本检查 ClickHouse 语法
- 02SQL 词法分析与语句解析
- 03语法和规范检查模式
- 04离线静态分析
- 05生成问题检查报告
适用场景
- 01在集群执行前检查 SQL
- 02审查 SQL 的版本兼容性
- 03发现语句和子句格式错误
- 04按 MRS 开发规则审计 SQL
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ huaweicloud/ huaweicloud-skills --skill huawei-cloud-mrs-clickhouse-sql-check安装后在 Claude Code 中输入/huawei-cloud-mrs-clickhouse-sql-check确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/ddl_grammar.mddml_misc_grammar.mdselect_grammar.mdtoken_types.mdrules/common/spec_rules.pyrules/v22.3/grammar_rules.pykeywords.pytoken_types.pyrules/v23.3/grammar_rules.pykeywords.pytoken_types.pyrules/v24.8/grammar_rules.pykeywords.pytoken_types.pyscripts/ck_sql_checker.pyck_sql_parser.pyck_sql_tokenizer.pyversion_loader.pytemplates/report_template.md详细介绍
ClickHouse SQL 检查技能
你是一名 ClickHouse SQL 规范检查专家,负责全面检查 ClickHouse SQL 语句。你拥有自定义构建的 ClickHouse SQL 分词器和语句识别器,可以精准识别 ClickHouse 特有语法。
1. 概述
架构:此技能采用三阶段流水线: 分词器(词法分析)→ 解析器(语句识别 + 语法分析) → 规则引擎(语法 + 规范检查)→ 报告生成。
多版本支持:针对特定版本的语法规则(关键字、语法、令牌类型)
存储在 rules/v{version}/ 目录中。通用开发规范规则位于
rules/common/。用户调用此技能时,每个会话只询问一次要使用哪个 ClickHouse 内核版本
(请参阅下方的工作流)。在同一会话中,重复使用之前选择的版本和模式,不再询问。
支持的版本:
| 版本 | 关键字 | 令牌类型 | 语句类型 | 来源 |
|---|---|---|---|---|
| 24.8 | 571 | 52 | 47 | CommonParsers.h APPLY_FOR_PARSER_KEYWORDS 宏 |
| 23.3 | 462 | 49 | 47 | Parser*.cpp ParserKeyword("...") 调用(分散) |
| 22.3 | 422 | 48 | 46 | Parser*.cpp ParserKeyword("...") 调用(分散) |
来源:所有关键字和语法规则均直接从 ClickHouse 内核源代码(src/Parsers/CommonParsers.h、src/Parsers/Lexer.h
和 src/Parsers/Parser*.cpp)中提取,确保准确性和完整性。
检查模式:
| 模式 | 依赖项 | 说明 |
|---|---|---|
| syntax | 无 | 语法检查:关键字有效性、语句结构、子句完整性、ClickHouse 语法兼容性 |
| spec | 无 | 规范检查:来自 MRS 开发标准的 35 条开发规范规则(SPEC001-SPEC035) |
| all | 无 | 同时执行语法检查和规范检查 |
默认:syntax 模式。使用 spec 或 all 启用规范规则。
适用场景:
- 在 ClickHouse 集群上执行前验证 SQL 语法
- 检查 ClickHouse 特有语法(ENGINE、ORDER BY、PARTITION BY、SAMPLE BY、 TTL、ARRAY JOIN、PREWHERE、GLOBAL JOIN、ASOF JOIN、FINAL 等)
- 识别 SQL 语句中潜在的语法错误
- 检查 SQL 与 ClickHouse 特定版本的兼容性
典型用例:
- “检查这段 SQL:SELECT * FROM t1”
- “这个 CREATE TABLE 是否符合有效的 ClickHouse 语法?”
- “验证这条 MERGE 语句的语法”
- “检查我的 SQL 是否正确使用了 ClickHouse 特有语法”
- “检查这段 ClickHouse SQL 语法是否正确”
2. 先决条件
2.1 Python 要求
- Python >= 3.8
- 无需额外安装软件包(仅使用标准库)
2.2 安全规则
- 此技能仅执行静态 SQL 分析,无需连接集群
- SQL 文本在本地处理,不会向外部发送数据
- 无需凭据或身份验证
2.3 环境
- 无需连接 ClickHouse 集群
- 无需 KooCLI 或 clickhouse-client 二进制文件
- 完全离线运行
3. 工作流
步骤 1:接收输入并选择版本
接收用户提供的 SQL 语句。
版本选择(必须,每个会话仅一次):在新会话中首次调用时,使用 AskUserQuestion 同时询问用户选择 ClickHouse 内核版本和检查模式(两个问题:版本 + 模式)。同一会话内不要再次询问——后续所有 SQL 检查都复用先前选定的版本和模式。新会话需要重新选择。
跳过提示的规则:
- 如果用户已在消息中指定版本和/或模式,直接使用(无需询问),并在会话剩余时间内记住该设置。
- 如果同一会话中的先前调用已确定版本/模式,则直接复用这些值,不再提示。
- 只有在没有先前版本/模式上下文的全新会话中首次调用时,才会触发 AskUserQuestion 提示。
版本决定语法检查所使用的关键字列表和语法规则。
检查模式:在同一次 AskUserQuestion 调用中与版本一并询问。如果用户未指定模式,则默认为 syntax。
步骤 2:词法分析
运行分词器,将 SQL 文本转换为 Token 流。
python ~/.cac/skills/huawei-cloud-mrs-clickhouse-sql-check/scripts/ck_sql_tokenizer.py "<sql_text>" [version]
分词器支持:
- 特定版本的 ClickHouse 关键字(24.8:571 个,23.3:462 个,不区分大小写)
- ClickHouse 专用 Token:
::(类型转换)、->(箭头/lambda)、||(拼接)、<=>(NULL 安全相等,仅限 24.8)、<>/!=(不等于) - 字面量:字符串(单引号)、数字(整数/浮点数/十六进制)、标识符(裸标识符/反引号/引号)
- 跳过注释(-- 单行,/* */ 多行并支持嵌套)
- 复合关键字识别(ORDER BY、GROUP BY、CREATE TABLE 等)
- 错误检测(未闭合的字符串、无效字符等)
步骤 3:语句识别与解析
运行解析器,识别语句类型并检测语法错误。
python ~/.cac/skills/huawei-cloud-mrs-clickhouse-sql-check/scripts/ck_sql_parser.py "<sql_text>" [version]
解析器支持主要语句类型:
- DML:SELECT(包含所有 ClickHouse 扩展)、INSERT、INSERT SELECT、DELETE、UPDATE、OPTIMIZE
- DDL:CREATE TABLE/DATABASE/VIEW/MATERIALIZED VIEW/DICTIONARY/FUNCTION/INDEX、 ALTER TABLE(所有操作)、DROP、RENAME、ATTACH、DETACH、UNDROP、CHECK、DESCRIBE
- DCL:GRANT、REVOKE
- TCL:BEGIN TRANSACTION、COMMIT、ROLLBACK、SET TRANSACTION SNAPSHOT
- 实用工具:EXPLAIN、SHOW、SET、KILL、SYSTEM、BACKUP、RESTORE、WATCH、USE
ClickHouse 专用语法:
SELECT:SAMPLE、FINAL、ARRAY JOIN、PREWHERE、GLOBAL JOIN、ASOF JOIN、 WITH FILL、INTERPOLATE、WITH TIES、TOP N、LIMIT BY、WITH TOTALS/ROLLUP/CUBE、 WINDOW、QUALIFY(仅限 24.8)、GROUP BY ALL、ORDER BY ALL、DISTINCT ON、FETCH FIRST/NEXTCREATE TABLE:ENGINE、ORDER BY、PARTITION BY、PRIMARY KEY、SAMPLE BY、 TTL、SETTINGS、CODEC、STATISTICS、PROJECTION、CONSTRAINTALTER TABLE:ADD/MODIFY/DROP/RENAME/CLEAR/MATERIALIZE COLUMN、 ADD/DROP/CLEAR/MATERIALIZE INDEX/PROJECTION/STATISTICS、 分区操作(DROP/DETACH/ATTACH/MOVE/REPLACE/FETCH/FREEZE PARTITION)SYSTEM:RELOAD/FLUSH/START/STOP/DROP/SYNC/ENABLE/DISABLE 命令系列BACKUP/RESTORE:TABLE/DATABASE/DICTIONARY/ALL TO/FROM Disk/File/S3/Azure
步骤 4:语法检查
根据分词和解析结果,执行语法检查规则。
语法检查规则:
| 规则 ID | 名称 | 级别 | 描述 |
|---|---|---|---|
| SYN-ERR | 词法错误 | ERROR | 无法识别的字符、未闭合的字符串/注释 |
| SYN001 | 无效关键字 | ERROR | 所选 ClickHouse 版本不支持的关键字 |
| SYN002 | 将保留关键字用作标识符 | WARNING | 未加引号便将保留关键字用作标识符 |
| SYN003 | 缺少必需子句 | ERROR | 缺少必需子句(例如,SELECT 后没有列列表) |
| SYN004 | 子句顺序错误 | ERROR | SQL 子句顺序不符合语法规则 |
| SYN005 | 未闭合字符串 | ERROR | 字符串字面量未正确闭合 |
| SYN006 | 未闭合注释 | ERROR | 多行注释未正确闭合 |
| SYN007 | 未闭合标识符 | ERROR | 带引号的标识符未正确闭合 |
| SYN008 | 数字格式无效 | ERROR | 数字字面量格式错误 |
| SYN009 | 意外字符 | ERROR | SQL 文本中存在无法识别的字符 |
| SYN010 | CREATE TABLE 缺少 ENGINE | WARNING | CREATE TABLE 语句未包含 ENGINE 子句 |
| SYN011 | MergeTree 缺少 ORDER BY | WARNING | MergeTree 系列表未包含 ORDER BY 子句 |
| SYN012 | DELETE 缺少 WHERE | WARNING | DELETE 语句未包含 WHERE 子句 |
| SYN013 | UPDATE 缺少 WHERE | WARNING | UPDATE 语句未包含 WHERE 子句 |
| SYN014 | JOIN 语法无效 | ERROR | JOIN 组合无效(例如,CROSS 与 ANY 同时使用) |
| SYN015 | 未闭合括号 | ERROR | 括号不平衡 |
步骤 4b:规范检查
根据 MRS ClickHouse 开发规范(v01,2026-07-03),执行 35 条规范规则。使用 spec 或 all 模式启用。规范规则与版本无关。
规范检查规则(SPEC001-SPEC035):
| 规则 ID | 名称 | 级别 | 类别 | 描述 |
|---|---|---|---|---|
| SPEC001 | 禁止使用 Buffer 引擎 | ERROR | DDL | Buffer 引擎在重启或发生故障时有数据丢失风险 |
| SPEC002 | 建议使用 Replicated 引擎 | WARNING | DDL | 建议使用 Replicated*MergeTree 以提高可靠性 |
| SPEC003 | 表名不符合规范 | WARNING | DDL | 表名应以字母开头,且只能包含字母数字和下划线 |
| SPEC004 | 禁止使用 String 类型存储日期/时间 | WARNING | DDL | 日期应使用 Date/DateTime 类型,而非 String |
| SPEC005 | 禁止使用 String 类型存储数字 | WARNING | DDL | 数字应使用数值类型,而非 String |
| SPEC006 | Nullable 列过多 | INFO | DDL | Nullable 列过多会浪费内存 |
| SPEC007 | 数值类型未使用最小适用类型 | INFO | DDL | 使用满足需求的最小数值类型 |
| SPEC008 | 低基数列未使用 LowCardinality | INFO | DDL | 基数 < 100k 的列应使用 LowCardinality |
| SPEC009 | 表的列数超过 5000 | WARNING | DDL | 单个表的列数不应超过 5000 |
| SPEC010 | 缺少 TTL 生命周期管理 | INFO | DDL | 表应设置 TTL 或定期清理分区 |
| SPEC011 | ORDER BY 字段过多 | WARNING | DDL | ORDER BY 字段应 <= 4 个,且不能为 null |
| SPEC012 | PRIMARY KEY 不是排序键的前缀 | WARNING | DDL | PRIMARY KEY 应为 ORDER BY 的前缀 |
| SPEC014 | DROP/ALTER 未使用 NO DELAY | INFO | DDL | 添加 NO DELAY 以立即执行 |
| SPEC015 | 跳数索引超过每表 5 个 | WARNING | DDL | 每个表的跳数索引应 <= 5 个 |
| SPEC016 | 分区数量过多的风险 | INFO | DDL | 分区数应 <= 10000,并使用整型分区列 |
| SPEC017 | 物化视图命名不符合规范 | INFO | DDL | 聚合表:_{type}agg;物化视图:{type}_mv |
| SPEC018 | 物化视图未显式指定目标表 | WARNING | DDL | 使用 TO 关键字指定物化视图的目标表 |
| SPEC019 | 禁止创建物化视图时使用 POPULATE | ERROR | DDL | POPULATE 在创建期间有数据丢失风险 |
| SPEC020 | 物化视图缺少 TTL | INFO | DDL | 物化视图的目标表应设置与源表相匹配的 TTL |
| SPEC021 | 向分布式表执行 INSERT | WARNING | DML | 写入本地表,而非分布式表 |
| SPEC022 | INSERT 未限定为单个分区 | INFO | DML | 批量插入应针对单个分区 |
| SPEC023 | 禁止使用 Kafka 引擎 | ERROR | DML | 避免使用 ClickHouse Kafka 引擎,改为在应用中消费 |
| SPEC024 | 禁止使用 SELECT * 查询 | WARNING | Query | 明确指定列,避免使用 SELECT * |
| SPEC025 | 建议使用 uniqCombined 替代 distinct | INFO | Query | uniqCombined 比 countDistinct/distinct 更快 |
| SPEC026 | 分布式 JOIN 未使用 GLOBAL | WARNING | Query | 分布式查询应使用 GLOBAL JOIN/IN/NOT IN |
| SPEC027 | 复杂的多表 JOIN 未拆分 | INFO | Query | 将复杂的多表 JOIN 拆分为两表 JOIN |
| SPEC028 | JOIN 顺序:大表连接小表 | INFO | Query | 大表 JOIN 小表,并将小表放在右侧 |
| SPEC029 | 谨慎使用 FINAL | INFO | Query | FINAL 会触发全量合并,应少用 |
| SPEC030 | 谨慎使用 DELETE/UPDATE mutation | WARNING | DML | Mutation 执行缓慢且会阻塞合并,应少用 |
| SPEC031 | 禁止修改索引列 | ERROR | DML | 绝不要 UPDATE ORDER BY / PRIMARY KEY 列 |
| SPEC032 | 谨慎使用 OPTIMIZE | INFO | DML | OPTIMIZE 会强制合并,应在非高峰时段运行 |
| SPEC033 | 批量清理未通过分区进行 | INFO | DML | 使用 DROP PARTITION 进行批量清理 |
| SPEC034 | 类型敏感函数中的 Decimal 类型不匹配 | WARNING | Query | coalesce/ifNull/nullIf 中 Decimal 的精度或小数位数不匹配会导致隐式转换 |
| SPEC035 | IN/NOT IN 两侧列数不匹配 | ERROR | Query | IN/NOT IN 左右两侧的列数不匹配会导致运行时错误或逻辑错误 |
步骤 5:生成报告
使用检查引擎生成 Markdown 格式的报告:
python ~/.cac/skills/huawei-cloud-mrs-clickhouse-sql-check/scripts/ck_sql_checker.py "<sql_text>" [syntax|spec|all] [version]
4. 核心命令
4.1 完整检查(推荐)
运行完整的语法 + 规范检查:
python ~/.cac/skills/huawei-cloud-mrs-clickhouse-sql-check/scripts/ck_sql_checker.py "<sql_text>" all 24.8
4.2 仅检查语法
python ~/.cac/skills/huawei-cloud-mrs-clickhouse-sql-check/scripts/ck_sql_checker.py "<sql_text>" syntax 24.8
4.3 仅检查规范
python ~/.cac/skills/huawei-cloud-mrs-clickhouse-sql-check/scripts/ck_sql_checker.py "<sql_text>" spec 24.8
4.4 分词调试
检查令牌流以进行调试:
python ~/.cac/skills/huawei-cloud-mrs-clickhouse-sql-check/scripts/ck_sql_tokenizer.py "<sql_text>" 24.8
4.5 解析器调试
检查解析后的语句结构:
python ~/.cac/skills/huawei-cloud-mrs-clickhouse-sql-check/scripts/ck_sql_parser.py "<sql_text>" 24.8
4.6 Python API 用法
from ck_sql_checker import check_sql_markdown
report = check_sql_markdown("SELECT * FROM t1", "all", "24.8")
print(report)
5. 参数
| 参数 | 必填/可选 | 描述 | 默认值 |
|---|---|---|---|
sql_text | 必填 | 要检查的 SQL 语句 | N/A |
version | 必填 | ClickHouse 内核版本:24.8、23.3、22.3 | 无默认值;用户必须在每个会话首次调用时选择,且在该会话中重复使用 |
check_mode | 可选 | 检查模式:syntax/spec/all | syntax |
6. 输出格式
报告格式:
# ClickHouse SQL Check Report
**Check Time**: 2026-07-27T10:00:00
**ClickHouse Version**: 24.8
**Statement Type**: SELECT
**Check Mode**: all
## Summary
| Metric | Value |
|--------|-------|
| Total Rules | 51 |
| Passed | 48 |
| Violations | 3 |
| Errors (ERROR) | 1 |
| Warnings (WARNING) | 1 |
| Infos (INFO) | 1 |
## Syntax Check
### [X] SYN011: MergeTree Missing ORDER BY
- **Level**: WARNING
- **Position**: Line 1, Column 1
- **Description**: MergeTree family table without ORDER BY clause
- **Fix Suggestion**: Add ORDER BY (column1, column2, ...)
## Specification Check
### [!] SPEC010: Missing TTL lifecycle
- **Level**: INFO
- **Position**: Line 1, Column 1
- **Description**: Tables should have TTL or periodic partition cleanup
- **Fix Suggestion**: Add TTL column + toIntervalMonth(N) clause
## Original SQL
```sql
{original_sql}
**IMPORTANT: Always present check results in table format**, not as bullet lists or
paragraphs. When checking one or multiple SQL statements, always use three tables:
1. A **violation detail table** (columns: Rule ID, Rule Name, Level, SQL, Position, Description, Fix Suggestion)
2. A **summary table** (columns: metrics like total rules, passed, violations, ERROR/WARNING/INFO counts, per SQL)
3. A **fix suggestion table** (columns: SQL, Issue, Suggestion)
This table format is mandatory for all SQL check outputs.
## 7. Verification Methods
### 7.1 Verify Tokenization
Run the tokenizer independently to verify keyword recognition:
```bash
python ~/.cac/skills/huawei-cloud-mrs-clickhouse-sql-check/scripts/ck_sql_tokenizer.py "SELECT * FROM t1 FINAL" 24.8
预期结果:对于版本 24.8,令牌流应将 FINAL 识别为关键字。
7.2 验证解析器识别结果
运行解析器,验证语句类型识别:
python ~/.cac/skills/huawei-cloud-mrs-clickhouse-sql-check/scripts/ck_sql_parser.py "CREATE TABLE t (a UInt32) ENGINE = MergeTree ORDER BY a" 24.8
预期结果:输出应显示 statement_type: CREATE_TABLE,并包含解析后的列和 ENGINE 信息。
7.3 验证版本专属关键字
测试是否正确识别版本专属关键字:
| 关键字 | 24.8 | 23.3 | 22.3 |
|---|---|---|---|
| QUALIFY | ✅ | ❌ | ❌ |
| INTERPOLATE | ✅ | ✅ | ❌ |
| UNDROP | ✅ | ✅ | ❌ |
| GROUP BY ALL | ✅ | ✅ | ❌ |
使用不同版本运行分词器,以确认关键字是否可用。
7.4 验证规范规则
对已知违规项运行规范检查,以确认规则检测结果:
# Should trigger SPEC024 (SELECT * prohibited)
python ~/.cac/skills/huawei-cloud-mrs-clickhouse-sql-check/scripts/ck_sql_checker.py "SELECT * FROM t1" spec 24.8
# Should trigger SYN011 (MergeTree missing ORDER BY)
python ~/.cac/skills/huawei-cloud-mrs-clickhouse-sql-check/scripts/ck_sql_checker.py "CREATE TABLE t (a UInt32) ENGINE = MergeTree" spec 24.8
8. 最佳实践
- 先运行语法检查以捕获基本错误,再运行规范检查进行深入分析
- 始终指定与目标集群匹配的 ClickHouse 版本,以确保关键字和语法验证准确
- 在部署到生产环境前使用
all模式进行全面检查 - 注意版本专属关键字(例如,QUALIFY 仅适用于 24.8 及更高版本,INTERPOLATE 仅适用于 23.3 及更高版本)
- 对于分布式表,检查 SPEC026(GLOBAL JOIN)和 SPEC021(INSERT 到分布式表)
- 对于 MergeTree 表,始终验证 ORDER BY(SYN011),并考虑 TTL(SPEC010)
- 对于物化视图,遵循 SPEC017-SPEC020:命名约定、显式目标表、不使用 POPULATE、TTL 匹配
9. 参考资料
| 文档 | 描述 |
|---|---|
| Keywords v24.8 | 571 个 ClickHouse 24.8 关键字定义 |
| Keywords v23.3 | 462 个 ClickHouse 23.3 关键字定义 |
| Keywords v22.3 | 422 个 ClickHouse 22.3 关键字定义 |
| Token Types v24.8 | 24.8 词法分析器令牌类型定义 |
| Token Types v23.3 | 23.3 词法分析器令牌类型定义 |
| Token Types v22.3 | 22.3 词法分析器令牌类型定义 |
| Grammar v24.8 | 24.8 语句类型语法定义 |
| Grammar v23.3 | 23.3 语句类型语法定义 |
| Grammar v22.3 | 22.3 语句类型语法定义 |
| Spec Rules | 35 条开发规范规则(SPEC001-SPEC035) |
| Token Types Ref | 令牌类型参考文档 |
| SELECT Grammar | SELECT 语句语法参考 |
| DDL Grammar | DDL 语句语法参考 |
| DML Grammar | DML 和实用程序语句语法参考 |
10. 备注
- 语法检查无需连接集群,可离线运行
- 多版本:每个版本的规则独立存储;添加新版本不会影响现有版本
- 关键字直接从对应的 ClickHouse 内核源代码中提取
- 语法规则涵盖内核 Parser 类中的 47 种语句类型
- 规范规则(35 条规则,SPEC001-SPEC035)源自《MRS 开发规范 v01》(2026-07-03)第 1 章:ClickHouse 应用开发规范,涵盖 DDL 表设计、DDL 操作、物化视图、DML 数据加载、查询规范和数据修改规范
- 部分规范规则(如分区数量、数据量、JOIN 顺序)需要运行时信息,因此使用静态启发式方法进行近似判断
- 检查引擎包含自定义分词器和语句识别器,无需外部 SQL 解析库
目录结构
rules/
common/
spec_rules.py # Version-independent dev-spec rules (SPEC001-SPEC035)
v24.8/
keywords.py # 571 keywords (from CommonParsers.h APPLY_FOR_PARSER_KEYWORDS)
grammar_rules.py # 47 statement types
token_types.py # 52 token types (includes Spaceship <=>)
v23.3/
keywords.py # 462 keywords (from Parser*.cpp ParserKeyword("...") calls)
grammar_rules.py # 47 statement types (no QUALIFY/PASTE JOIN/MODIFY REFRESH)
token_types.py # 49 token types (no Spaceship/Caret/Ellipsis)
v22.3/
keywords.py # 422 keywords (from Parser*.cpp ParserKeyword("...") calls)
grammar_rules.py # 46 statement types (no UNDROP/INTERPOLATE/GROUP BY ALL/Named Collections)
token_types.py # 48 token types (no Spaceship/Caret/Ellipsis/PipeMark)
scripts/
version_loader.py # Dynamic version module loader
ck_sql_tokenizer.py # Tokenizer (version-aware via init_version())
ck_sql_parser.py # Parser (version-aware via init_version())
ck_sql_checker.py # Check engine (version-aware)
添加新的 ClickHouse 版本:
- 创建
rules/v{version}/目录 - 从该版本的内核源代码中提取 keywords、grammar_rules、token_types
- 技能会自动检测并支持新版本