Skip to content

Meta: Close the remaining practical parity gaps between sqruff and SQLFluff #2498

@gvozdvmozgu

Description

@gvozdvmozgu

This issue tracks the remaining work needed for sqruff to reach practical parity with sqlfluff, based on a repo-to-repo comparison of code, tests, docs, CLI, config, dialects, rules, parsing, templating, fixing behavior, and developer tooling.

Legend: P0 = blocks practical parity, P1 = important follow-up for stable parity, P2 = nice-to-have ecosystem parity.

Snapshot

Surface sqruff sqlfluff
Rules 69 73
Missing rules OR01, TQ01, TQ02, TQ03 n/a
Dialects 14 28
Missing dialects db2, doris, exasol, flink, greenplum, hive, impala, mariadb, materialize, oracle, soql, starrocks, teradata, vertica n/a
Default visible templaters in current CLI build raw, placeholder core: raw, jinja, python, placeholder; repo also contains the dbt plugin
Default config templater = raw, rules = core templater = jinja, rules = all
Rule fixture drift 9 SQLFluff fixture files missing, 63 shared fixture files differ source of truth

Must-Have Parity Work

  • P0 Ship SQLFluff’s practical command set in the default sqruff CLI.
    Where: crates/cli-lib/src/commands.rs, crates/cli-lib/src/commands_parse.rs, new render/format command implementations, crates/cli/Cargo.toml, docs/reference/cli.md.
    SQLFluff reference: src/sqlfluff/cli/commands.py, docs/source/reference/cli.rst, test/cli/test_parse_with_positions.py.
    Why it matters: the current default sqruff binary exposes lint, fix, lsp, info, rules, dialects, and templaters; parse exists only behind a non-default feature, and there is no render or format.
    Acceptance criteria: the published/default CLI exposes parse, render, and format; sqruff --help matches the shipped feature set; CLI docs are generated from that same build.

  • P0 Bring lint/fix option parity to SQLFluff’s day-to-day workflow.
    Where: crates/cli-lib/src/commands.rs, crates/cli-lib/src/commands_lint.rs, crates/cli-lib/src/commands_fix.rs, crates/cli-lib/src/formatters/*.
    SQLFluff reference: src/sqlfluff/cli/commands.py, test/cli/commands_test.py, test/cli/formatters_test.py.
    Why it matters: sqruff currently lacks core flags and formats users rely on, including --rules, --exclude-rules, --templater, --stdin-filename, --ignore-local-config, --disable-noqa-except, --nofail, --processes, --write-output, --annotation-level, --check, --fixed-suffix, --show-lint-violations, --FIX-EVEN-UNPARSABLE, plus yaml, sarif, github-annotation, and none output formats.
    Acceptance criteria: those flags and formats exist or have an equivalent supported mapping; exit code semantics match SQLFluff for lint/fix/parse flows; formatter tests cover the added output modes.

  • P0 Make shared default config behavior match SQLFluff.
    Where: crates/lib/src/core/default_config.cfg, crates/lib/src/core/config.rs.
    SQLFluff reference: src/sqlfluff/core/default_config.cfg, docsv/configuration/defaults.md.
    Why it matters: current defaults diverge in user-visible ways, including templater = raw vs jinja, rules = core vs all, and sql_file_exts missing .pkb.
    Acceptance criteria: shared defaults match SQLFluff unless an intentional divergence is documented; currently missing shared keys and sections are implemented, including disable_noqa_except, processes, recursion_limit, render_variant_limit, implicit_indents, ignore_comment_lines, skip_implicit_indents_in, bind_variable, column_path_operator, match_condition, and slash.

  • P0 Complete config file discovery, merging, and inline config directive parity.
    Where: crates/lib/src/core/config.rs, crates/cli-lib/src/lib.rs, docs/usage/configuration.md.
    SQLFluff reference: src/sqlfluff/core/config/loader.py, src/sqlfluff/core/config/file.py, test/core/config/loader_test.py, docsv/configuration/index.md.
    Why it matters: sqruff currently loads .sqlfluff/.sqruff from the tree but not setup.cfg, tox.ini, pep8.ini, or pyproject.toml, and process_inline_config() is still panic!("Not implemented").
    Acceptance criteria: config precedence matches SQLFluff’s documented search order; pyproject.toml works; -- sqlfluff:... inline directives work and are tested.

  • P0 Bring ignore file behavior to SQLFluff parity.
    Where: crates/cli-lib/src/ignore.rs, crates/lib/src/core/linter/core.rs, config docs.
    SQLFluff reference: docsv/configuration/ignoring.md, test/core/linter/discovery_test.py, test/fixtures/config/*.
    Why it matters: sqruff currently reads a single root .sqruffignore, while SQLFluff supports .sqlfluffignore files in subdirectories and ignore_paths in pyproject.toml.
    Acceptance criteria: nested ignore files work; .sqlfluffignore compatibility exists for migration; ignore_paths works; CLI behavior can honor or bypass ignore handling like SQLFluff.

  • P0 Ship Jinja, Python, and dbt templating as a supported user-facing path, not just as docs or optional internals.
    Where: crates/lib/src/templaters.rs, crates/lib/src/templaters/*, crates/cli-python/*, packaging in crates/cli/Cargo.toml and crates/cli-python/pyproject.toml, docs/reference/templaters.md.
    SQLFluff reference: src/sqlfluff/core/templaters/*, plugins/sqlfluff-templater-dbt/*, docs/source/configuration/templating/*.rst.
    Why it matters: the current default Rust CLI only reports raw and placeholder, while sqruff docs describe raw, placeholder, python, jinja, and dbt.
    Depends on: default-config parity.
    Acceptance criteria: the supported install path exposes Jinja/Python/dbt predictably; sqruff templaters and docs agree; the default templater story is aligned with SQLFluff or explicitly documented as a deliberate non-parity choice.

  • P0 Align Jinja/dbt config keys and finish the currently unimplemented templater path handling.
    Where: crates/lib/src/core/config.rs, crates/lib/src/templaters/python_shared.rs, crates/lib/src/templaters/jinja.rs, crates/lib/src/templaters/dbt.rs.
    SQLFluff reference: src/sqlfluff/core/templaters/jinja.py, src/sqlfluff/core/config/file.py, docsv/configuration/templating/jinja.md, docsv/configuration/templating/dbt.md.
    Why it matters: sqruff docs use SQLFluff-style keys such as load_macros_from_path and library_path, but ConfigLoader currently unimplemented!()s load_macros_from_path, and PythonFluffConfig reads different internal keys such as templater_paths and library_paths.
    Acceptance criteria: SQLFluff config names work end-to-end; path values resolve relative to config files correctly; dbt project/profile/target/context options behave like SQLFluff; templater docs match the actual config schema.

  • P0 Close the unsupported dialect gap.
    Where: crates/lib-dialects/src, crates/lib-dialects/test/fixtures/dialects, docs/reference/dialects.md.
    SQLFluff reference: src/sqlfluff/core/dialects/__init__.py, test/fixtures/dialects/*, docs/source/reference/dialects.rst.
    Why it matters: sqruff supports 14 dialects while SQLFluff supports 28; missing dialects are db2, doris, exasol, flink, greenplum, hive, impala, mariadb, materialize, oracle, soql, starrocks, teradata, and vertica.
    Acceptance criteria: each missing dialect has parser support, docs, and fixture coverage, or an explicitly linked deferral issue.

  • P0 Catch up supported dialect fixtures to SQLFluff’s current corpus.
    Where: crates/lib-dialects/test/fixtures/dialects, crates/lib-dialects/tests/dialects.rs, .hacking/dialect_sqlfluff_catchup/main.py.
    SQLFluff reference: test/fixtures/dialects/*.
    Why it matters: even supported dialects are still behind. Current .sql fixture drift vs SQLFluff is ansi 11 missing / 3 changed, athena 0 / 1, bigquery 36 / 13, clickhouse 9 / 3, databricks 24 / 6, duckdb 32 / 1, mysql 203 / 1, postgres 46 / 26, redshift 9 / 7, snowflake 52 / 51, sparksql 7 / 7, sqlite 18 / 6, trino 8 / 1, and tsql 155 / 5.
    Depends on: dialect implementation work.
    Acceptance criteria: shared dialect fixture directories match SQLFluff’s .sql corpus except for explicitly reviewed divergences; the catch-up workflow is repeatable in CI or release checks.

  • P0 Implement the remaining SQLFluff rules: OR01, TQ01, TQ02, and TQ03.
    Where: new rule modules and registry wiring under crates/lib/src/rules/*, generated rule docs, rule fixtures.
    SQLFluff reference: src/sqlfluff/rules/oracle/OR01.py, src/sqlfluff/rules/tsql/TQ01.py, src/sqlfluff/rules/tsql/TQ02.py, src/sqlfluff/rules/tsql/TQ03.py, test/fixtures/rules/std_rule_cases/OR01.yml, TQ01.yml, TQ02.yml, TQ03.yml.
    Why it matters: sqruff is at 69 of SQLFluff’s 73 rules, and the missing rules are part of dialect-specific practical parity.
    Depends on: Oracle/TSQL dialect coverage.
    Acceptance criteria: the rules appear in sqruff rules, support config selection, have generated docs, and pass the corresponding YAML fixture suites.

  • P0 Bring rule selection and noqa reference resolution to SQLFluff parity.
    Where: crates/lib/src/core/rules.rs, crates/lib/src/core/rules/noqa.rs, CLI/config selection surfaces.
    SQLFluff reference: test/core/rules/noqa_test.py, src/sqlfluff/core/rules/reference.py, env/bin/python -m sqlfluff rules.
    Why it matters: SQLFluff supports legacy alias codes, rule names, groups, and glob expansion in noqa and rule selection; sqruff currently only tests direct codes and still carries TODOs around warnings and unused directives.
    Acceptance criteria: legacy L0xx aliases, named/group references, and glob patterns work consistently in config, CLI selection, and noqa; warn_unused_ignores and disable_noqa_except behave like SQLFluff and are tested.

  • P1 Refresh the copied rule fixture corpus and keep it synchronized.
    Where: crates/lib/test/fixtures/rules/std_rule_cases, crates/lib/tests/rules.rs.
    SQLFluff reference: test/fixtures/rules/std_rule_cases/*.yml.
    Why it matters: sqruff is missing 9 SQLFluff rule fixture files (AL02_LT01.yml, AL05_CV12.yml, AL09.yml, CP02_LT01.yml, LT02-indent-oracle.yml, OR01.yml, TQ01.yml, TQ02.yml, TQ03.yml) and 63 shared fixture files currently differ.
    Depends on: rule and dialect work where applicable.
    Acceptance criteria: shared fixture files are synchronized; local-only fixture variants are documented; the rule harness covers the same cases SQLFluff uses for shared rules.

  • P1 Port the missing config, parser, linter, templater, reflow, and CLI test suites.
    Where: crates/lib/tests, crates/cli/tests, new tests under crates/lib-core/tests or equivalent.
    SQLFluff reference: test/core/config/*, test/core/parser/*, test/core/linter/*, test/core/templaters/*, test/utils/reflow/*, test/cli/*, test/fixtures/linter/*, test/fixtures/templater/*.
    Why it matters: sqruff has strong rule and dialect harnesses, but the remaining coverage is still much narrower than SQLFluff’s. For example, crates/lib/test/fixtures/templaters currently contains only jinja_a, and crates/lib/test/fixtures/linter has 4 samples versus SQLFluff’s much broader fixture set.
    Acceptance criteria: each major SQLFluff test area has an owned sqruff equivalent; missing templater and linter fixture families are ported; config/parser/reflow regressions are caught without relying only on rule fixtures.

  • P1 Match SQLFluff’s fix safety and edge-case behavior.
    Where: crates/cli-lib/src/commands_fix.rs, crates/lib/src/core/linter/*, crates/lib/src/utils/reflow/*.
    SQLFluff reference: test/core/linter/fix_test.py, test/rules/std_fix_auto_test.py, test/fixtures/linter/autofix, sqlfluff fix --help.
    Why it matters: SQLFluff exposes explicit safety controls for fixing parse and templating failures, suffix-based writes, and deferred apply flows; sqruff currently writes fixes directly and lacks the matching control surface.
    Depends on: CLI option parity.
    Acceptance criteria: --FIX-EVEN-UNPARSABLE, --check, and --fixed-suffix work; fix behavior around parse/templating failures matches SQLFluff’s safety model; autofix fixtures cover those flows.

  • P1 Bring the docs to parity with shipped behavior and fill the biggest missing user/operator guides.
    Where: docs/*, docs generation in crates/cli-lib/src/docs*.
    SQLFluff reference: docsv/configuration/*, docsv/usage/*, docsv/development/*, docs/source/reference/api.rst.
    Why it matters: sqruff docs currently omit large parts of SQLFluff’s guidance and also contain live mismatches with the shipped CLI, especially around templater availability and config keys.
    Acceptance criteria: docs no longer describe unsupported defaults or keys; add missing sections for defaults, layout/rule configuration, templating, ignoring, CI/pre-commit/team rollout/troubleshooting, and contributor guides for dialects/rules/plugins, or explicitly document intentional non-goals.

Nice-To-Have Improvements

  • P2 Add plugin and extensibility parity.
    Where: new plugin host/registry modules, packaging entry points, example plugin(s), docs.
    SQLFluff reference: src/sqlfluff/core/plugin/*, plugins/sqlfluff-plugin-example, plugins/sqlfluff-templater-dbt, pyproject.toml entry points.
    Why it matters: SQLFluff’s plugin system lets users ship rules and templaters without forking. That is not required for immediate practical parity, but it matters for ecosystem growth and dbt/plugin expectations.
    Acceptance criteria: sqruff can discover external rule/templater plugins; there is an example plugin and contributor documentation; plugin defaults can merge into config cleanly.

  • P2 Add ecosystem integrations: pre-commit, diff-quality, and shell completion/autocomplete.
    Where: packaging/entry points, .pre-commit-*, docs, CLI completion generation.
    SQLFluff reference: .pre-commit-config.yaml, .pre-commit-hooks.yaml, src/sqlfluff/diff_quality_plugin.py, test/cli/autocomplete_test.py, docs/source/production/pre_commit.rst, docs/source/production/diff_quality.rst.
    Why it matters: these are not parser/linter blockers, but they materially affect adoption in CI and editor workflows.
    Acceptance criteria: reusable pre-commit hooks exist; changed-lines-only integration exists via diff-quality or an equivalent; shell completion is documented and tested.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions