Skip to main content

Error recovery

A file with a syntax error in it still gets formatted. The parser recovers, the parts it could read are laid out normally, and the span it could not is passed through exactly as the author typed it. Nothing is marked up, nothing is deleted, and no token is moved out of the broken region.

Two things are switched off for a file that had to recover, both for the same reason — a position taken from a guessed tree lands wherever the guess said. clarifyPrecedence will not add parentheses, and the editor integration will not show per-token mappings.

A query whose WHERE was left unfinished​

The select list, the join and the from are read and laid out. The where stops at a dangling >, so it is kept verbatim — including the >.

select   o.customer_id ,  o.order_total ,  c.email , o.created_at
from orders o  join customers c on o.customer_id=c.id
where o.status = 'shipped'  and  o.order_total >
select
    o.customer_id,
    o.order_total,
    c.email,
    o.created_at
from orders o
join customers c on o.customer_id = c.id
where o.status = 'shipped' and o.order_total >

One broken statement among good ones​

The insert and the update are formatted the way any statement is. The statement between them is not SQL the parser can read, so it survives with its own spacing, and its terminator is neither doubled nor dropped.

insert into audit_log ( event , actor , created_at ) values ('login','svc',now());
select  a.id ,  from  where  a.x = ;
update  customers  set  tier='gold' , updated_at=now()  where  lifetime_value > 10000
insert into audit_log(event, actor, created_at)
values ('login', 'svc', now());

select  a.id ,  from  where  a.x = ;

update customers
set tier = 'gold', updated_at = now()
where lifetime_value > 10000

Text that is not SQL at all​

A run of bytes the lexer cannot make tokens of is still a span in the file. It keeps its place between the statements around it, which are formatted normally.

select   customer_id ,  sum(order_total)  as lifetime
from orders  group by customer_id;
@#$%^&
select   c.email , c.tier  from customers c  where c.tier = 'gold'
select customer_id, sum(order_total) as lifetime
from orders
group by customer_id;

@#$%^&

select c.email, c.tier
from customers c
where c.tier = 'gold'