Skip to content

fix: lint SQL macro bodies as compiled and pass SQL macro expansions to Python macros intact - #1236

Merged
kvlonge merged 2 commits into
mainfrom
fix/sql-macro-lint-expansion
Oct 23, 2026
Merged

kvlonge merged 2 commits into
mainfrom
fix/sql-macro-lint-expansion

Conversation

@kvlonge

@kvlonge kvlonge commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

Why

With Rules on, SQL macro files that compile failed to lint: a parameter followed by words and ( (@value IS NULL OR TRIM(@value) = '') was read as an unprefixed call (L005), and a body opening with (( was parsed as a statement the native parser rejects (rules-unevaluated). A SQL macro call passed to a Python macro failed when its expansion held ", with no location; a body ending in a -- comment swallowed the caller's text; and SQBRSQL033 judged comments from macro expansions in the caller.

Changes

  • One shared rule for an unprefixed call, @name( with no gap, used by the Python call scanner, the SQL macro lexer, parameter references and the bare-call check. @name IS NULL OR f(x) in model SQL is no longer P014; @const/@enum/@param stay declarations with or without a space before (.
  • Lint neutralizes macro parameters with the compiler's parameter scan, lints expression bodies as SELECT <body> and CTE-list bodies with a ceremonial SELECT 1, and drops findings in that generated frame.
  • Expansions spliced into Python macro arguments write " as \x22, so the scanner and argument parser agree.
  • Expansions ending in a line comment get a line break only when text follows on that line; calls last on their line compile unchanged.
  • Unreadable macro calls raise MacroArgumentError with call, file, line and column.
  • Lint blanks comments generated by SQL macro expansions before rules run (judged in the macro file); compiled SQL keeps them; Python macro output is still judged.

Verification

  • Rust unit tests: scanner, expansion (quotes, '''', backslashes, newlines, dict and list values, comments), lint frames and comments.
  • New E2E file covering each body with Rules on, spaced declarations, Python macro arguments, error location and SQBRSQL033 for SQL and Python macros.
  • make test, make check-ci, make compiler-differential (no golden changes). One Python-oracle golden updated for seven located scan errors.

…to Python macros intact

Linting a SQL macro file read a parameter followed by words and a
parenthesis, such as `@value IS NULL OR TRIM(@value) = ''`, as an
unprefixed macro call (L005), and a body opening with two parentheses
reached the native parser as a statement it rejected (rules-unevaluated).

- One rule decides an unprefixed call everywhere: `@name(` with the
  parenthesis right after the name. The Python macro call scanner, the
  SQL macro lexer, parameter references and the bare-call check share
  it, so `@name IS NULL OR f(x)` in model SQL is no longer P014 either.
  `@const`, `@enum` and `@param` stay declarations with or without a
  space before their parenthesis.
- Lint replaces a SQL macro body's parameters by sentinels with the
  compiler's own parameter scan, lints an expression body as the
  `SELECT` the compiler parses it as, and a CTE-list body with its
  ceremonial `SELECT 1` and its CTEs counted as used by the caller.
  Findings in the generated frame are dropped.
- A SQL macro expansion passed to a Python macro is spliced as a
  string literal with `"` written as `\x22`, which the call scanner
  and the argument parser read the same way, so quotes, backslashes,
  line breaks and comments reach the macro unchanged.
- An expansion ending in a line comment gets a line break only when
  text would follow it on the same line, so the caller's text stays code
  and calls already last on their line compile unchanged.
- A macro call the scan cannot read is a MacroArgumentError naming the
  call, file, line and column instead of a location-less P001.
- Rules on a caller skip comments a SQL macro expansion generated; the
  macro file is where they are judged, and compiled SQL keeps them.
  Comments from Python macro output are judged as before.
@kvlonge
kvlonge enabled auto-merge (squash) October 23, 2026 13:09
@kvlonge
kvlonge merged commit 2357ce2 into main Oct 23, 2026
44 checks passed
@kvlonge
kvlonge deleted the fix/sql-macro-lint-expansion branch October 23, 2026 14:34
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