Releases: sbdchd/squawk
Parser Fixes & Improvements
Fix False Positive with Require Schema Rule & Github Actions Output Clobbering
Added
- fmt: support comments in group by (#1194)
Fixed
-
linter: fix github actions output clobbering json/gcc (#1192)
-
linter: fix require table schema false positive on temp tables (#1191)
Previously this would error:
create temp table t (id bigint); -
parser: fix various ast gaps (#1190)
-
parser: fix index option parsing (#1188)
Previously this wouldn't parse:
create index index_name on public.table_name using gin (column_name public.gin__int_ops);
-
parser: add ast nodes & fix alter restart (#1193)
Fix Precommit Install & IDE Improvements
Fixed
-
ci: fix precommit install by declaring optional dependencies (#1180)
-
ide: fix
select *w/create view& more (#1184)The following now works correctly:
create table t(a int); -- ^ dest create view v as table t; select a$0 from v; -- ^ src
-
ide: treat
select intolikecreate table as(#1183)create table t(a bigint); -- ^ dest select * into u from t; select a from u; -- ^ src
-
ide: fix column resolution with cte & shadowing (#1182)
with outer_cte as (select 1 c) -- ^ dest select * from ( with inner_cte as (select 2 d) select c from outer_cte -- ^ src ) s;
-
ide: fix aliases not hiding original name (#1181)
create table t(a int); update t as u set a = t.a; -- ^ error
-
ide: fix cte & alias resolution (#1179)
with a as (select * from b), -- ^ src doesn't resolve b as (select 1 x) select * from a; -
ide: don't resolve trailing FromItems in a lateral subquery (#1177)
with d as (select 1 id, 2 amount), c as (select 2 id) select r.amount from d, lateral ( select d.amount from d where d.id = c.id -- ^ src doesn't resolve limit 1 ) r, c;
Parser Improvements & Fixes + Error Docs Hyperlinks
More Parser Validation + CI Hardening
v2.54.0 - 2026-05-24
Added
-
lexer: add parsing and erroring for num trailing suffix (#1159)
error[syntax-error]: trailing junk after numeric literal ββΈ stdin:1:11 β 1 β SELECT 0x0y; β°β΄ β -
parser: warn about empty / invalid params & empty quoted idents (#1164)
error[syntax-error]: empty delimited identifier ββΈ stdin:1:8 β 1 β select "", $, $2147483648 β°β΄ ββ error[syntax-error]: missing parameter number ββΈ stdin:1:12 β 1 β select "", $, $2147483648 β°β΄ β error[syntax-error]: parameter number too large ββΈ stdin:1:15 β 1 β select "", $, $2147483648 β°β΄ βββββββββββ -
parser: warn about invalid octal/hex/binary digits (#1163)
error[syntax-error]: invalid digit for a base 2 literal ββΈ stdin:1:12 β 1 β select 0b104, 0o7719, 0xg β°β΄ β error[syntax-error]: invalid digit for a base 8 literal ββΈ stdin:1:20 β 1 β select 0b104, 0o7719, 0xg β°β΄ β error[syntax-error]: trailing junk after numeric literal ββΈ stdin:1:25 β 1 β select 0b104, 0o7719, 0xg β°β΄ β -
parser: improve error reporting for malformed literals (#1162)
error[syntax-error]: trailing junk after positional parameter ββΈ stdin:1:10 β 1 β SELECT $1a; β°β΄ βinstead of
error[syntax-error]: trailing junk after positional parameter ββΈ stdin:1:10 β 1 β SELECT $1a; β°β΄ βββ -
parser: improve lexing numbers (#1161)
select .4;
now produces:
[email protected] ".4"instead of:
[email protected] ".4" -
ide: goto def for
t.c%type(#1161)create table t(a int, b text); -- ^ dest create function f(x t.a%type) returns s.t.b%type -- ^ source as $$ select 'hello'::text $$ language sql;
-
ide: find refs for types like
bit(#1153)create type pg_catalog.bit; -- ^^^ source create function pg_catalog.bit(bigint, integer) returns bit -- ^^^ ref language internal;
-
ide: add hover for string literals (#1155)
Now we decode the escape sequences for string literals on hover and show the
value up to the first new line. -
ide: improve numeric literal type inference (#1156)
select 2147483647; -- type: integer select 2147483648; -- type: bigint select 100000000000000000000000; -- type: numeric
-
fmt: literals & binary operators (#1169)
Format binary operators and literals.
-- before select TRUE and FALSE; select X'AF'; -- after select true and false; select x'AF';
-
fmt: unquote column aliases when possible (#1168)
-- before select 1 as "foo"; -- after select 1 as foo;
Changed
Fixed
- lexer: fix unicode escape string issue (#1158)
- vscode: update TextMate grammar to support other numeric literal kinds (#1157)
v2.53.0 - 2026-05-17
Added
Changed
Fixed
- install: fix windows npx install bug (#1140)
Fix NPX Windows Install + Parser Improvements
Fix NPM Package Publishing
Changed
Attempt to fix npm install method
Improved Parser Validation for Strings + Updated Install Method
Added
-
parser: validation for bit, byte, and escape string types (#1132)
select b'01' '10'; select x'0F' '10'; select e'foo' 'bar';
now gives:
error[syntax-error]: Expected new line or comma between string literals ββΈ stdin:1:13 β 1 β select b'01' '10'; β°β΄ β error[syntax-error]: Expected new line or comma between string literals ββΈ stdin:2:13 β 2 β select x'0F' '10'; β°β΄ β error[syntax-error]: Expected new line or comma between string literals ββΈ stdin:3:14 β 3 β select e'foo' 'bar'; β°β΄ β
-
parser: validation for escape sequences (#1125, #1123, #1122, #1128, #1129)
select U&'wrong: !061' UESCAPE '!'; select U&"wrong: \06" UESCAPE '\';
now gives:
error[syntax-error]: Unicode escape requires 4 hex digits: !XXXX ββΈ stdin:1:20 β 1 β select U&'wrong: !061' UESCAPE '!'; β°β΄ ββββ error[syntax-error]: Unicode escape requires 4 hex digits: \XXXX ββΈ stdin:2:20 β 2 β select U&"wrong: \06" UESCAPE '\'; β°β΄ βββ
Changed
-
ci: update npm based install method (#1133)
Instead of fetching the binary via an install script we use an optional
peer dependency, mirroring ESBuild and Sentry.
Fixed
-
cli: fix missing binary exit code (#1130)
Before if the install script didn't run the NPM JS shim would exit without
erroring. Thanks @nwalters512! -
parser: parsing unicode escape idents in cast position (#1127)
select 2::U&"!0069!006E!0074!0038" UESCAPE '!' from t;
now parses without error
File Level Disable Comment For `assume_in_transaction`
v2.51.0 - 2026-05-06
Added
-
linter: add file-level override to disable
assume_in_transaction(#996). Thanks @reteps!When using
assume-in-transaction, you can disable it on a per file basis using a comment:-- squawk-disable-assume-in-transaction -
syntax: add validation for
select into(#1116)Warn about invalid usages, such as:
select 4 a union select 5 a into t;with t as (select 1 a into t) select * from t;select * from t where a in (select 1 a into t);
and more!
-
parser: add empty statement to ast (#1111)
; ; ;
now gives:
-
ide: code actions create table as <-> select into + parser fix (#1113)
Create table and select into are roughly interchangable, so this code action
supports switching between. -
ide: show comments for types and columns (#1110)
Changed
- parser: cleanup insert & create rule ast grammar to be more strict (#1112)
Fixed
New Rules: Prefer Repack, Identifier Too Long, Require Concurrent Reindex, Require Concurrent Partition Detach + A Lexer Fix
Added
-
linter: new rule: prefer-repack (#1105)
repackisn't out yet, coming in PG19, but when it's out:-- instead of cluster foo; -- or vacuum full foo; -- use repack (concurrently) foo;
-
linter: new rule: require-concurrent-reindex (#1104)
-- instead of reindex table foo; -- use reindex table concurrently foo;
-
linter: new rule: require-concurrent-partition-detach (#1103)
-- instead of alter table t detach partition p; -- use alter table t detach partition p concurrently;
-
linter: new rule: identifier-too-long (#1102)
Postgres truncates identifiers that are too long, we now warn about this.
create table table_very_long_very_long_very_long_very_long_very_long_very_long (c bigint);
warning[identifier-too-long]: `table_very_long_very_long_very_long_very_long_very_long_very_long` is too long and will be truncated to 63 bytes. ββΈ stdin:1:14 β 1 β create table table_very_long_very_long_very_long_very_long_very_long_very_long (c bigint); β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ΄ 1 - create table table_very_long_very_long_very_long_very_long_very_long_very_long (c bigint); 1 + create table table_very_long_very_long_very_long_very_long_very_long_very_lo (c bigint); β°β΄Thanks @subnix for coming up with this idea!
-
linter: parallel file checking (#1099)
We now check files in parallel using rayon, which gives a nice speed up of
22-55%. -
lexer/ide: fix lexing of non-ascii + fix case folding in goto def (#1101)
Previously we case folding all of the characters in our unquoted identifiers
including unicode. This differed from Postgres behavior which only folded ascii.Now we correctly error instead of resolving in the following:
with t as (select 1 Γpfel) select Γ€pfel from t; -- ^ goto def no longer resolves
Additionally fixed a bug in the lexer where we weren't lexing unicode identifiers.
For example, the following now lexes:
with t as (select 1 π¦) select π¦ from t;