Repository navigation
v0.7.0 is the headline release for the Contracts theme: schema-aware linting via the new C001-C005 rule pack, two new CLI subcommands, and three community-contributed rules. No breaking changes. Without --contract the tool behaves identically to v0.6.x.
Highlights
Contracts pack (C001-C005)
Declare your expected schema in YAML and lint queries against it:
sql-sop check . --contract contract.yml
The five new rules:
- C001
column-not-in-contract(warning) — SQL references a column that is not declared in the contract for that table. - C002
table-not-in-contract(warning) — statement touches a table not declared in the contract. - C003
not-null-violation(error) — INSERT omits a column the contract marks as NOT NULL with no default. - C004
primary-key-missing-on-insert(error) — INSERT omits a primary-key column that has no default. - C005
unmapped-fk(warning) — JOIN predicate uses two columns the contract has no foreign-key relationship for.
Contract format is a thin subset of the open data-contract spec. Contract path can also live in .sql-guard.yml via a contract: field.
New subcommands
Bootstrap a contract from a live database (requires sql-sop[snapshot]):
sql-sop schema-snapshot --dsn "mssql+pyodbc://..." --output contract.yml
Validate the YAML before running rules (CI-friendly):
sql-sop validate-contract --contract contract.yml
schema-snapshot introspects tables, columns, PKs, FKs, and nullable flags via SQLAlchemy. validate-contract exits non-zero on parse failure, so a malformed contract fails fast in CI.
Community-contributed rules
- W014
case-without-else— warns when aCASE ... ENDblock has noELSEbranch. Walks token-by-token tracking nesting. Contributed by @hellozzm in #32. - W015
join-function-on-column— JOIN-side companion to W003. CatchesJOIN ... ON UPPER(o.email) = UPPER(c.email)patterns that defeat indexes. Contributed by @mvanhorn in #33. - W022
cross-join-explicit— flags explicitCROSS JOIN. Strips trailing line comments before matching. Contributed by @vibeyclaw in #31. - W023
scalar-udf-in-where— warns on schema-prefixed UDF calls inWHERE/HAVING/ONclauses, the canonical T-SQL scalar-UDF anti-pattern. Contributed by @mvanhorn in #34. Resolves #30.
Rule counts
- Core registry: 43 rules (10 errors, 28 warnings, 5 Python-source)
- With
--contract: 48 rules (12 errors, 31 warnings, 5 Python-source)
Backwards compatibility
No breaking changes. All Contracts-pack rules require an explicit --contract flag (or contract: field in .sql-guard.yml); silent without it. The [snapshot] extra is opt-in via pip install "sql-sop[snapshot]" so SQLAlchemy stays out of the core install.
Install
pip install sql-sop==0.7.0
For the schema-snapshot subcommand: pip install "sql-sop[snapshot]==0.7.0"
For the pre-commit hook, set rev: v0.7.0 in your .pre-commit-config.yaml.
What's Changed
- feat(rules): add W023 scalar-udf-in-where by @mvanhorn in #34
- feat(rules): add W015 join-function-on-column by @mvanhorn in #33
- feat: add W014 case-without-else rule by @hellozzm in #32
- feat: add W022 cross-join-explicit rule by @vibeyclaw in #31
- feat: contracts pack (C001-C005) + schema-snapshot + validate-contract subcommands by @Pawansingh3889 in #35
- chore: release v0.7.0 contracts pack, schema-snapshot, validate-contract by @Pawansingh3889 in #36
New Contributors
- @hellozzm made their first contribution in #32
- @vibeyclaw made their first contribution in #31
Full Changelog: v0.6.2...v0.7.0