Tag lines
The rule that a block is a one-liner, or every one of its tags owns a line — never a mix.
Each pair below is a real, passing case from dfmt's test corpus (suites/dfmt-jinja/cases/tag-lines/): the template as written, then the same template after dfmt — every Jinja tag reproduced exactly, the SQL laid out around it. 18 examples.
A block body is one level under its tag
dialect postgres
Left unchanged — already in dfmt's shape:
select
a
{% if true %}
, b
{% endif %}
from t
A multiline tag reanchors where it lands
Before
select *
from t
{% if flag %}
{% set max_partition = (
"select date(gr) from (
select max(d) as gr
from t2
)
") %}
where d >= 1
{% endif %}
After
select *
from t
{% if flag %}
{% set max_partition = (
"select date(gr) from (
select max(d) as gr
from t2
)
") %}
where d >= 1
{% endif %}
A set before the first statement goes with it
dialect postgres
Before
{% set x = 1 %}
select a from t
After
{% set x = 1 %}
select a
from t
A set block keeps all three tags
Before
{%- set a_q -%}
(select 1)
{%- endset -%}
{%- set b_q -%}
(select 2)
{%- endset -%}
/* which query wins */
select cast({{ a_q }} as int) as a, cast({{ b_q }} as int) as b
from t
After
{%- set a_q -%}
(select 1)
{%- endset -%}
{%- set b_q -%}
(select 2)
{%- endset -%}
/* which query wins */
select cast({{ a_q }} as int) as a, cast({{ b_q }} as int) as b
from t
A set glued to select keeps its tag
dialect ansi · config keywordCase = upper, identifierCase = upper, functionCase = upper, dataTypeCase = upper, indentWidth = 2, maxLineWidth = 80, blankLineBetweenCtes = false, collapseShortStatements = false
Before
{% set x = 'hello' %}SELECT 1
After
{% set x = 'hello' %}
SELECT 1
A spaced block takes a line for every tag
dialect postgres
Before
select a {% if true %}, b{% endif %} from t
After
select
a
{% if true %}
, b
{% endif %}
from t
A spaced if else glued to its terminator opens
Before
select id from t where {% if flag %} total > 0 {% else %} total >= 0 {% endif %};
After
select id
from t
where
{% if flag %}
total > 0
{% else %}
total >= 0
{% endif %};
A spaced if else inside a clause opens
Before
select a from t where {% if is_incremental() %} a > 0 {% else %} a >= 0 {% endif %} group by a
After
select a
from t
where
{% if is_incremental() %}
a > 0
{% else %}
a >= 0
{% endif %}
group by a
A trimmed set under a line comment
Before
-- what this model is for
{%- set q -%}
(select 1)
{%- endset %}
-- how q is used
select cast({{ q }} as int) as a
from t
After
-- what this model is for
{%- set q -%}
(select 1)
{%- endset %}
-- how q is used
select cast({{ q }} as int) as a
from t
An author inline for stays inline
Before
select a {% for x in ['p', 'q'] %}, {{ x }}_col{% endfor %} from t
After
select
a
{% for x in ['p', 'q'] %}, {{ x }}_col{% endfor %}
from t
An untaken guard in where keeps its own line
dialect ansi · config keywordCase = upper, identifierCase = upper, functionCase = upper, dataTypeCase = upper, indentWidth = 2, maxLineWidth = 80, blankLineBetweenCtes = false, collapseShortStatements = false
Before
select id
from t
where a = 1
{% if flag %}
and b = 2
{% endif %}
After
SELECT ID
FROM T
WHERE
A = 1
{% if flag %}
AND B = 2
{% endif %}
Closer aligns with its opener
Before
select
client_key,
stream_id,
min(session_start_timestamp) as first_seen_timestamp,
sum(count_pageviews) as count_pageviews,
count(distinct session_key) as count_sessions
{% if events %}
{% for ce in events %}
{% set clean = ce %}
, sum(count_{{ clean }}) as count_{{ clean }}
{% endfor %}
{% endif %}
from sessions
After
select
client_key,
stream_id,
min(session_start_timestamp) as first_seen_timestamp,
sum(count_pageviews) as count_pageviews,
count(distinct session_key) as count_sessions
{% if events %}
{% for ce in events %}
{% set clean = ce %}
, sum(count_{{ clean }}) as count_{{ clean }}
{% endfor %}
{% endif %}
from sessions
Else with glued body
Before
select a
from t
{% if is_incremental() %}
where event_date between date_sub(current_date, interval 3 day) and current_date
{% else %} where event_date >= date_sub(current_date, interval 60 day)
{% endif %}
After
select a
from t
{% if is_incremental() %}
where event_date between date_sub(current_date, interval 3 day) and current_date
{% else %}
where event_date >= date_sub(current_date, interval 60 day)
{% endif %}
Glued cte block comes apart once
Before
with
base as (select id, ts, amount, account_key from events where kind = 'fill')
{% if is_incremental() %} , max_date as (select max(_inserted_timestamp) max_ts from {{ this }})
{% endif %}
select base.id, base.ts, base.amount
from base
After
with
base as (select id, ts, amount, account_key from events where kind = 'fill')
{% if is_incremental() %}
, max_date as (select max(_inserted_timestamp) max_ts from {{ this }})
{% endif %}
select base.id, base.ts, base.amount
from base
Guard after a trailing comment
Before
select a
from t
-- incremental run only: update the partition of the run day
{% if var("flag", false) %}
where a > 0
{% endif %}
After
select a from t
-- incremental run only: update the partition of the run day
{% if var("flag", false) %}
where a > 0
{% endif %}
If tags take the column of the code they interrupt
Before
with enriched_session_events as (
select
anonymous_user_key,
event_collection_timestamp_utc,
{% if true %}
normalized_event_name_with_category,
{% endif %}
event_property_value_as_reported
from source_session_events
)
select * from enriched_session_events
After
with
enriched_session_events as (
select
anonymous_user_key,
event_collection_timestamp_utc,
{% if true %}
normalized_event_name_with_category,
{% endif %}
event_property_value_as_reported
from source_session_events
)
select *
from enriched_session_events
Standing guard keeps its own line
Left unchanged — already in dfmt's shape:
select
a
{%- if true -%},{% endif %}
b
from t
Whole clause conditional
Before
select a, b
from t
{% if is_incremental() %}
where updated_at > (select max(updated_at) from {{ this }})
{% endif %}
order by a
After
select a, b
from t
{% if is_incremental() %}
where updated_at > (select max(updated_at) from {{ this }})
{% endif %}
order by a