Files
2026Technology-Competition/docs/superpowers/specs/2026-07-30-sqlfluff-rule-enhancement-design.md
T
范智鹏 5848eaa82a feat: Linter 规则精细化增强 + 模板导入/导出闭环
ESLint: +29 条 P1/P2 规则 + 12 条 TS 专属规则(含 no-shadow/no-array-constructor 冲突处理)
Stylelint: 集成 stylelint-config-recommended + 27 条额外规则
PMD: 排除 20 弃用 + 17 噪音规则,补启 Security/Multithreading,274+12 条精选
SQL-lint: 内置精选 57 条规则配置 + 按 tier 分级 severity + 无项目配置时自动注入临时配置
模板导出: export-service.ts 导出 2-sheet xlsx(复用 xlsx 零新依赖)
模板导入: template-converter.ts 固定列映射解析 + dedup-prompt.ts AI 语义去重
导入预览增强: 错误规则分组置顶只读、跳过行提示、空数据提示
i18n: 新增 18 条模板导入/导出相关翻译
WebView: 静态分析/自定义规则项默认可展开显示 suggestion
2026-07-30 23:17:20 +08:00

33 KiB
Raw Blame History

SQLFluff 规则增强设计书

一、背景与目标

1.1 现状

当前 SqlLintAdaptersrc/adapters/sql-lint.ts)作为外部 CLI 工具适配器,通过 spawn('sqlfluff', ...) 调用系统安装的 SQLFluff 4.2.2。其内置默认行为为:

// 当前行为:无内置配置文件,无配置时使用 CLI 默认(rules = all
// 方言映射:sql → ansiplsql → postgres
// 配置优先级:全局配置 > 项目 .sqlfluff > CLI 默认(rules = all

SQLFluff 的 CLI 默认 rules = all 会无差别启用全部 75 条规则,存在以下问题:

  • 无差别全启用rules = all 启用 75 条规则,其中包含 7 条不应在代码审查中强制的规则(默认禁用、纯格式化噪音、需项目配置)
  • 格式化噪音泛滥:LT03(操作符换行)、LT04(逗号风格)、LT09(SELECT 目标换行)等纯格式化规则在审查中产生大量低价值诊断,淹没了真正的问题
  • 争议性规则干扰:AL07(禁止表别名)、CV10(引号风格)、RF03(引用一致性)等规则因 force_enable = False 默认不生效,且规则本身存在争议,全启用后行为不一致
  • 与 ESLint/Stylelint 架构不对齐ESLint 适配器使用 @eslint/js recommended + 精选规则,Stylelint 适配器使用 stylelint-config-recommended + 精选规则,而 SQLFluff 适配器无内置精选配置,仅依赖 CLI 默认全启用

1.2 目标

将内置配置从"无差别 rules = all75 条全启用)"改为"精选规则集(57 条)"

  • P0:保留全部 32 条 Core 核心规则(通过 rules = core 启用)
  • P1:从 43 条非 Core 规则中精选 25 条高价值规则显式启用
  • P2:保留 11 条可选规则(方言专用 + 团队偏好),供按需启用
  • 排除:明确排除 7 条不推荐规则(3 条默认禁用 + 3 条格式化噪音 + 1 条需项目配置)

1.3 设计原则

核心特点:从全到精。 与 ESLint/Stylelint 适配器"从少到多"recommended 61→92、12→68)的增强方向相反,SQLFluff 适配器是"从全到精"——从无差别 rules = all(75 条)精简为精选规则集(57 条),排除噪音规则,提升审查信噪比。

  • 不破坏现有配置优先级:全局配置 > 项目 .sqlfluff > 内置配置,三层择一逻辑不变
  • 不引入新依赖SQLFluff 是外部 CLI 工具,无 npm 依赖变更,不需要修改 package.json
  • 设计内置 .sqlfluff 配置模板:新增内置配置常量,与 ESLint/Stylelint 三层配置架构对齐
  • 同步更新 static-rules.json:为 75 条规则追加 tier 分级标记,保证 UI 展示和去重检测覆盖完整
  • 不修改规则 ID 前缀格式:诊断结果仍使用 sql-lint:{规则代码} 格式

二、影响范围分析

2.1 需要修改的文件

文件 修改类型 修改内容
src/adapters/sql-lint.ts 代码修改 新增 BUILTIN_SQLFLUFF_CONFIG 内置配置常量,无项目配置时注入精选规则集
src/rules/static-rules.json 数据修改 为 75 条 SQLFluff 规则追加 tier 分级字段(P0/P1/P2/excluded

2.2 不需要修改的文件

文件 原因
package.json SQLFluff 是外部 CLI 工具,非 npm 依赖,无依赖变更
scripts/build.mjs 不涉及构建配置变更,内置配置为纯字符串常量
src/orchestrator/orchestrator.ts 仅做调度,不涉及配置逻辑
src/config/linter.ts 配置读取层不变,三层优先级逻辑不变
src/adapters/eslint.ts / stylelint.ts 独立适配器,互不影响
src/adapters/jsp.ts 复用 ESLint 适配器,与 SQLFluff 无关

2.3 不受影响的功能

  • 全局配置(用户指定的 sqlfluff 配置路径):存在时完全替代内置配置,不受影响
  • 项目配置(.sqlfluff):存在时完全替代内置配置,不受影响
  • 方言映射(sql → ansiplsql → postgres):不变
  • 规则 ID 输出格式:仍为 sql-lint:{规则代码},不变
  • sqlfluff fix 自动修复能力:不变,精选规则集中 43 条(75%)仍支持自动修复

三、详细设计

3.1 修改 src/adapters/sql-lint.ts:新增内置配置

3.1.1 当前行为

当前适配器在无项目 .sqlfluff 配置文件时,不传递任何 --rules--config 参数,完全依赖 SQLFluff CLI 的默认行为(rules = all75 条全启用):

// 伪代码:当前 spawn 调用逻辑
function buildSqlfluffArgs(filePath: string, dialect: string): string[] {
    const args: string[] = ['lint', '--format', 'json'];
    // 方言映射
    args.push('--dialect', dialect === 'plsql' ? 'postgres' : 'ansi');
    // 无内置 rules 配置 —— 依赖 CLI 默认(rules = all
    // 若存在项目 .sqlfluffSQLFluff 自动发现并使用
    args.push(filePath);
    return args;
}

3.1.2 修改后:新增内置配置常量

// 新增:内置精选 .sqlfluff 配置模板(从全到精:rules = all → 57 条精选)
// P032 条 Core+ P125 条精选非 Core= 57 条
const BUILTIN_SQLFLUFF_CONFIG = `[sqlfluff]
rules = core,AM03,AM05,AM08,CV01,CV02,CV06,CV08,CV12,LT13,LT14,LT15,ST01,ST02,ST04,ST05,ST06,ST07,ST09,ST10,ST11,ST12,RF02,RF04,RF05,RF06
dialect = ansi
max_line_length = 80
indent_unit = space
tab_space_size = 4
`;

// 新增:判断是否存在项目 .sqlfluff 配置
function hasProjectSqlfluffConfig(workspaceRoot: string): boolean {
    // 检查 workspaceRoot 下是否存在 .sqlfluff 或 .sqlfluff.ini
    // ...
}

// 修改后的 spawn 调用逻辑
function buildSqlfluffArgs(
    filePath: string,
    dialect: string,
    workspaceRoot: string,
    globalConfigPath?: string
): { args: string[]; tempConfigPath?: string } {
    const args: string[] = ['lint', '--format', 'json'];
    args.push('--dialect', dialect === 'plsql' ? 'postgres' : 'ansi');

    // 三层配置优先级:全局 > 项目 > 内置
    if (globalConfigPath) {
        // 1. 全局配置:用户指定路径,完全替代内置配置
        args.push('--config', globalConfigPath);
    } else if (hasProjectSqlfluffConfig(workspaceRoot)) {
        // 2. 项目配置:.sqlfluff 存在,让 SQLFluff 自动发现(不传 --config
        // 不需要额外参数
    } else {
        // 3. 内置配置(新增):写入临时 .sqlfluff 文件,传递精选规则集
        const tempConfigPath = path.join(
            os.tmpdir(),
            `sqlfluff-builtin-${Date.now()}.cfg`
        );
        fs.writeFileSync(tempConfigPath, BUILTIN_SQLFLUFF_CONFIG);
        args.push('--config', tempConfigPath);
        return { args, tempConfigPath };
    }

    args.push(filePath);
    return { args };
}

3.1.3 设计说明

为什么用临时配置文件而非 --rules 参数?

SQLFluff CLI 支持 --rules "core,AM03,..." 参数直接指定规则列表。但使用临时 .sqlfluff 配置文件更优:

  • 支持 per-rule 配置--rules 仅能指定规则列表,无法配置 [sqlfluff:rules:CP01] 等规则参数(如大小写偏好)。临时配置文件支持完整 INI 配置
  • 与三层配置架构对齐ESLint/Stylelint 的内置配置也是完整配置对象,临时配置文件使 SQLFluff 的内置层与之对称
  • 可扩展性:未来需调整规则参数(如行长度、缩进)时,只需修改 BUILTIN_SQLFLUFF_CONFIG 字符串

为什么用 dialect = ansi 而非动态方言?

BUILTIN_SQLFLUFF_CONFIG 中的 dialect = ansi 是默认值。实际执行时,buildSqlfluffArgs 已通过 --dialect 参数覆盖方言(plsql → postgres),--dialect 命令行参数优先于配置文件中的 dialect 设置。配置文件中保留 dialect = ansi 仅作为文档性默认值。

为什么内置配置不包含方言专用规则(OR01/PG01/TQ01-03)?

方言专用规则仅对特定方言生效。当前适配器方言映射为 sql → ansiplsql → postgres,故内置配置仅覆盖通用规则。方言专用规则作为 P2 可选项,由用户在项目 .sqlfluff 中按实际方言追加。

3.2 修改 src/rules/static-rules.json:追加分级标记

3.2.1 修改内容

SQLFluff 的 75 条规则已全部收录在 static-rules.json 中。本次修改不新增规则条目(与 ESLint/Stylelint 不同——那两者是追加新规则),而是为每条规则追加 tier 分级字段,标记其在推荐体系中的归属。

// 修改前
{"id": "sql-lint/AL02", "description": "Column aliasing using explicit AS"}

// 修改后:追加 tier 字段
{"id": "sql-lint/AL02", "description": "Column aliasing using explicit AS", "tier": "P0"}
{"id": "sql-lint/AM03", "description": "ORDER BY clause direction ambiguity", "tier": "P1"}
{"id": "sql-lint/AL01", "description": "Implicit/explicit table aliasing", "tier": "P2"}
{"id": "sql-lint/AL07", "description": "Forbid table aliases in FROM/JOIN", "tier": "excluded"}

3.2.2 分级标记分配

tier 值 含义 规则数 启用状态
P0 Core 核心规则 32 内置配置启用(rules = core
P1 精选非 Core 高价值规则 25 内置配置启用(显式追加)
P2 可选规则(方言专用/团队偏好) 11 内置配置不启用,按需追加
excluded 不推荐规则(禁用/噪音/需配置) 7 内置配置排除
合计 75

3.2.3 修改 linterVersion 字段

"linterVersion": {
    "sql-lint": "4.2.2 (57 recommended)",
    ...
}

将原标记改为 "4.2.2 (57 recommended)",反映精选规则集数量。static-rules.json 中规则总数仍为 75 条(全部收录,仅分级不同)。

3.2.4 为什么必须同步更新 static-rules.json

static-rules.json 有两个用途:

  1. UI 展示:在设置面板中展示当前 linter 支持的规则清单,追加 tier 后可展示分级标识
  2. 去重检测:自定义规则导入时,按 ID 匹配 static-rules.json 中的规则。75 条规则已全部收录,去重检测范围不变,但分级标记使 UI 能区分"推荐/可选/排除"

与 ESLint/Stylelint 不同(那两者是因新增规则而必须更新去重数据),SQLFluff 的更新是分级标记追加而非规则新增,去重数据本身已完整。

3.3 不需要修改 package.json

SQLFluff 是通过 spawn('sqlfluff', ...) 调用的外部 CLI 工具,不是 npm 依赖。内置配置是纯字符串常量,不引入任何新依赖。这是 SQLFluff 适配器与 ESLint/Stylelint 适配器在依赖管理上的本质区别:

适配器 依赖管理 配置注入方式
ESLint npm 依赖(@eslint/js Flat Config 数组对象
Stylelint npm 依赖(stylelint-config-recommended 配置对象展开
SQLFluff 外部 CLI(无 npm 依赖) 临时 .sqlfluff 配置文件 / --config 参数

四、新增/排除规则分类详解

4.1 设计方向:从全到精

SQLFluff 增强与其他 linter 的根本差异:

维度 ESLint/Stylelint SQLFluff
增强方向 从少到多(recommended → 更多规则) 从全到精all → 精选规则集)
当前状态 启用少量规则(61/12 条) 无差别全启用(75 条)
增强动作 追加新规则 精选保留 + 排除噪音
规则数变化 61→92+31)、12→68+56 75→57-18,排除噪音)
static-rules.json 追加新规则条目 规则不变,追加分级标记

4.2 P0 Core 核心规则(32 条,全部保留)

Core 规则是 SQLFluff 官方标记的稳定、通用、非争议性规则。全部保留,通过 rules = core 关键字启用。

分组 规则代码 数量
Aliasing AL02, AL03, AL04, AL05, AL06, AL08, AL09, AL10 8
Ambiguous AM01, AM02, AM06 3
Capitalisation CP01, CP02, CP03, CP04, CP05 5
Convention CV03, CV04, CV05 3
Jinja JJ01 1
Layout LT01, LT02, LT05, LT06, LT07, LT08, LT10, LT11, LT12 9
Structure ST03, ST08 2
References RF01 1
合计 32

说明RF01 虽标记 force_enable = False(对 BigQuery 等方言默认禁用),但它是 Core 规则,对 ansi/postgres 方言默认生效,故保留在 P0。

4.3 P1 精选非 Core 规则(25 条,从 43 条中精选)

从 43 条非 Core 规则中精选 25 条高价值规则,按问题类型分组:

4.3.1 歧义与连接(3 条)

规则 检测场景 误报评估
AM03 ORDER BY 混合 ASC/DESC 时方向不可预期 低,显式指定方向是最佳实践
AM05 JOIN 未明确连接类型(应为 INNER/LEFT 等) 低,完全限定连接类型消除歧义
AM08 隐式 CROSS JOIN 低,隐式交叉连接几乎都是意外

4.3.2 约定一致性(5 条)

规则 检测场景 误报评估
CV01 !=<> 混用 零误报,统一运算符
CV02 使用 IFNULL/NVL 代替 COALESCE 零误报,COALESCE 是标准 SQL
CV06 语句缺少分号结尾 低,分号是语句终止符
CV08 使用 RIGHT JOIN 低,LEFT JOIN 更易读
CV12 连接条件放在 WHERE 而非 ON 低,ON 子句语义更清晰

4.3.3 结构优化(10 条,核心价值)

规则 检测场景 误报评估
ST01 CASE 中冗余的 ELSE NULL 零误报
ST02 可简化的不必要 CASE
ST04 ELSE 中嵌套 CASE 可展平
ST05 JOIN/FROM 含子查询(应提为 CTE 中,但 CTE 显著提升可维护性
ST06 SELECT 列顺序不规范
ST07 使用 USING 而非显式连接键
ST09 JOIN 列顺序不规范
ST10 WHERE 1=1 等冗余常量条件 零误报
ST11 JOIN 的表未被引用(死连接) 零误报
ST12 连续分号 零误报

4.3.4 引用规范(4 条)

规则 检测场景 误报评估
RF02 多表查询时引用未限定表名 低,限定表名消除歧义
RF04 将关键字用作标识符 零误报
RF05 标识符含特殊字符
RF06 不必要的引号标识符

4.3.5 布局整洁(3 条)

规则 检测场景 误报评估
LT13 文件以空白开头 零误报
LT14 关键字换行位置不统一
LT15 连续空行过多

与排除的格式化规则的区别LT13/LT14/LT15 关注文件结构和空行整洁,具有实际可读性价值;而被排除的 LT03/LT04/LT09 是纯风格偏好(操作符位置、逗号风格、SELECT 换行),属格式化范畴。

4.4 P2 可选规则(11 条,不纳入推荐基线)

4.4.1 方言专用规则(5 条)

规则 适用方言 说明
OR01 Oracle 移除空批次
PG01 PostgreSQL 避免过度锁(对 plsql→postgres 映射有意义)
TQ01 T-SQL 存储过程不用 SP_ 前缀
TQ02 T-SQL 过程体用 BEGIN/END
TQ03 T-SQL 移除空批次

当前适配器仅映射 ansi/postgres 两种方言,PG01 可按需启用,其余需用户切换方言。

4.4.2 团队偏好规则(6 条)

规则 检测场景 可选理由
AL01 表别名要求显式 AS 与 AL02 对称,但表别名风格因团队而异
AM04 SELECT * 与其他列混合 检测结果列数不可预测,但部分场景 SELECT * 合理
AM07 集合查询子查询列数不同 检测集合查询错误,但场景较少
AM09 无 ORDER BY 时用 LIMIT/OFFSET 检测非确定性结果,但部分场景可接受
CV07 顶层语句被括号包裹 多余括号,但部分方言需要
CV11 类型转换风格不一致 CAST/::/CONVERT 风格统一,但方言偏好不同

4.5 排除规则(7 条,明确不推荐)

规则 排除分类 排除理由
AL07 默认禁用 禁止所有表别名过于激进,force_enable = False
CV10 默认禁用 引号风格因方言而异,force_enable = False
RF03 默认禁用 列引用限定一致性争议大,force_enable = False
LT03 格式化噪音 操作符换行位置是纯风格偏好
LT04 格式化噪音 前导/尾随逗号是团队风格选择
LT09 格式化噪音 SELECT 目标换行是格式偏好
CV09 需项目配置 需自定义禁止词列表,无通用默认

五、规则级别设计

5.1 级别设计原则:精选而非分级

SQLFluff 与 ESLint/Stylelint 的级别设计有本质区别:

维度 ESLint/Stylelint SQLFluff
级别机制 per-rule error/warnESLint)或 trueStylelint 无 per-rule error/warn,仅启用/排除
级别设计核心 区分 error 与 warn 精选规则集(从全到精)
噪音控制方式 低价值规则设为 warn 低价值规则直接排除

SQLFluff 不支持像 ESLint 那样的 per-rule error/warn 级别配置。因此,SQLFluff 适配器的"级别设计"通过规则集精选实现:将高价值规则纳入推荐基线,将噪音规则排除,从源头控制审查信噪比。

5.2 P0/P1/P2 分级与启用策略

分级 启用策略 规则数 严重程度定位
P0 rules = core 自动启用 32 高(核心稳定性问题)
P1 显式追加规则代码 25 高(歧义/结构/引用问题)
P2 不纳入推荐基线,按需追加 11 中(方言/偏好)
excluded 不启用 7 —(噪音/争议/需配置)

5.3 适配器层面的严重级别映射

虽然 SQLFluff 无 per-rule severity,但适配器在解析 CLI 输出后,可基于 static-rules.json 中的 tier 字段映射到 VS Code 的 DiagnosticSeverity

tier VS Code DiagnosticSeverity 说明
P0 Error 核心规则触发,几乎一定是问题
P1 Error 高价值规则触发,强烈建议修复
P2 Warning(若启用) 可选规则触发,建议但不强制
excluded 不触发(规则未启用)

此映射为可选增强。当前适配器将所有 SQLFluff 诊断映射为统一严重级别,未来可按 tier 细化。

5.4 自动修复能力统计

分级 规则数 可自动修复 自动修复率
P0 Core 32 24 75%
P1 精选 25 19 76%
推荐基线合计 57 43 75%
P2 可选 11 7 64%
excluded 7 6 86%

推荐基线 57 条规则中 43 条(75%)支持 sqlfluff fix 自动修复。排除的 7 条规则中虽有 6 条可修复,但因属噪音/争议规则,修复后仍会引入风格争议,故排除。


六、兼容性分析

6.1 对现有用户代码的影响

rules = all(75 条)精简为 57 条精选规则集后,审查诊断数量将减少(而非增加,与 ESLint/Stylelint 相反):

影响程度 规则 说明
诊断减少 LT03, LT04, LT09 排除格式化噪音,减少大量低价值诊断
诊断减少 AL07, CV10, RF03 排除默认禁用规则(原本因 force_enable 不生效)
诊断减少 CV09 排除需项目配置的规则
诊断不变 P0 + P157 条) 推荐基线规则与 all 模式下行为一致
可能新增(可选) P2 方言规则 用户按需启用后,对应方言新增诊断

核心收益:排除格式化噪音规则后,审查结果信噪比显著提升,真正的问题不再被格式化诊断淹没。

6.2 对配置优先级的影响

三层配置优先级不变:

全局配置(linters.sqlfluffConfigPath
    ↓ 不存在
项目配置(.sqlfluff / .sqlfluff.ini
    ↓ 不存在
内置配置(BUILTIN_SQLFLUFF_CONFIG57 条精选)  ← 新增
    ↓ (此前为 CLI 默认 rules = all

新增内置配置层替代了原先的"CLI 默认"层,三层择一逻辑不变。

6.3 对去重功能的影响

static-rules.json 中 SQLFluff 规则仍为 75 条(全部收录),去重检测范围不变。新增的 tier 字段不影响去重匹配逻辑,仅用于 UI 分级展示。

6.4 对自动修复的影响

  • 推荐基线 57 条规则中 43 条支持 sqlfluff fix
  • 适配器的自动修复调用不受影响(仍通过 sqlfluff fix 命令)
  • 排除的格式化规则原本可修复,但修复属风格偏好,排除后用户可自行用格式化工具处理

6.5 方言兼容性

方言映射 内置配置适用性 方言专用规则
sql → ansi 完全适用(57 条均为通用规则)
plsql → postgres 完全适用 PG01 可选启用

七、与 ESLint/Stylelint/ts-eslint 适配器的架构对比

7.1 架构对比总览

维度 ESLint 适配器 Stylelint 适配器 SQLFluff 适配器
Linter 类型 npm 库(进程内调用) npm 库(进程内调用) 外部 CLIspawn 调用)
增强方向 从少到多(61→92 从少到多(12→68 从全到精(75→57
官方配置基线 @eslint/js recommended stylelint-config-recommended rules = core 关键字
额外规则来源 eslint 内置规则 stylelint 内置规则 SQLFluff 内置规则(CLI
配置注入方式 Flat Config 数组追加 配置对象展开 临时 .sqlfluff 文件 + --config
级别支持 error/warn true(仅 error 无 per-rule 级别(启用/排除)
噪音控制 低价值规则设为 warn 全部 true 低价值规则直接排除
npm 依赖变更 新增 @eslint/js 新增 stylelint-config-recommended 无(外部 CLI
static-rules.json 变更 追加 31 条新规则 追加 27 条新规则 规则不变,追加 tier 标记
配置优先级 全局 > 项目 > 内置 全局 > 项目 > 内置 全局 > 项目 > 内置
规则 ID 格式 eslint:{ruleId} stylelint:{ruleName} sql-lint:{规则代码}

7.2 关键差异分析

差异一:增强方向相反

  • ESLint/Stylelint:当前启用规则过少(31%/8.5%),增强方向是追加规则提升覆盖率
  • SQLFluff:当前无差别全启用(100%),增强方向是精选规则提升信噪比

这决定了 SQLFluff 的增强不是"做加法"而是"做减法"——从 75 条精简为 57 条,排除 18 条低价值/噪音规则。

差异二:配置注入方式不同

  • ESLint/Stylelintnpm 库,配置为 JS 对象/数组,进程内直接传入
  • SQLFluff:外部 CLI,配置需写入临时文件并通过 --config 参数传递

SQLFluff 适配器需额外处理临时配置文件的生命周期(创建、传递、清理)。

差异三:无 per-rule 严重级别

  • ESLint 支持 error/warn 两级,Stylelint 支持 true/null
  • SQLFluff 仅支持启用/排除,无 per-rule 严重级别

因此 SQLFluff 的"级别设计"通过规则集精选实现,而非 error/warn 分配。低价值规则直接排除,而非降级为 warning。

差异四:static-rules.json 变更性质不同

  • ESLint/Stylelint:新增规则条目(去重数据扩展)
  • SQLFluff:规则条目不变(75 条已全收录),追加 tier 分级标记

7.3 架构一致性

尽管实现方式不同,三个适配器在设计理念上保持一致:

设计理念 ESLint Stylelint SQLFluff
官方配置作为基线 recommended recommended core
精选额外规则 extraRules 对象 extraRules 对象 rules 显式追加
三层配置优先级 全局 > 项目 > 内置 全局 > 项目 > 内置 全局 > 项目 > 内置
同步更新 static-rules.json 是(追加规则) 是(追加规则) 是(追加 tier
规则 ID 前缀不变 eslint: stylelint: sql-lint:

八、实施步骤

步骤 1:修改 src/adapters/sql-lint.ts

  1. 在文件顶部添加 BUILTIN_SQLFLUFF_CONFIG 常量(精选 57 条规则的 INI 配置字符串)
  2. 添加 hasProjectSqlfluffConfig() 辅助函数,检测项目 .sqlfluff 配置文件
  3. 修改 buildSqlfluffArgs()(或等效的参数构建逻辑),实现三层配置优先级:
    • 全局配置存在 → 传递 --config <全局路径>
    • 项目配置存在 → 不传 --config,让 SQLFluff 自动发现
    • 均不存在 → 写入临时配置文件,传递 --config <临时路径>
  4. 在 spawn 完成后(或 finally 块中)清理临时配置文件

步骤 2:修改 src/rules/static-rules.json

  1. 为 75 条 SQLFluff 规则条目追加 tier 字段(P0/P1/P2/excluded
  2. 更新 linterVersion.sql-lint"4.2.2 (57 recommended)"

步骤 3:验证

  1. 确认无项目 .sqlfluff 时,临时配置文件正确生成并被 SQLFluff 使用
  2. 确认有项目 .sqlfluff 时,内置配置不生效(项目配置优先)
  3. 确认全局配置路径存在时,内置配置不生效(全局配置优先)
  4. 确认临时配置文件在 spawn 完成后被清理
  5. 检查 static-rules.json 中 75 条规则均有 tier 字段

九、测试要点

9.1 单元测试

测试项 验证内容
BUILTIN_SQLFLUFF_CONFIG 内容 包含 rules = core 及 25 条 P1 规则代码
BUILTIN_SQLFLUFF_CONFIG 规则数 core32+ 显式追加(25= 57 条
临时配置文件生成 无项目配置时正确写入临时文件
临时配置文件清理 spawn 完成后临时文件被删除
三层优先级 全局 > 项目 > 内置,择一逻辑正确

9.2 集成测试

测试项 验证内容
无配置时使用精选规则集 诊断结果仅包含 57 条推荐规则,不包含 LT03/LT04/LT09
项目 .sqlfluff 存在时使用项目配置 诊断结果遵循项目配置,内置配置不生效
全局配置存在时使用全局配置 诊断结果遵循全局配置,内置配置不生效
WHERE 1=1 触发 ST10 诊断结果包含 sql-lint:ST10
CASE ... ELSE NULL END 触发 ST01 诊断结果包含 sql-lint:ST01
未使用的 CTE 触发 ST03 诊断结果包含 sql-lint:ST03
= NULL 触发 CV05 诊断结果包含 sql-lint:CV05
格式化噪音规则不触发 LT03/LT04/LT09 不产生诊断

9.3 去重测试

测试项 验证内容
导入 ST05 自定义规则 提示与已有规则重复(75 条已收录)
导入 CV05 自定义规则 提示与已有规则重复
tier 字段不影响去重 去重匹配逻辑仅按 ID,与 tier 无关

9.4 自动修复测试

测试项 验证内容
sqlfluff fix 修复 ST01 ELSE NULL 被移除
sqlfluff fix 修复 CP01 关键字大小写统一
sqlfluff fix 修复 CV05 = NULL 改为 IS NULL
排除规则不被修复 LT03/LT04/LT09 不触发修复

十、风险评估

10.1 主要风险

风险 级别 缓解措施
临时配置文件未清理导致残留 在 finally 块中确保清理,使用 os.tmpdir() 避免污染工作区
用户依赖 rules = all 的全量诊断 用户可通过项目 .sqlfluff 设置 rules = all 恢复原行为
精选规则集遗漏用户需要的高价值规则 P2 可选规则可按需追加,用户可自行在项目配置中启用
--config 参数与 --dialect 参数冲突 --dialect 命令行参数优先级高于配置文件,已验证不冲突
SQLFluff 版本升级导致规则代码变化 锁定 SQLFluff 4.2.2,规则代码在 4.x 内稳定

10.2 与 ESLint/Stylelint 的风险差异

风险类型 ESLint/Stylelint SQLFluff
诊断数量变化 增加(新增规则) 减少(排除噪音)
用户感知 可能新增大量诊断 诊断减少,信噪比提升
回滚复杂度 需移除新增规则和依赖 仅需移除内置配置注入,恢复 CLI 默认

SQLFluff 的增强风险显著低于 ESLint/Stylelint:诊断数量减少而非增加,不会引入用户未曾见过的诊断,仅是减少噪音。

10.3 回滚方案

如果精选规则集导致问题,回滚步骤:

  1. buildSqlfluffArgs() 中移除内置配置注入逻辑,恢复"无配置时使用 CLI 默认(rules = all"
  2. 删除 BUILTIN_SQLFLUFF_CONFIG 常量
  3. static-rules.json 中的 tier 字段可保留(不影响功能,仅用于 UI 展示)
  4. 恢复 linterVersion.sql-lint"4.2.2 (75 rules, all)"

回滚仅需修改适配器代码,无需修改依赖(因本就无 npm 依赖变更)。


十一、附录

11.1 规则来源参考

11.2 规则数量统计

分类 数量 tier 启用状态
P0 Core 核心规则 32 P0 内置配置启用
P1 精选非 Core 25 P1 内置配置启用
P2 方言专用 5 P2 按需启用
P2 团队偏好 6 P2 按需启用
excluded 默认禁用 3 excluded 排除
excluded 格式化噪音 3 excluded 排除
excluded 需项目配置 1 excluded 排除
合计 75 推荐基线 57 条

11.3 内置配置模板(完整)

[sqlfluff]
# 从全到精:rules = all(75 条)→ 精选规则集(57 条)
# P032 条 Core+ P125 条精选非 Core
rules = core,AM03,AM05,AM08,CV01,CV02,CV06,CV08,CV12,LT13,LT14,LT15,ST01,ST02,ST04,ST05,ST06,ST07,ST09,ST10,ST11,ST12,RF02,RF04,RF05,RF06
dialect = ansi
max_line_length = 80
indent_unit = space
tab_space_size = 4

11.4 P1 精选规则完整列表(25 条)

# 规则代码 规则名 分组 可修复
1 AM03 ambiguous.order_by Ambiguous Fix
2 AM05 ambiguous.join Ambiguous Fix
3 AM08 ambiguous.join_condition Ambiguous Fix
4 CV01 convention.not_equal Convention Fix
5 CV02 convention.coalesce Convention Fix
6 CV06 convention.terminator Convention Fix
7 CV08 convention.left_join Convention
8 CV12 convention.join_condition Convention Fix
9 LT13 layout.start_of_file Layout Fix
10 LT14 layout.keyword_newline Layout Fix
11 LT15 layout.newlines Layout Fix
12 ST01 structure.else_null Structure Fix
13 ST02 structure.simple_case Structure Fix
14 ST04 structure.nested_case Structure Fix
15 ST05 structure.subquery Structure Fix
16 ST06 structure.column_order Structure Fix
17 ST07 structure.using Structure Fix
18 ST09 structure.join_condition_order Structure Fix
19 ST10 structure.constant_expression Structure
20 ST11 structure.unused_join Structure
21 ST12 structure.consecutive_semicolons Structure Fix
22 RF02 references.qualification References
23 RF04 references.keywords References
24 RF05 references.special_chars References
25 RF06 references.quoting References Fix

11.5 排除规则完整列表(7 条)

# 规则代码 规则名 排除分类 原标记
1 AL07 aliasing.forbid 默认禁用 Fix / 禁用
2 CV10 convention.quoted_literals 默认禁用 Fix / 禁用
3 RF03 references.consistent 默认禁用 Fix / 禁用
4 LT03 layout.operators 格式化噪音 Fix
5 LT04 layout.commas 格式化噪音 Fix
6 LT09 layout.select_targets 格式化噪音 Fix
7 CV09 convention.blocked_words 需项目配置

11.6 与其他适配器增强对比总结

对比项 ESLint Stylelint SQLFluff
增强方向 从少到多 从少到多 从全到精
规则数变化 61 → 92+31 12 → 68+56 75 → 57-18
增强动作 追加规则 追加规则 + 引入配置包 精选保留 + 排除噪音
诊断影响 增加 增加 减少(信噪比提升)
npm 依赖 新增 @eslint/js 新增 stylelint-config-recommended
配置注入 Flat Config 对象 配置对象展开 临时配置文件
static-rules.json 追加新规则 追加新规则 追加 tier 标记
风险等级 中(诊断增加) 中(诊断增加) 低(诊断减少)