Repository navigation
feat: check enum literals at compile time and fix rule helper and slot checks - #1258
Merged
Merged
Conversation
evaluate_rule copied only the rule's own file into its temporary project, so a rule importing a helper under rules/ failed to load in its tests. When the rule file belongs to a project's rules/ directory, the harness now copies that directory, as sqb compile sees it, keeping symlinks as links and leaving out bytecode and dot-directories such as tool caches. The rule under test is still written last, so a RuleCase file cannot replace it. An integration test runs a project's rule tests in a pytest subprocess under the prepend and importlib import modes, and the testing docs describe the pytest configuration importlib needs.
…compile time An enum-typed column of an enforced contract was only checked by its generated accepted_values audit, so a union branch filling it with a string that is not an enum member compiled cleanly and failed after the build. sqb compile now reports K013 for each constant string literal that fills such a column, written directly, in any UNION branch, or passed through a CTE or derived table, naming the value, the model and the enum and pointing at the projected literal. The check never fires where the audit could pass: it stops at a passthrough read through a filter, join or row limit, at EXCEPT and INTERSECT, and at a positional read of a by-name union, and it is skipped on SQL Server, whose default collation ignores case and trailing spaces. Computed values stay with the audit. Rules can read each declared column's enum with ctx.columns.enum_types(model); declared column types are unchanged. The new fact is tracked for the Rules cache and invalidated by header column edits.
…checks The output-select walk shared the capture walk's scope classification, which treats a LATERAL subquery as an expression, so a mapped single-column slot read without AS inside a LATERAL whose columns reach the output through l.* escaped the AS rule. The output walk now treats every FROM and JOIN item, LATERAL included, like a derived table; the capture check is unchanged. The P018 clash check counted only bare columns beside a group, so an undeclared column read through the relation, such as @weekly.region, next to a group holding the same column produced a duplicate output column. Such reads now count as output columns.
…es not declare A forwarded aliased slot read whose slot the outer macro's relation does not declare compiles and reads the column through the alias, without a P022 at the outer macro.
kvlonge
enabled auto-merge (squash)
October 26, 2026 06:09
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
evaluate_rulecopied only the rule's own file, so a rule importing a shared helper underrules/could not be tested.accepted_valuesaudit after the build.LATERALsubqueries escaped theASrule, andP018missed a relation-qualified read such as@weekly.regionbeside a group holding the same column.Changes
rules/directory, the harness copies that directory (symlinks kept, caches and dot-directories skipped) and writes the rule under test last. The testing docs cover thepythonpathsetting--import-mode=importlibneeds.K013contract error: for an enforced contract, every constant string literal that fills an enum-typed column must be a member of the enum. This covers a literal written directly, one in anyUNIONbranch, and one passed through a CTE or derived table. The error names the value, model and enum, and points at the projected literal. To avoid errors where the audit would pass, passthroughs through a filter, join or row limit,EXCEPTand by-name positions are not followed, and SQL Server is skipped. Computed values stay with the audit.ctx.columns.enum_types(model)maps each enum-typed column to its enum for Rules. Declared column types are unchanged. The Rules cache tracks it.LATERALitems like derived tables. Undeclared relation reads count as output columns in theP018clash check.Verification
K013, rule tests under both pytest import modes, and the Rules fact digests and payload.make testandmake check-cipass.