Skip to content

fix!: batch of refactor, sink, audit, CLI and rules fixes - #1202

Merged
kvlonge merged 17 commits into
mainfrom
fix/bug-batch-1
Oct 21, 2026
Merged

kvlonge merged 17 commits into
mainfrom
fix/bug-batch-1

Conversation

@kvlonge

@kvlonge kvlonge commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Why

Fixes a batch of bugs in refactoring, lifecycle sinks, generic audits, CLI errors and rules. Each fix ships with an integration or E2E test.

Changes

  • sqb rename / sqb mv take a model's own unit tests with it: the file is renamed, its TEST (name ...) gets the new subject, and mirrored tests/unit/<folders> files move with the model. A test stays in its folder (renamed, with a note in the new notes output) when a scoped macro, enum or constant it uses would resolve differently from the destination.
  • Audit-argument column renames list USING joins and leave lambda parameters alone.
  • After one slow call, a lifecycle sink resumes once the call returns; outcome events held during the stall are still delivered, a warning names the sink, and a failing stderr never stops delivery.
  • BREAKING: a generic audit argument that the audit's SQL never uses is a P001 compile error naming the argument and the definition file.
  • Documents the rendered audit SQL under target/compiled/audits.
  • Expected CLI errors whose text holds undecodable bytes print escaped instead of crashing.
  • Rules: # is no longer a Snowflake line comment; SELECT * is reported in plain set-operation branches, with dynamic-pivot branches still exempt.
  • The S101 help shows one settings example (regression test); the 64-bit option help repeats the full audit call.

Verification

  • New Rust unit tests plus integration/E2E tests for each fix; focused pytest runs pass.
  • make check-ci, workspace clippy -D warnings, fensu check, fensu dupes --since origin/main.
  • make compiler-differential: 374 projects pass; failure-corpus goldens updated.
  • A large private project compiles with no diagnostics and identical output on the branch and on 0.164.3.

A model's own unit test files, whose every TEST block targets only that
model, now follow it: test_<model>[__<behavior>].sql files take the new
name, TEST (name "<model>__<behavior>") headers take the new subject, and
files in the folder mirroring the model move to the folder mirroring the
destination. The edits are verified in the scratch compile like every
other edit, reported in --dry-run, and written only when verification
passes.
…lumn renames

An audit argument that joins on the renamed column with USING or NATURAL
is now listed for a manual edit instead of failing the verification
compile. The column analyser treats a lambda parameter named like the
column as its own scope, so references in the lambda body are no longer
renamed to the outer column.
A sink call over the one-second timeout used to block that sink for the
rest of the command, silently dropping every later event including run
and invocation outcomes. Delivery now resumes on a fresh worker once the
slow call returns; events dropped meanwhile are still counted, outcome
events are held and delivered instead of dropped, and the command warns
when the stall begins. The timeout clock only charges calls the delivery
thread has started and caps each dispatcher round's charge, so time
spent waiting for the GIL is not blamed on the sink. The exit warning now
points at sink health and the shutdown deadline instead of only the
shutdown timeout.
An attached generic audit that passes an argument neither its SQL nor its
evidence SQL reads, including a misspelt one, now fails the compile with
an error naming the audit, the argument to remove and the definition
file. Such arguments used to be ignored, so the audit silently checked
something other than what the attachment declared.

BREAKING CHANGE: projects whose audit attachments pass arguments the
audit never reads must remove those arguments.
…piled/audits

sqb compile already writes each attached generic audit's rendered SQL to
target/compiled/audits/generic/<resource>/ and removes it with the
attachment, but nothing said so. Document the compiled artifact layout
and cover the audit files, and their cleanup, with an end-to-end test.
A selector with undecodable bytes made sqb compile crash with a Unicode
error instead of reporting S007, in text mode and with --json. Expected
error text now keeps lone surrogates as \xNN or \uXXXX escapes before it
is printed or put in the JSON report.
The Rules scanner skipped Snowflake code after #, which Snowflake does
not treat as a comment (only -- and //), so dependency calls there were
missed. The scanner now matches the Snowflake tokenizer.
SQBRMODEL102 only inspected a query's body when it was a single SELECT,
so a star in any branch of UNION, INTERSECT or EXCEPT went unreported.
The rule now checks every plain SELECT branch of each query body.
The help for an oversized minimum_samples or evidence_limit showed the
audit call with only the offending option, so copying it dropped the
audit's name, severity and other options. It now repeats the whole call
with only the offending value replaced.
SQBRMODEL102 now checks every set-operation branch, but the dynamic-pivot
exemption was decided once per query and never matched a set-operation
body, so a union of dynamic-pivot star branches was reported per branch
although a lone dynamic-pivot star is exempt. The exemption now applies
to each branch.
…e written

A failing stderr write of the blocked-sink warning ended the dispatcher
thread, leaving queued events undelivered and uncounted. The warning is
now best-effort.
…resolves

Test SQL resolves macros, enums and constants from the test file's own
folder, so moving a model's test to the destination's mirrored folder
could hide a folder-scoped test declaration, failing verification. A
test file now moves only when every scoped declaration it uses resolves
to the same definition from the destination folder; otherwise it is
renamed in place and the output's new notes section names the file and
the declaration. The JSON output gains a notes array.
@kvlonge
kvlonge enabled auto-merge (squash) October 21, 2026 16:54
Two integration tests pinned the previous crash (a TypeError) for a selector with undecodable bytes. Expected CLI errors now print that text escaped, so the tests assert the escaped S007 error and a valid ASCII JSON report.
@kvlonge
kvlonge merged commit 1ecc1d0 into main Oct 21, 2026
46 checks passed
@kvlonge
kvlonge deleted the fix/bug-batch-1 branch October 21, 2026 20:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant