mcpField
H
huawei-cloud-mrs-clickhouse-sql-check

huawei-cloud-mrs-clickhouse-sql-check

github.com/huaweicloud测试与质量59116 次安装2 天前更新
代码仓库

关于 huawei-cloud-mrs-clickhouse-sql-check

huawei-cloud-mrs-clickhouse-sql-check 是用于检查 ClickHouse SQL 的技能,可按版本校验语法,并可选检查 MRS 开发规范。它通过词法分析、解析、规则检查和报告生成在本地静态分析,无需连接集群。

主要功能

  1. 01按版本检查 ClickHouse 语法
  2. 02SQL 词法分析与语句解析
  3. 03语法和规范检查模式
  4. 04离线静态分析
  5. 05生成问题检查报告

适用场景

  1. 01在集群执行前检查 SQL
  2. 02审查 SQL 的版本兼容性
  3. 03发现语句和子句格式错误
  4. 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.md
dml_misc_grammar.md
select_grammar.md
token_types.md
rules/common/
spec_rules.py
rules/v22.3/
grammar_rules.py
keywords.py
token_types.py
rules/v23.3/
grammar_rules.py
keywords.py
token_types.py
rules/v24.8/
grammar_rules.py
keywords.py
token_types.py
scripts/
ck_sql_checker.py
ck_sql_parser.py
ck_sql_tokenizer.py
version_loader.py
templates/
report_template.md

详细介绍

ClickHouse SQL 检查技能

你是一名 ClickHouse SQL 规范检查专家,负责全面检查 ClickHouse SQL 语句。你拥有自定义构建的 ClickHouse SQL 分词器和语句识别器,可以精准识别 ClickHouse 特有语法。

1. 概述

架构:此技能采用三阶段流水线: 分词器(词法分析)→ 解析器(语句识别 + 语法分析) → 规则引擎(语法 + 规范检查)→ 报告生成。

多版本支持:针对特定版本的语法规则(关键字、语法、令牌类型) 存储在 rules/v{version}/ 目录中。通用开发规范规则位于 rules/common/。用户调用此技能时,每个会话只询问一次要使用哪个 ClickHouse 内核版本 (请参阅下方的工作流)。在同一会话中,重复使用之前选择的版本和模式,不再询问。

支持的版本:

版本关键字令牌类型语句类型来源
24.85715247CommonParsers.h APPLY_FOR_PARSER_KEYWORDS 宏
23.34624947Parser*.cpp ParserKeyword("...") 调用(分散)
22.34224846Parser*.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/NEXT
  • CREATE TABLE:ENGINE、ORDER BY、PARTITION BY、PRIMARY KEY、SAMPLE BY、 TTL、SETTINGS、CODEC、STATISTICS、PROJECTION、CONSTRAINT
  • ALTER 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子句顺序错误ERRORSQL 子句顺序不符合语法规则
SYN005未闭合字符串ERROR字符串字面量未正确闭合
SYN006未闭合注释ERROR多行注释未正确闭合
SYN007未闭合标识符ERROR带引号的标识符未正确闭合
SYN008数字格式无效ERROR数字字面量格式错误
SYN009意外字符ERRORSQL 文本中存在无法识别的字符
SYN010CREATE TABLE 缺少 ENGINEWARNINGCREATE TABLE 语句未包含 ENGINE 子句
SYN011MergeTree 缺少 ORDER BYWARNINGMergeTree 系列表未包含 ORDER BY 子句
SYN012DELETE 缺少 WHEREWARNINGDELETE 语句未包含 WHERE 子句
SYN013UPDATE 缺少 WHEREWARNINGUPDATE 语句未包含 WHERE 子句
SYN014JOIN 语法无效ERRORJOIN 组合无效(例如,CROSS 与 ANY 同时使用)
SYN015未闭合括号ERROR括号不平衡
步骤 4b:规范检查

根据 MRS ClickHouse 开发规范(v01,2026-07-03),执行 35 条规范规则。使用 spec 或 all 模式启用。规范规则与版本无关。

规范检查规则(SPEC001-SPEC035):

规则 ID名称级别类别描述
SPEC001禁止使用 Buffer 引擎ERRORDDLBuffer 引擎在重启或发生故障时有数据丢失风险
SPEC002建议使用 Replicated 引擎WARNINGDDL建议使用 Replicated*MergeTree 以提高可靠性
SPEC003表名不符合规范WARNINGDDL表名应以字母开头,且只能包含字母数字和下划线
SPEC004禁止使用 String 类型存储日期/时间WARNINGDDL日期应使用 Date/DateTime 类型,而非 String
SPEC005禁止使用 String 类型存储数字WARNINGDDL数字应使用数值类型,而非 String
SPEC006Nullable 列过多INFODDLNullable 列过多会浪费内存
SPEC007数值类型未使用最小适用类型INFODDL使用满足需求的最小数值类型
SPEC008低基数列未使用 LowCardinalityINFODDL基数 < 100k 的列应使用 LowCardinality
SPEC009表的列数超过 5000WARNINGDDL单个表的列数不应超过 5000
SPEC010缺少 TTL 生命周期管理INFODDL表应设置 TTL 或定期清理分区
SPEC011ORDER BY 字段过多WARNINGDDLORDER BY 字段应 <= 4 个,且不能为 null
SPEC012PRIMARY KEY 不是排序键的前缀WARNINGDDLPRIMARY KEY 应为 ORDER BY 的前缀
SPEC014DROP/ALTER 未使用 NO DELAYINFODDL添加 NO DELAY 以立即执行
SPEC015跳数索引超过每表 5 个WARNINGDDL每个表的跳数索引应 <= 5 个
SPEC016分区数量过多的风险INFODDL分区数应 <= 10000,并使用整型分区列
SPEC017物化视图命名不符合规范INFODDL聚合表:_{type}agg;物化视图:{type}_mv
SPEC018物化视图未显式指定目标表WARNINGDDL使用 TO 关键字指定物化视图的目标表
SPEC019禁止创建物化视图时使用 POPULATEERRORDDLPOPULATE 在创建期间有数据丢失风险
SPEC020物化视图缺少 TTLINFODDL物化视图的目标表应设置与源表相匹配的 TTL
SPEC021向分布式表执行 INSERTWARNINGDML写入本地表,而非分布式表
SPEC022INSERT 未限定为单个分区INFODML批量插入应针对单个分区
SPEC023禁止使用 Kafka 引擎ERRORDML避免使用 ClickHouse Kafka 引擎,改为在应用中消费
SPEC024禁止使用 SELECT * 查询WARNINGQuery明确指定列,避免使用 SELECT *
SPEC025建议使用 uniqCombined 替代 distinctINFOQueryuniqCombined 比 countDistinct/distinct 更快
SPEC026分布式 JOIN 未使用 GLOBALWARNINGQuery分布式查询应使用 GLOBAL JOIN/IN/NOT IN
SPEC027复杂的多表 JOIN 未拆分INFOQuery将复杂的多表 JOIN 拆分为两表 JOIN
SPEC028JOIN 顺序:大表连接小表INFOQuery大表 JOIN 小表,并将小表放在右侧
SPEC029谨慎使用 FINALINFOQueryFINAL 会触发全量合并,应少用
SPEC030谨慎使用 DELETE/UPDATE mutationWARNINGDMLMutation 执行缓慢且会阻塞合并,应少用
SPEC031禁止修改索引列ERRORDML绝不要 UPDATE ORDER BY / PRIMARY KEY 列
SPEC032谨慎使用 OPTIMIZEINFODMLOPTIMIZE 会强制合并,应在非高峰时段运行
SPEC033批量清理未通过分区进行INFODML使用 DROP PARTITION 进行批量清理
SPEC034类型敏感函数中的 Decimal 类型不匹配WARNINGQuerycoalesce/ifNull/nullIf 中 Decimal 的精度或小数位数不匹配会导致隐式转换
SPEC035IN/NOT IN 两侧列数不匹配ERRORQueryIN/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/allsyntax

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.823.322.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. 最佳实践

  1. 先运行语法检查以捕获基本错误,再运行规范检查进行深入分析
  2. 始终指定与目标集群匹配的 ClickHouse 版本,以确保关键字和语法验证准确
  3. 在部署到生产环境前使用 all 模式进行全面检查
  4. 注意版本专属关键字(例如,QUALIFY 仅适用于 24.8 及更高版本,INTERPOLATE 仅适用于 23.3 及更高版本)
  5. 对于分布式表,检查 SPEC026(GLOBAL JOIN)和 SPEC021(INSERT 到分布式表)
  6. 对于 MergeTree 表,始终验证 ORDER BY(SYN011),并考虑 TTL(SPEC010)
  7. 对于物化视图,遵循 SPEC017-SPEC020:命名约定、显式目标表、不使用 POPULATE、TTL 匹配

9. 参考资料

文档描述
Keywords v24.8571 个 ClickHouse 24.8 关键字定义
Keywords v23.3462 个 ClickHouse 23.3 关键字定义
Keywords v22.3422 个 ClickHouse 22.3 关键字定义
Token Types v24.824.8 词法分析器令牌类型定义
Token Types v23.323.3 词法分析器令牌类型定义
Token Types v22.322.3 词法分析器令牌类型定义
Grammar v24.824.8 语句类型语法定义
Grammar v23.323.3 语句类型语法定义
Grammar v22.322.3 语句类型语法定义
Spec Rules35 条开发规范规则(SPEC001-SPEC035)
Token Types Ref令牌类型参考文档
SELECT GrammarSELECT 语句语法参考
DDL GrammarDDL 语句语法参考
DML GrammarDML 和实用程序语句语法参考

10. 备注

  1. 语法检查无需连接集群,可离线运行
  2. 多版本:每个版本的规则独立存储;添加新版本不会影响现有版本
  3. 关键字直接从对应的 ClickHouse 内核源代码中提取
  4. 语法规则涵盖内核 Parser 类中的 47 种语句类型
  5. 规范规则(35 条规则,SPEC001-SPEC035)源自《MRS 开发规范 v01》(2026-07-03)第 1 章:ClickHouse 应用开发规范,涵盖 DDL 表设计、DDL 操作、物化视图、DML 数据加载、查询规范和数据修改规范
  6. 部分规范规则(如分区数量、数据量、JOIN 顺序)需要运行时信息,因此使用静态启发式方法进行近似判断
  7. 检查引擎包含自定义分词器和语句识别器,无需外部 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 版本:

  1. 创建 rules/v{version}/ 目录
  2. 从该版本的内核源代码中提取 keywords、grammar_rules、token_types
  3. 技能会自动检测并支持新版本

评论

支持 Markdown