关于 huawei-cloud-mrs-spark-sql-check
用于静态检查 Huawei Cloud MRS Spark SQL 的 Skill,面向希望在执行前获得语法和规范反馈的开发者。它通过自定义分词器、解析器和规则引擎生成 Markdown 报告,无需连接集群。
主要功能
- 01自定义 Spark SQL 分词与解析
- 02语法和规范检查
- 03支持 Spark 专属语法
- 04可选语法、规范或全部模式
- 05生成 Markdown 违规报告
适用场景
- 01在 MRS Spark 上运行前验证 SQL
- 02按 Spark SQL 规范审查语句
- 03查找 Spark 专属 DDL 和 DML 的语法问题
- 04识别 SQL 设计与性能警告
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ huaweicloud/ huaweicloud-skills --skill huawei-cloud-mrs-spark-sql-check安装后在 Claude Code 中输入/huawei-cloud-mrs-spark-sql-check确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/report_template.mdreferences/acceptance-criteria.mdast-schema.mdrules/grammar_rules.pykeywords.pyperf_rules.yamlspec_rules.yamlsyntax_rules.yamlscripts/spark_sql_checker.pyspark_sql_parser.pyspark_sql_tokenizer.py详细介绍
MRS Spark SQL 检查技能
你是一名 MRS Spark SQL 规范检查专家,负责对 Huawei Cloud MRS Spark 的 SQL 语句进行全面检查。你拥有自定义构建的 Spark SQL 分词器和递归下降解析器,可以精确识别 Spark 特有语法。
概述
架构:此技能采用三阶段流水线:分词器(词法分析)-> 解析器(语法分析)-> 规则引擎(语法 + 规范检查)-> 报告生成。
适用场景:
- 在 MRS Spark 集群上执行 SQL 前验证 SQL 语法
- 根据 Spark SQL 开发规范审查 SQL 语句
- 检查 Spark 特有语法(USING、OPTIONS、CACHE TABLE、CREATE TEMP VIEW 等)
- 识别 Spark SQL 语句中潜在的性能反模式
典型用例:
- “检查这条 Spark SQL:SELECT * FROM t1”
- “这个 CREATE TABLE USING PARQUET 是否符合 Spark 规范?”
- “验证这条 INSERT OVERWRITE 语句的语法”
- “审查我的 Spark SQL 是否符合规范”
检查模式
| 模式 | 依赖项 | 说明 |
|---|---|---|
| syntax | 无 | 语法检查:关键字有效性、语句结构、子句完整性、Spark SQL 语法兼容性 |
| spec | 无 | 规范检查:对象设计标准、数据操作标准、命名约定、Spark SQL 开发规则 |
| all | 无 | 同时执行语法检查和规范检查 |
默认:syntax + spec 模式(无需外部依赖)。
前置条件
1. Python 要求
- Python >= 3.8
- 无需安装其他软件包(仅使用标准库)
2. 安全规则
- 此技能仅执行静态 SQL 分析,无需连接集群
- SQL 文本在本地处理,不会向外部发送任何数据
- 无需凭据或身份验证
工作流
步骤 1:接收输入
接收用户提供的 SQL 语句和检查模式。如果未指定模式,则默认使用 syntax + spec 模式。
步骤 2:分词
运行分词器,将 SQL 文本转换为 Token 流。
python ~/.cac/skills/huawei-cloud-mrs-spark-sql-check/scripts/spark_sql_tokenizer.py "<sql_text>"
分词器支持:
- 所有 Spark SQL 关键字(4 类:RESERVED、COL_NAME、TYPE_FUNC_NAME、UNRESERVED)
- Spark 特有的 Token:
HINT(/*+ ... */)、BACKTICK_IDENT(`ident`) - 字面量:字符串、整数、浮点数
- 跳过注释(-- 单行注释、/* / 多行注释,但 /+ hint */ 会保留为 HINT Token)
步骤 3:解析
运行解析器生成 AST 并检测语法错误。
python ~/.cac/skills/huawei-cloud-mrs-spark-sql-check/scripts/spark_sql_parser.py "<sql_text>"
解析器支持主要语句类型:
- DML:SELECT、INSERT(包括 INSERT OVERWRITE)、UPDATE、DELETE、MERGE
- DDL:CREATE TABLE(含 USING/OPTIONS)、ALTER TABLE、DROP、CREATE VIEW/TEMP VIEW/GLOBAL TEMP VIEW、TRUNCATE
- DCL:GRANT、REVOKE
- 实用工具:EXPLAIN、SET、SHOW、DESCRIBE、ANALYZE TABLE
- Spark 特有语法:CACHE TABLE、UNCACHE TABLE、CLEAR CACHE、REFRESH TABLE/FUNCTION、ADD JAR、LIST JAR、RESET
Spark 特有语法:
CREATE TABLE ... USING {parquet|orc|json|csv|...} [OPTIONS (...)]CACHE [LAZY] TABLE table_name [AS SELECT ...]CREATE [OR REPLACE] [GLOBAL] TEMP [MATERIALIZED] VIEWREFRESH TABLE table_name/REFRESH FUNCTION func_nameADD JAR /path/to/file.jar/*+ BROADCAST(table) */和/*+ COALESCE(N) */提示LATERAL VIEW ... EXPLODE(...)PARTITIONED BY (col_name)(Spark 风格,仅列名)
步骤 4:语法检查
根据词法分析和解析结果,执行语法检查规则。
语法检查规则(20 条):
| 规则 ID | 名称 | 级别 | 描述 |
|---|---|---|---|
| SYN-ERR | 词法错误 | ERROR | SQL 文本中包含无法识别的字符 |
| SYN001 | 无效关键字 | ERROR | Spark SQL 不支持的关键字 |
| SYN002 | 将保留关键字用作标识符 | ERROR | 未加引号便将保留关键字用作标识符 |
| SYN003 | 语法结构错误 | ERROR | 缺少必需的子句或关键字 |
| SYN004 | 子句顺序错误 | ERROR | SQL 子句顺序不符合语法规则 |
| SYN005 | PARTITIONED BY 语法错误 | ERROR | 分区定义语法无效 |
| SYN006 | CLUSTERED BY 语法错误 | ERROR | 分桶定义语法无效(Hive 兼容) |
| SYN007 | STORED AS / USING 语法错误 | ERROR | 存储格式或数据源无效 |
| SYN008 | ROW FORMAT 语法错误 | ERROR | ROW FORMAT 定义无效(Hive 兼容) |
| SYN009 | INSERT OVERWRITE 语法错误 | ERROR | INSERT OVERWRITE 结构无效 |
| SYN010 | LATERAL VIEW 语法错误 | ERROR | LATERAL VIEW 结构无效 |
| SYN011 | 子查询语法错误 | ERROR | 子查询结构无效 |
| SYN012 | CREATE TABLE 结构错误 | ERROR | CREATE TABLE 中缺少必需元素 |
| SYN013 | ALTER TABLE 语法错误 | ERROR | ALTER TABLE 操作无效 |
| SYN014 | MERGE 语法错误 | ERROR | MERGE 语句结构无效 |
| SYN016 | USING 子句错误 | ERROR | USING 数据源规范无效 |
| SYN017 | OPTIONS 子句错误 | ERROR | OPTIONS 子句格式无效 |
| SYN018 | CACHE TABLE 语法错误 | ERROR | CACHE TABLE 结构无效 |
| SYN019 | REFRESH 语法错误 | ERROR | REFRESH 语句结构无效 |
| SYN020 | ADD/LIST JAR 语法错误 | ERROR | ADD JAR / LIST JAR 结构无效 |
步骤 5:规范检查
根据 AST 和 Token 流执行规范检查规则。这些规则源自 Spark SQL 开发规范和 MRS Spark 最佳实践。
规范检查规则(29 条):
| 规则 ID | 名称 | 级别 | 类别 | 描述 |
|---|---|---|---|---|
| SPEC001 | 禁止 SELECT * | WARNING | 数据操作 | 查询必须明确指定列清单 |
| SPEC002 | DELETE/UPDATE 缺少 WHERE | ERROR | 数据操作 | DML 必须包含 WHERE 条件 |
| SPEC003 | 笛卡尔积 | ERROR | 数据操作 | 多表查询缺少 JOIN 条件 |
| SPEC004 | 隐式类型转换 | WARNING | 数据操作 | 可能导致意外结果 |
| SPEC005 | LIKE 前导通配符 | WARNING | 数据操作 | 无法进行分区裁剪 |
| SPEC006 | 分区字段使用函数 | WARNING | 数据操作 | 对分区字段使用函数会阻止分区裁剪 |
| SPEC007 | INSERT 缺少列清单 | WARNING | 数据操作 | 依赖默认列顺序 |
| SPEC008 | 缺少表注释 | INFO | 对象设计 | 表没有注释 |
| SPEC009 | 保留关键字用作标识符 | ERROR | 命名 | 可能导致语法歧义 |
| SPEC010 | 列名过长 | WARNING | 命名 | 列名超过 30 个字符 |
| SPEC012 | 金额字段使用 FLOAT/DOUBLE | ERROR | 对象设计 | 金额字段应使用 DECIMAL |
| SPEC013 | 列数过多 | WARNING | 对象设计 | 表的列数不应超过 100 个 |
| SPEC014 | 分区字段过多 | WARNING | 对象设计 | 分区字段不应超过 3 个 |
| SPEC015 | 缺少列注释 | INFO | 对象设计 | 列没有注释 |
| SPEC016 | CASE WHEN 缺少 ELSE | WARNING | 数据操作 | CASE WHEN 应包含 ELSE 子句 |
| SPEC017 | NULL 值处理 | WARNING | 数据操作 | 条件中的 NULL 处理 |
| SPEC018 | 禁止使用字符串 'null' | ERROR | 数据操作 | 不要使用字符串 'NULL' |
| SPEC019 | JOIN 字段类型不匹配 | WARNING | 数据操作 | JOIN 字段应使用相同类型 |
| SPEC020 | INSERT INTO VALUES | WARNING | SQL 开发 | 应使用 INSERT SELECT |
| SPEC021 | 子查询嵌套深度 | WARNING | SQL 开发 | 子查询不应超过 3 层 |
| SPEC022 | 缺少分区裁剪 | ERROR | 数据操作 | 查询分区表时未指定分区过滤条件 |
| SPEC023 | 非标准 JOIN 条件 | WARNING | 数据操作 | JOIN ON 中不应包含 IF/CASE WHEN |
| SPEC024 | CASCADE 使用警告 | WARNING | SQL 开发 | 在 ALTER TABLE 中谨慎使用 CASCADE |
| SPEC025 | 优先使用 USING 而非 STORED AS | WARNING | SQL 开发 | 使用 Spark 原生 USING 语法 |
| SPEC026 | CACHE TABLE 建议 | INFO | SQL 开发 | 缓存重复访问的表 |
| SPEC027 | BROADCAST Hint 建议 | INFO | SQL 开发 | 对小表使用广播 JOIN |
| SPEC028 | DROP 缺少 IF EXISTS | WARNING | SQL 开发 | 使用 DROP 时加上 IF EXISTS |
| SPEC029 | ADD JAR 警告 | INFO | SQL 开发 | 优先使用 --jars 而非 ADD JAR |
步骤 6:生成报告
使用检查引擎生成 Markdown 格式的报告:
python ~/.cac/skills/huawei-cloud-mrs-spark-sql-check/scripts/spark_sql_checker.py "<sql_text>" all
报告格式:
# MRS Spark SQL Check Report
**Check Time**: yyyy-mm-ddThh:mm:ss
**Statement Type**: SELECT
**Check Mode**: all
## Summary
| Metric | Value |
|--------|-------|
| Total Rules | 56 |
| Passed | 51 |
| Violations | 5 |
| Errors (ERROR) | 2 |
| Warnings (WARNING) | 2 |
| Infos (INFO) | 1 |
## Syntax Check
### [X] SYN003: Syntax Structure Error
- **Level**: ERROR
- **Position**: Line 1, Column 15
- **Description**: Missing FROM clause
- **Fix Suggestion**: Add FROM table_name
## Specification Check
### [!] SPEC001: SELECT * Prohibited
- **Level**: WARNING
- **Position**: Line 1, Column 8
- **Description**: Query uses SELECT *, should specify explicit column list
- **Fix Suggestion**: Replace SELECT * with specific column list
参数
| 参数 | 必填/可选 | 描述 | 默认值 |
|---|---|---|---|
sql_text | 必填 | 要检查的 SQL 语句 | N/A |
check_mode | 可选 | 检查模式:syntax/spec/all | syntax+spec |
输出格式
检查报告以 Markdown 格式输出,包含:
- 汇总表:规则总数、通过数、各级别的违规数
- 语法检查部分:语法规则中的违规(SYN-ERR、SYN001-SYN020)
- 规范检查部分:规范规则中的违规(SPEC001-SPEC029)
- 大型 SQL 拦截部分:拦截规则中的违规(INTERCEPT001-INTERCEPT007)
- 原始 SQL:经过检查的 SQL 语句
每条违规都包含:规则 ID、规则名称、级别、位置(行/列)、描述、代码片段和修复建议。
核心命令
spark_sql_checker.py spark_sql_parser.py spark_sql_tokenizer.py
最佳实践
- 先运行语法检查以发现基本错误,然后运行规范检查进行深入分析
- 对于 CREATE TABLE 语句,优先使用
USING parquet,而不是STORED AS PARQUET - 使用 ORC 或 Parquet 存储格式,以获得更好的压缩率和查询性能
- 查询分区表时,始终添加分区筛选条件
- 使用
all模式进行全面检查 - 对小表与大表的连接使用
/*+ BROADCAST(small_table) */提示
参考资料
| 文档 | 描述 |
|---|---|
| AST Schema | Spark SQL 的 AST 节点类型定义 |
| Syntax Rules | 20 条语法检查规则定义 |
| Specification Rules | 29 条规范检查规则定义 |
| Keywords | Spark SQL 关键字定义 |
| Grammar Rules | 语句类型语法定义 |
注意事项
- 语法和规范检查不需要连接集群,可离线运行
- Spark 专用语法检查(USING、OPTIONS、CACHE TABLE 等)基于 Spark SQL 语法定义
- 检查引擎包含自定义词法分析器和递归下降解析器,无需外部 SQL 解析库
- Spark SQL 源自 HiveQL;也支持与 Hive 兼容的语法(STORED AS、CLUSTERED BY、ROW FORMAT)