Bug
RF03 (references.consistent) silently skips consistency checking for a
Jinja-templated, unqualified column reference, even though the rendered
identifier is a completely ordinary column name a user wrote themselves.
Repro
$ cat jinja_case.sql
{% set my_col = 'customer_id' %}
SELECT {{ my_col }}, orders.total FROM orders
$ sqlfluff lint --dialect ansi --templater jinja --rules RF03 jinja_case.sql
All Finished!
$ cat plain_case.sql
SELECT customer_id, orders.total FROM orders
$ sqlfluff lint --dialect ansi --rules RF03 plain_case.sql
L: 1 | P: 8 | RF03 | Unqualified reference 'customer_id' found in single
| table select. [references.consistent]
L: 1 | P: 21 | RF03 | Qualified reference 'orders.total' found in single table
| select which is inconsistent with previous references.
| [references.consistent]
Both files describe the exact same query (customer_id unqualified,
orders.total qualified, single table). The byte-identical query flags two
RF03 violations when written plainly, and zero when the same identifier is
rendered through Jinja. Reproduces on current main.
Why this happens
_check_references() in src/sqlfluff/rules/references/RF03.py skips any
unqualified reference where ref.is_templated is True:
if this_ref_type == "unqualified" and ref.is_templated:
continue
That guard was added in #7615 to stop the placeholder templater's
colon-style bind parameters (e.g. :colname, rendered as a bare identifier
that is not a real column) from being wrongly qualified/flagged — the PR
body, review thread and added tests are all scoped explicitly to the
placeholder templater. ref.is_templated is a generic marker shared by
every templater, though, so the same guard also silently exempts Jinja/dbt
{{ var }}-rendered column names — genuine identifiers the user intends to
select — from ever being checked. Nothing in #7615's discussion considers
Jinja; this is scope drift in an unconditional check, not a decision anyone
made about the Jinja/dbt case.
Expected
The Jinja-rendered case should report the same two violations as the
non-templated equivalent. The placeholder-templater exemption #7615 added
should stay scoped to that templater.
I have a fix + regression fixture ready and will open a PR shortly.
Bug
RF03(references.consistent) silently skips consistency checking for aJinja-templated, unqualified column reference, even though the rendered
identifier is a completely ordinary column name a user wrote themselves.
Repro
Both files describe the exact same query (
customer_idunqualified,orders.totalqualified, single table). The byte-identical query flags twoRF03violations when written plainly, and zero when the same identifier isrendered through Jinja. Reproduces on current
main.Why this happens
_check_references()insrc/sqlfluff/rules/references/RF03.pyskips anyunqualified reference where
ref.is_templatedisTrue:That guard was added in #7615 to stop the
placeholdertemplater'scolon-style bind parameters (e.g.
:colname, rendered as a bare identifierthat is not a real column) from being wrongly qualified/flagged — the PR
body, review thread and added tests are all scoped explicitly to the
placeholdertemplater.ref.is_templatedis a generic marker shared byevery templater, though, so the same guard also silently exempts Jinja/dbt
{{ var }}-rendered column names — genuine identifiers the user intends toselect — from ever being checked. Nothing in #7615's discussion considers
Jinja; this is scope drift in an unconditional check, not a decision anyone
made about the Jinja/dbt case.
Expected
The Jinja-rendered case should report the same two violations as the
non-templated equivalent. The
placeholder-templater exemption #7615 addedshould stay scoped to that templater.
I have a fix + regression fixture ready and will open a PR shortly.