- 新增三个 demo 工程(demo-eslint / demo-sqlfluff / demo-stylelint):各含 src/ 样例代码与覆盖率映射(run-coverage.mjs、coverage_map.json、stylelint_line_map.json) - 归档各 demo 的插件实测导出报告(reports/): - demo-eslint:common.js / esm-demo.js / legacysyntax.cjs / typescript.ts 审查报告 + 覆盖率报告(292/292 条零偏差,126 种规则全覆盖) - demo-sqlfluff:11 个 SQL 样例审查报告 + 覆盖率报告(113/113 条零偏差,57 种规则全覆盖,含 JJ01 行号缺陷修复后的复测验证) - demo-stylelint:common.css / empty-source.css 审查报告 + 覆盖率报告(145/145 条零偏差,68 种规则全覆盖)
112 lines
6.0 KiB
Markdown
112 lines
6.0 KiB
Markdown
# 代码审查报告
|
||
|
||
**文件:** `data\demo-sqlfluff\src\07_structure.sql`
|
||
**语言:** sql
|
||
**耗时:** 226.0s
|
||
**分析工具:** sqlfluff
|
||
|
||
---
|
||
|
||
总计: 30 | 错误: 29 | 警告: 1 | 建议: 0
|
||
|
||
静态分析 · 28 个问题
|
||
|
||
- 🔴 `sqlfluff:LT05` L1
|
||
L1: 行过长(97 > 80)。
|
||
建议: 将该行注释拆分为多行或精简文字,使长度不超过 80 个字符。
|
||
- 🔴 `sqlfluff:ST01` L3
|
||
L3: 不要在 CASE WHEN 语句中指定 'ELSE NULL'(冗余)。
|
||
建议: 删除 `ELSE NULL` 分支;当条件不满足时 CASE 会自然返回 NULL。
|
||
- 🔴 `sqlfluff:ST02` L13
|
||
L13: 不必要的 CASE 语句,建议改用 COALESCE 函数。
|
||
建议: 改为 `COALESCE(amount > 0, FALSE) AS positive`,效果与当前 CASE 一致。
|
||
- 🔴 `sqlfluff:ST03` L20
|
||
L20: 查询定义了 CTE "unused_cte" 但未使用。
|
||
建议: 删除未使用的 CTE `WITH unused_cte AS (...)`,直接从 `SELECT` 开始查询。
|
||
- 🔴 `sqlfluff:LT08` L23
|
||
L23: CTE 结束括号之后应有空行,但未找到。
|
||
建议: 在 CTE 的闭合括号 `)` 与后续 `SELECT` 之间插入一个空行。
|
||
- 🔴 `sqlfluff:ST04` L32
|
||
L32: ELSE 子句中的嵌套 CASE 语句可以展平。
|
||
建议: 合并为一个 CASE:`CASE WHEN a = 1 THEN b WHEN c = 1 THEN d END AS result`。
|
||
- 🔴 `sqlfluff:RF04` L35
|
||
L35: 不应将关键字用作标识符。
|
||
建议: 将别名 `result` 改为非关键字名称,例如 `result_value`。
|
||
- 🔴 `sqlfluff:AL08` L42
|
||
L42: 列别名 'id' 与第 41 行的列名重复。
|
||
建议: 为 `sub.id` 指定唯一别名,例如 `AS sub_id`,避免结果集列名冲突。
|
||
- 🔴 `sqlfluff:AM05` L45
|
||
L45: JOIN 子句应使用全限定名。
|
||
建议: 明确使用 `INNER JOIN`,并确保 ON 条件中的列均带表别名限定。
|
||
- 🔴 `sqlfluff:ST05` L46
|
||
L46: select_statement 子句中不应包含子查询,应改用 CTE。
|
||
建议: 将 JOIN 中的派生表提取为 CTE:`WITH sub AS (SELECT id FROM other_table) SELECT ... JOIN sub ON ...`。
|
||
- 🔴 `sqlfluff:LT02` L46
|
||
L46: 应在 'ON' 前换行,且 'ON' 前不应有缩进。
|
||
建议: 将 ON 子句放到新行,放在与 JOIN 同一层级:`(SELECT ...) AS sub
|
||
ON a.id = sub.id;`
|
||
- 🔴 `sqlfluff:ST06` L49
|
||
L49: SELECT 中应先写通配符和简单目标,再写计算与聚合。
|
||
建议: 将 `*` 移到最前,再写普通列,最后写 `SUM(amount)`,并给聚合结果命名。注意当前查询还缺少 GROUP BY 或窗口函数。
|
||
- 🔴 `sqlfluff:AL03` L50
|
||
L50: 列表达式没有别名,请使用显式 `AS` 子句。
|
||
建议: 为 `SUM(amount)` 添加别名:`SUM(amount) AS total_amount`。
|
||
- 🔴 `sqlfluff:AM05` L62
|
||
L62: JOIN 子句应使用全限定名。
|
||
建议: 将 `USING (id)` 改写为带表别名限定的 ON 条件,并可加上 `INNER`。
|
||
- 🔴 `sqlfluff:LT02` L63
|
||
L63: 应在 'USING' 前换行,且不应缩进。
|
||
建议: 将 `USING (id)` 移到新行(若改写为 ON 也保持换行)。
|
||
- 🔴 `sqlfluff:ST07` L63
|
||
L63: 发现 USING 语句,应只使用 ON 语句。
|
||
建议: 将 `USING (id)` 改写为 `ON a.id = b.id`。
|
||
- 🔴 `sqlfluff:LT10` L66
|
||
L66: 'SELECT' 修饰符(如 'DISTINCT')必须与 'SELECT' 在同一行。
|
||
建议: 将 `DISTINCT` 移到 `SELECT` 同一行:`SELECT DISTINCT id`。
|
||
- 🔴 `sqlfluff:LT02` L67
|
||
L67: 该行不应缩进。
|
||
建议: 将 `DISTINCT` 移到 `SELECT` 同一行,消除缩进。
|
||
- 🔴 `sqlfluff:LT01` L67
|
||
L67: 'DISTINCT' 关键字与左括号 '(' 之间应有单个空格。
|
||
建议: 不要使用函数式写法;最好是去掉括号写成 `DISTINCT id`。
|
||
- 🔴 `sqlfluff:ST08` L67
|
||
L67: 'DISTINCT' 不能与括号一起使用。
|
||
建议: 去掉括号:`SELECT DISTINCT id`。
|
||
- 🔴 `sqlfluff:AM05` L77
|
||
L77: JOIN 子句应使用全限定名。
|
||
建议: 明确写出 `INNER JOIN`,并保持 ON 条件使用表别名限定。
|
||
- 🔴 `sqlfluff:LT02` L78
|
||
L78: 应在 'ON' 前换行,且不应缩进。
|
||
建议: 将 `ON` 子句放到新行:`other_table AS b
|
||
ON b.id = a.id;`
|
||
- 🔴 `sqlfluff:ST09` L78
|
||
L78: JOIN 条件应把先出现的表放在前面。
|
||
建议: 将 `ON b.id = a.id` 调整为 `ON a.id = b.id`。
|
||
- 🔴 `sqlfluff:ST10` L86
|
||
L86: 冗余常量表达式。
|
||
建议: 删除 `WHERE` 子句,或改为 `WHERE TRUE`;如果动态生成条件,请不要保留恒真条件。
|
||
- 🔴 `sqlfluff:ST11` L94
|
||
L94: JOIN 表 'other_table AS b' 未在查询其他位置引用。
|
||
建议: 若确实不需要该表,删除整个 LEFT JOIN;若只想判断存在性,请改用 EXISTS 子查询。
|
||
- 🔴 `sqlfluff:LT02` L94
|
||
L94: 应在 'ON' 前换行,且不应缩进。
|
||
建议: 将 `ON` 子句放到新行:`other_table AS b
|
||
ON a.id = b.id;`
|
||
- 🔴 `sqlfluff:ST12` L100
|
||
L100: 检测到连续分号(计数 2)。
|
||
建议: 删除多余的分号,只保留一个 `;`。
|
||
- 🔴 `sqlfluff:LT12` L101
|
||
L101: 文件必须以单个尾随换行符结束。
|
||
建议: 确保文件末尾恰好有一个换行符,不要多出空行或缺少换行。
|
||
|
||
AI 审查 · 2 条建议
|
||
|
||
- 🔴 [AI] [bug] `aggregate-without-group-by` L49
|
||
**聚合函数与未分组列/通配符混用**
|
||
第49行的 SELECT 将 `SUM(amount)` 与 `id`、`*` 放在同一个 SELECT 列表中,但没有 GROUP BY,也没有把 `SUM` 改为窗口函数。在大多数 SQL 引擎中这是非法查询;即使某些引擎允许,也会随机返回非聚合列的任意行,结果不可预测。
|
||
建议: 如果希望保留每一行并附带总额,使用窗口函数 `SUM(amount) OVER () AS total_amount`;如果希望做聚合,则需要列出所有非聚合列并加 `GROUP BY`,或显式只保留聚合结果。
|
||
- 🟡 [AI] [bug] `unused-left-join-cardinality` L94
|
||
**未使用的 LEFT JOIN 可能使结果行数倍增**
|
||
第93-94行的 LEFT JOIN 虽然未在 SELECT 或 WHERE 中引用 `other_table AS b`,但 SQL 仍会执行关联;若 `other_table.id` 有重复值,每条匹配都会复制左表行,导致结果集意外膨胀。静态规则只报告了表未被引用,但没有强调行数变化风险。
|
||
建议: 完全移除该 LEFT JOIN;若需要检查是否存在匹配,使用 `WHERE EXISTS (SELECT 1 FROM other_table b WHERE b.id = a.id)`。
|