Skip to main content

Preserve breaks

preserveBreaks decides whether dfmt reads the line breaks you wrote. Off, a statement is laid out from its structure, the width and the other options, and a list you stacked by hand is joined back up if it fits. On, a line break you put between two list items, or in front of a clause, is kept.

Default: off. The output then depends on the SQL and the options and on nothing else: the same statement formats the same way whoever typed it and however they wrapped it. That is the property a formatter is for, so it is the default.

breaks_only keeps your breaks. A list you wrote one item per line stays that way where it would have fitted on one line, and a statement you spread over lines is not gathered back up onto one. It keeps nothing else: spacing, indentation and the position of commas are still dfmt's. Choose it where the authors group their columns deliberately, the join keys first and then the measures, and a width-only layout would run those groups together. The cost is that the same statement can format two ways depending on how it was typed.

breaks_and_alignment also reads the spaces you added to line things up. Padding written in front of as down a select list is detected and re-emitted as alignment — for any of the constructs that page names, and without an align setting. The same goes for a table's column definitions: when you lined up their names and types, both columns stay lined up, every column of the group included, and a blank line or a comment between two columns starts a new group. Use it for a project that aligns by hand and wants that kept.

The two settings answer different questions and do not conflict. align says "line this construct up wherever it occurs"; breaks_and_alignment says "wherever I lined something up, keep it". Setting both is ordinary: the named constructs are always aligned, and anything else the author padded is kept as well.

A stacked list, off and on​

select a,
  b,
  c from t
select a, b, c from t
select a,
  b,
  c from t
select
    a,
    b,
    c
from t

Padding before as, under the two on-values​

select
  customer_id       as cust,
  customer_name     as name,
  customer_email    as email
from t
select
    customer_id as cust,
    customer_name as name,
    customer_email as email
from t
select
  customer_id       as cust,
  customer_name     as name,
  customer_email    as email
from t
select
    customer_id    as cust,
    customer_name  as name,
    customer_email as email
from t

Column definitions you lined up​

create table orders (
  id          bigint primary key,
  customer_id bigint      not null,
  total       numeric(10, 2) not null,
  note        text
)
create table orders(
    id          bigint         primary key,
    customer_id bigint         not null,
    total       numeric(10, 2) not null,
    note        text
)

What is read. Between two items of a list, a newline is a break; a line comment counts too, because it ends the line. In front of a clause, a break before from, where, order by and the rest is kept, and a break before a qualifier such as the on of a join or the over of a window function is not, because a qualifier belongs to the clause before it. A break inside a subquery or a CTE body is read the same way, which means the parentheses around it have to open and the statement outside them comes apart with it.

What is not. An and/or chain carries no opinion: its breaks are never read, and andOrPosition and the width decide it. And an empty line between two items is not this option's at all. It is grouping, it survives at every setting, off included, and blankLines is where that is decided.