Skip to content

feat(rules): DOL041 — planner settings overridden in raw SQL (SET enable_hashjoin = off) #110

Description

@dtduc-git

Summary

Proposal for a new editor rule that flags application code overriding the Postgres query planner via connection-scoped SET commands.

Motivation

A production incident class that static review keeps missing: a view toggled enable_hashjoin and enable_mergejoin off on the connection before running a query whose filtered row set grows over time. Postgres then had no choice but to satisfy the query with nested-loop joins — progressively slower as the data grew — and neither code review nor an AI reviewer flagged the diff, because the diff looks innocent in isolation.

Two reasons this fits the rule engine well:

  • It's pure string shape — the GUC name is in the SQL text even when the value is a bind parameter (%s), so the line-oriented regex engine can catch it with no AST and no Python process.
  • It is invisible to the CLI analyzers too: nplusone, suggest-indexes, and migration-risk don't look at raw SQL session commands.

Proposed rule

  • Code: DOL041, category performance, default severity warning, applicability unsafe (no QuickFix — the fix is a design decision).
  • Detects: SET / SET LOCAL / SET SESSION of planner-toggling GUCs — enable_* (hashjoin, mergejoin, nestloop, seqscan, indexscan, …), plan_cache_mode, jit* — inside any line, including inside cursor.execute(...) strings.
  • Does not flag: non-planner session settings (statement_timeout, search_path, work_mem, …) — those have legitimate per-request uses and would make the rule noisy.
  • Non-goal for this PR: the CLI counterpart — the roadmap already tracks porting the DOL engine into the Python CLI (one catalogue, three surfaces), so this lands editor-side first and rides that work later.

Test plan

Regex + fixtures in test/rules/rawsql.test.js, mirroring test/rules/queryset.test.js: parameterized and literal values, SET LOCAL/SET SESSION variants, TO form, and negative cases.

Happy to send the PR if this is in scope.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions