sqlfmt icon indicating copy to clipboard operation
sqlfmt copied to clipboard

Customize formatting for certain jinja expressions/macros

Open tconbeer opened this issue 3 years ago • 1 comments

Some jinja expressions contain keywords, but they're all just formatted like names.

For example, {{ dbt_utils.group_by(n) }} tends to get wrapped onto the line above it. sqlfmt doesn't have any way to know that the macro compiles to a keyword, so it wants to one-line it with the end of the where statement. If sqlfmt knew this compiled to GROUP BY, it would not do that.

I've thought about this before, and I don't have a great solution except for hard-coding it in as an exception (it's one of very few macros that start with a keyword).

other than the hacky/hard-coded method, we could consider an inline comment that could tell sqlfmt how to treat a jinja expression (if the default treatment doesn't work). So something like:

{{ dbt_utils.group_by(6) }}  -- fmt: group by

If anyone else has solutions/ideas, I'm open to them, but I do not want to go down the sqlfluff road and jinja-template the sql.

For now, I'd suggest either 1) using a -- fmt: off comment on this line, or b) not using dbt_utils.group_by() and instead implement a macro called range:

{%- macro range(n) -%}
{% for i in range(1, n + 1) -%}
    {{ i }}{{ ',' if not loop.last }}   
{%- endfor -%}
{%- endmacro -%}

and then call it with:

...
where my_condition
group by {{ range(10) }}

Originally posted by @tconbeer in https://github.com/tconbeer/sqlfmt/issues/165#issuecomment-1107884456

tconbeer avatar May 04 '22 01:05 tconbeer

I can't imagine any viable solutions to this problem if we're going to format without compiling. The dbt_utils.group_by macro has always been a bit gross for this specific reason, and the range alternative you proposed is infinitely better in my eyes.

If a solution needs to be implemented, then it should probably be a configuration where users can define a list of macros that should always be on a new line (rather than just hard-coding for dbt_utils.group_by--though it could be the default).

rileyschack avatar Jan 06 '23 20:01 rileyschack