Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
274 commits
Select commit Hold shift + click to select a range
e7559a3
WIP: postgres parser: TRUNCATE and COPY
kvlonge Nov 6, 2026
40a9fe7
Take whole_text as a /2 receipt's parser check in syntax-coverage
kvlonge Nov 6, 2026
60bbc3e
WIP: postgres parser: lock entry for the new workspace crate
kvlonge Nov 6, 2026
4ddc2fc
Record the three ddl negatives that split into two statements
kvlonge Nov 6, 2026
eb99774
Merge wip/pg-parser into the Postgres local-parser branch
kvlonge Nov 6, 2026
7a9066b
Let syntax-coverage judge Postgres roots with the Postgres parser
kvlonge Nov 6, 2026
d6e1286
Expose statement_name_findings for parsed statements
kvlonge Nov 6, 2026
35c9119
Read the Postgres root with the Postgres parser
kvlonge Nov 6, 2026
b7bead0
Record the first Postgres coverage baseline
kvlonge Nov 6, 2026
947f18a
WIP: postgres parser: MERGE
kvlonge Nov 6, 2026
7b54600
WIP: postgres parser: group grammar helpers one level deep
kvlonge Nov 6, 2026
4f67de9
WIP: postgres parser: check SQL/JSON and SQL/XML calls fully
kvlonge Nov 6, 2026
5db80c3
WIP: postgres parser: GROUP BY DISTINCT and row assignments in UPDATE
kvlonge Nov 6, 2026
28550cb
Merge wip/pg-parser into the Postgres local-parser branch
kvlonge Nov 6, 2026
0a175e5
Re-record the Postgres baseline with the parser that reads MERGE
kvlonge Nov 6, 2026
b97a7af
Record source ranges on Postgres parser nodes
kvlonge Nov 6, 2026
6764c6d
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
a5c2371
Check Postgres SQL with PostgreSQL's coercion and name rules
kvlonge Nov 6, 2026
a20177b
test: record PIVOT without an alias list and TABLE(FLATTEN(...)) as d…
kvlonge Nov 6, 2026
5e84074
Name unaliased Postgres outputs as PostgreSQL does
kvlonge Nov 6, 2026
cb6da84
Type Postgres outputs from the 18.6 catalogue
kvlonge Nov 6, 2026
04ba795
feat: convert PIVOT without an alias column list
kvlonge Nov 6, 2026
97da035
feat: convert TABLE(FLATTEN(...)) after a comma as LATERAL FLATTEN
kvlonge Nov 6, 2026
e0f7e14
Resolve Postgres operators and common types from the 18.6 catalogue
kvlonge Nov 6, 2026
c9f4e6b
evidence: record unaliased PIVOT key names and TABLE(FLATTEN) forms
kvlonge Nov 6, 2026
e25efbe
Merge commit 'c9f4e6b90616fd6283c1236acb003a218095d583' into feat/piv…
kvlonge Nov 6, 2026
ea0ede3
Merge commit 'c9f4e6b90616fd6283c1236acb003a218095d583' into feat/tab…
kvlonge Nov 6, 2026
ec67f88
Report Postgres window functions called without OVER
kvlonge Nov 6, 2026
5ceec19
Give each lineage output its most significant transform kind
kvlonge Nov 6, 2026
19a2e49
Parse Postgres type strings and lower SQLBuild's type markers
kvlonge Nov 6, 2026
3c8dcf8
test: pin PIVOT refusals for a partial alias list and a quoted key
kvlonge Nov 6, 2026
24483a7
Merge wip/pg-local-parser into the Postgres integration branch
kvlonge Nov 6, 2026
7f3eb78
Merge wip/pg-parser into the Postgres integration branch
kvlonge Nov 6, 2026
1220a1b
Merge wip/lineage-transform-kinds into the Postgres integration branch
kvlonge Nov 6, 2026
228cb0b
Add a strict Postgres entry point
kvlonge Nov 6, 2026
ddecefc
Merge wip/pg-parser into the Postgres local-parser branch
kvlonge Nov 6, 2026
13d37b7
Keep window outputs unknown unless they never give NULL, and count ev…
kvlonge Nov 6, 2026
4f6ae98
Judge Postgres cases with the strict Postgres parser
kvlonge Nov 6, 2026
000579b
Merge wip/pg-local-parser into the Postgres integration branch
kvlonge Nov 6, 2026
ff573c6
Merge wip/lineage-transform-kinds into the Postgres integration branch
kvlonge Nov 6, 2026
16b915a
Merge main into the Postgres integration branch
kvlonge Nov 6, 2026
b7f2b56
Merge remote-tracking branch 'origin/main' into wip/pg-catalogue
kvlonge Nov 6, 2026
727ef18
Bring the Postgres type-string, marker and strict code under main's f…
kvlonge Nov 6, 2026
af8daf4
Merge wip/pg-parser into the Postgres local-parser branch
kvlonge Nov 6, 2026
0f203a0
Bring the window nullability and coercion code under main's fensu rules
kvlonge Nov 6, 2026
a97e2e7
Keep the Postgres verdict's doc comment to one line
kvlonge Nov 6, 2026
c8fe597
Merge wip/pg-local-parser into the Postgres integration branch
kvlonge Nov 6, 2026
590845e
Merge wip/lineage-transform-kinds into the Postgres integration branch
kvlonge Nov 6, 2026
391e6e0
Re-record the Postgres baseline with the strict Postgres parser
kvlonge Nov 6, 2026
b4d65cd
Merge wip/pg-catalogue into the Postgres integration branch
kvlonge Nov 6, 2026
d2f7175
Land the auditor's first Postgres review batch
kvlonge Nov 6, 2026
73f0a91
Keep ORDER BY USING, COPY PROGRAM and TRUNCATE targets in the Postgre…
kvlonge Nov 6, 2026
2f15c74
Merge branch 'wip/pg-local-parser' into wip/pg-integration
kvlonge Nov 6, 2026
e48be3a
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
4dd7df2
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
12d3330
Re-record the Postgres baseline on the integration parser
kvlonge Nov 6, 2026
cdff612
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
cecd9bf
Land the auditor's second Postgres review batch
kvlonge Nov 6, 2026
b90b598
Land the reviewer's third Postgres review batch
kvlonge Nov 6, 2026
6944736
Keep operator names, modifiers, window names and boolean tests in the…
kvlonge Nov 6, 2026
72980d9
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
eb1b2c4
Merge branch 'wip/pg-local-parser' into wip/pg-integration
kvlonge Nov 6, 2026
1cbe9f0
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
1647725
Parse COMMENT ON in the Postgres parser
kvlonge Nov 6, 2026
2b9de58
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
b71461e
Fix the Postgres catalogue defects behind the auditor's 31 held forms
kvlonge Nov 6, 2026
35e38f0
Re-record the Postgres baseline on parser tree 37050ece
kvlonge Nov 6, 2026
dd83a28
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
7af0ec7
Keep routine argument modes in the Postgres tree
kvlonge Nov 6, 2026
dcd61d2
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
3266c12
Parse SECURITY LABEL in the Postgres parser
kvlonge Nov 6, 2026
2e061b2
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
c9bdab0
Land the reviewer's fourth Postgres batch and withdraw datatype.chara…
kvlonge Nov 6, 2026
16cbec0
Give BIT and CHAR their default length of 1 in the Postgres tree
kvlonge Nov 6, 2026
f0fcd1e
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
339f81e
Land the reviewer's fifth Postgres batch on parser tree 7627aaef
kvlonge Nov 6, 2026
497e4f1
Restore the Postgres baseline the previous commit emptied
kvlonge Nov 6, 2026
87404be
Parse CREATE FUNCTION and PROCEDURE in the Postgres parser
kvlonge Nov 6, 2026
e9f15fc
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
0ca346d
Merge commit '497e4f14' into wip/pg-integration
kvlonge Nov 6, 2026
a3ad8e3
Merge branch 'wip/pg-local-parser' into wip/pg-integration
kvlonge Nov 6, 2026
6401fce
Re-record the Postgres baseline on parser tree 783462b5
kvlonge Nov 6, 2026
97d553d
Merge commit '6401fce9' into wip/pg-integration
kvlonge Nov 6, 2026
ff1ce6a
Withdraw seven Postgres approvals a known type-name defect reaches (D…
kvlonge Nov 6, 2026
4713a84
Cover CREATE PROCEDURE's sql_body with the documented BEGIN ATOMIC body
kvlonge Nov 6, 2026
56078ad
Quote type name parts as quote_ident does in the Postgres tree
kvlonge Nov 6, 2026
47473f2
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
6a37c3b
Merge commit '4713a843' into wip/pg-integration
kvlonge Nov 6, 2026
605f899
Merge branch 'wip/pg-local-parser' into wip/pg-integration
kvlonge Nov 6, 2026
1ea94b2
Re-record the Postgres baseline on parser tree a510c28d
kvlonge Nov 6, 2026
d8fbab7
Merge commit '1ea94b23' into wip/pg-integration
kvlonge Nov 6, 2026
f5a654d
Land the reviewer's seventh Postgres batch on parser tree a510c28d
kvlonge Nov 6, 2026
b53b3b2
Merge commit 'f5a654d8' into wip/pg-integration
kvlonge Nov 6, 2026
2c68336
Parse CREATE TABLE and CREATE TABLE AS in the Postgres parser
kvlonge Nov 6, 2026
db81ebb
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
7031857
Merge branch 'wip/pg-local-parser' into wip/pg-integration
kvlonge Nov 6, 2026
d5b8c5b
Re-record the Postgres baseline on parser tree 2948a1db
kvlonge Nov 6, 2026
fed599f
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
7bf8d27
Cover several CREATE FUNCTION options and several BEGIN ATOMIC statem…
kvlonge Nov 6, 2026
fb04813
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
c1301ed
Land the reviewer's eighth Postgres batch on parser tree 2948a1db
kvlonge Nov 6, 2026
41e2a0b
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
b95328f
Parse CREATE AGGREGATE in the Postgres parser
kvlonge Nov 6, 2026
b820991
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
efb0600
Merge branch 'wip/pg-local-parser' into wip/pg-integration
kvlonge Nov 6, 2026
634ca74
Re-record the Postgres baseline on parser tree 1460fa5d
kvlonge Nov 6, 2026
a41a4ae
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
bc1e3c8
Parse CREATE DATABASE in the Postgres parser
kvlonge Nov 6, 2026
6b88df6
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
7e9fc99
Merge branch 'wip/pg-local-parser' into wip/pg-integration
kvlonge Nov 6, 2026
168323f
Withdraw 5 routine approvals on a known four-part-name defect
kvlonge Nov 6, 2026
a40e304
Reach SORTOP, CONNECTION LIMIT and OID with real operands
kvlonge Nov 6, 2026
99d9228
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
f679eb5
Keep four-part routine names and fold ordered-set VARIADIC types
kvlonge Nov 6, 2026
3c6baf8
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
221933a
Merge branch 'wip/pg-local-parser' into wip/pg-integration
kvlonge Nov 6, 2026
11d1d95
Land the reviewer's tenth Postgres batch on parser tree 4825006a
kvlonge Nov 6, 2026
a78d1d3
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
ba55843
Re-record the Postgres baseline on parser tree 9138a8de
kvlonge Nov 6, 2026
d1009c9
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
8f636d0
Land the reviewer's eleventh Postgres batch on parser tree 9138a8de
kvlonge Nov 6, 2026
66a0962
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
6b17e7c
WIP: parse ALTER TABLE, FOREIGN TABLE, INDEX, SEQUENCE, VIEW and MATE…
kvlonge Nov 6, 2026
e8eab74
Test and document the relation ALTER statements
kvlonge Nov 6, 2026
c65478e
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
b1f0aa1
Merge branch 'wip/pg-local-parser' into wip/pg-integration
kvlonge Nov 6, 2026
0d899f3
Re-record the Postgres baseline on parser tree 394fb708
kvlonge Nov 6, 2026
630c560
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
d310591
Land the reviewer's twelfth Postgres batch on parser tree 394fb708
kvlonge Nov 6, 2026
a15d80f
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
314d820
Parse ALTER FUNCTION, PROCEDURE, ROUTINE and AGGREGATE
kvlonge Nov 6, 2026
85bedf2
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
6e35c47
Merge branch 'wip/pg-local-parser' into wip/pg-integration
kvlonge Nov 6, 2026
1fca1eb
Re-record the Postgres baseline on parser tree bb29fc0e
kvlonge Nov 6, 2026
2421349
Answer the reviewer's pending Postgres obligation notes
kvlonge Nov 6, 2026
4dcae9e
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
61e781a
Land the reviewer's re-approval of the 13 forms the obligation notes …
kvlonge Nov 6, 2026
55f3288
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
0d83bd6
Land the reviewer's thirteenth Postgres batch on parser tree bb29fc0e
kvlonge Nov 6, 2026
7146978
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
6615378
Answer the reviewer's batch-13 obligation notes
kvlonge Nov 6, 2026
c00e64e
Land the reviewer's re-approval of the 30 forms the batch-13 notes ch…
kvlonge Nov 6, 2026
5b09d09
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
be1588e
Parse the remaining ALTER statements of named objects
kvlonge Nov 6, 2026
575560d
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
8679bf5
Merge branch 'wip/pg-local-parser' into wip/pg-integration
kvlonge Nov 6, 2026
438bcc4
Land the reviewer's sixteenth Postgres batch on parser tree c1fde191
kvlonge Nov 6, 2026
d121075
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
cd6ac6b
Refuse four-part type names in ALTER TYPE attribute commands
kvlonge Nov 6, 2026
869e864
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
875ef6a
Merge branch 'wip/pg-local-parser' into wip/pg-integration
kvlonge Nov 6, 2026
29e7f9c
Re-record the Postgres baseline on parser tree 31234130
kvlonge Nov 6, 2026
904bad4
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
8a40717
Answer the reviewer's batch-16 coverage notes
kvlonge Nov 6, 2026
046b8fb
Land the reviewer's re-approval of the 15 forms the batch-16 notes ch…
kvlonge Nov 6, 2026
abf5fd0
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
ddc06f8
Answer the reviewer's batch-17 note on ALTER EXTENSION members
kvlonge Nov 6, 2026
8f6d173
Land the reviewer's re-approval of the two ALTER EXTENSION forms
kvlonge Nov 6, 2026
f54c373
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
6501f2e
WIP: parse CREATE VIEW, MATERIALIZED VIEW, INDEX, SEQUENCE, TRIGGER, …
kvlonge Nov 6, 2026
913707f
Test and document the CREATE view, index, sequence, trigger, type and…
kvlonge Nov 6, 2026
c5b6ddc
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
a3165fa
Read CREATE VIEW's RECURSIVE apart from its check option
kvlonge Nov 6, 2026
2439c49
Merge remote-tracking branch 'origin/wip/pg-local-parser' into wip/pg…
kvlonge Nov 6, 2026
2cec8f0
Merge remote-tracking branch 'origin/wip/pg-create-view-split' into w…
kvlonge Nov 6, 2026
548a242
Re-record the Postgres baseline on parser tree 5aa36f34
kvlonge Nov 6, 2026
bde1a9d
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
d558d88
Refuse four-part names for composite types
kvlonge Nov 6, 2026
15a8614
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
79ce265
Merge remote-tracking branch 'origin/wip/pg-local-parser' into wip/pg…
kvlonge Nov 6, 2026
da4aefc
Re-record the Postgres baseline on parser tree de1cb0ac
kvlonge Nov 6, 2026
6671521
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
f9d6ec5
Land the reviewer's nineteenth Postgres batch on parser tree de1cb0ac
kvlonge Nov 6, 2026
f6079af
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
2a86404
Give CREATE TYPE's INTERNALLENGTH a number
kvlonge Nov 6, 2026
395d30e
Land the reviewer's approval of create-type.input-output
kvlonge Nov 6, 2026
48a9319
Parse the catalog CREATE statements
kvlonge Nov 6, 2026
98e7ee6
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
2539f45
Merge remote-tracking branch 'origin/wip/pg-local-parser' into wip/pg…
kvlonge Nov 6, 2026
00b4e8a
Merge remote-tracking branch 'origin/wip/pg-obligation-notes-5' into …
kvlonge Nov 6, 2026
6c35f8e
Re-record the Postgres baseline on parser tree dcaf2931
kvlonge Nov 6, 2026
e5ff59b
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
fd98fa1
Land the reviewer's twenty-first Postgres batch on parser tree dcaf2931
kvlonge Nov 6, 2026
ddc9bf6
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
8b918a2
Parse CREATE ROLE, USER, GROUP, POLICY and USER MAPPING
kvlonge Nov 6, 2026
efd8e90
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
5cd42ce
Merge remote-tracking branch 'origin/wip/pg-local-parser' into wip/pg…
kvlonge Nov 6, 2026
8dc5d05
Re-record the Postgres baseline on parser tree 416dd30e
kvlonge Nov 6, 2026
4fbbebe
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
27b36a1
Land the reviewer's twenty-second Postgres batch on parser tree 416dd30e
kvlonge Nov 6, 2026
878d850
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
e2b4104
Keep retired Postgres obligation ids as tombstones
kvlonge Nov 6, 2026
44bce66
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
86bff65
Refuse a rebuild that drops an obligation id without a tombstone
kvlonge Nov 6, 2026
0ef34c5
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
26cdfed
Give every role option of CREATE ROLE, USER and GROUP its own obligation
kvlonge Nov 6, 2026
1a48c3c
Answer the batch-19 and batch-21 coverage notes on the Postgres DDL f…
kvlonge Nov 6, 2026
cf58e1c
Merge branch 'wip/pg-local-parser' into wip/pg-integration
kvlonge Nov 6, 2026
0fe50f1
Parse ALTER ROLE, USER, GROUP, POLICY, SYSTEM and USER MAPPING
kvlonge Nov 6, 2026
e7d6100
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
7da3344
Re-record the Postgres baseline on parser tree 8650b82c
kvlonge Nov 6, 2026
041cdc0
Merge branch 'wip/pg-catalogue' of https://github.com/sqlstack-io/sql…
kvlonge Nov 6, 2026
a0c1fe8
Land the reviewer's twenty-fourth Postgres batch on parser tree 8650b82c
kvlonge Nov 6, 2026
da3f754
Merge branch 'wip/pg-catalogue' of https://github.com/sqlstack-io/sql…
kvlonge Nov 6, 2026
00a2897
Name the commit that retired the batch-19 and batch-21 obligation ids
kvlonge Nov 6, 2026
a035e9e
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-ob…
kvlonge Nov 6, 2026
0f778fb
Answer the batch-24 coverage notes on ALTER POLICY
kvlonge Nov 6, 2026
84836c7
Write CREATE TYPE's string LIKE and COLLATABLE values as operand classes
kvlonge Nov 6, 2026
b250b1a
Name the commit that retired CREATE TYPE's string-value negatives
kvlonge Nov 6, 2026
e417bb1
Keep array bounds after SETOF
kvlonge Nov 6, 2026
f19ef14
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
e943480
Merge branch 'wip/pg-local-parser' into wip/pg-integration
kvlonge Nov 6, 2026
bb2b2b7
Test the strict parser's byte coverage check on its own
kvlonge Nov 6, 2026
ffb8534
Merge branch 'wip/pg-parser' into wip/pg-local-parser
kvlonge Nov 6, 2026
8f17e05
Merge branch 'wip/pg-local-parser' into wip/pg-integration
kvlonge Nov 6, 2026
269f654
Merge remote-tracking branch 'origin/main' into wip/pg-integration
kvlonge Nov 6, 2026
4ea067d
Land the reviewer's twenty-fifth Postgres batch on parser tree 8650b82c
kvlonge Nov 6, 2026
9505f30
Answer the batch-25 coverage notes on foreign partitions and publicat…
kvlonge Nov 6, 2026
5348cab
Merge branch 'wip/pg-catalogue' of https://github.com/sqlstack-io/sql…
kvlonge Nov 6, 2026
3de1421
Re-record the Postgres baseline on parser tree d7df6560
kvlonge Nov 6, 2026
f586384
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-ob…
kvlonge Nov 6, 2026
790aa37
Land the reviewer's twenty-sixth Postgres batch on parser tree 8650b82c
kvlonge Nov 6, 2026
6f2c2a6
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
c55b7bc
Merge remote-tracking branch 'origin/main' into wip/pg-integration
kvlonge Nov 6, 2026
28317bc
Record the two joined SET ... RESET form ids as splits, and cite the …
kvlonge Nov 6, 2026
9a7f865
Name the commit that retired the two publication notes
kvlonge Nov 6, 2026
df3c5e5
Require the bare SAVEPOINT and PREPARE names the batch-27 review foun…
kvlonge Nov 6, 2026
891a88c
Land the reviewer's twenty-eighth Postgres batch on parser tree d7df6560
kvlonge Nov 6, 2026
f5a1b82
Merge remote-tracking branch 'origin/wip/pg-catalogue' into wip/pg-in…
kvlonge Nov 6, 2026
8c1a539
Revert "Bring the window nullability and coercion code under main's f…
kvlonge Nov 6, 2026
b80bac3
Revert "Keep window outputs unknown unless they never give NULL, and …
kvlonge Nov 6, 2026
8bc048e
Revert "Give each lineage output its most significant transform kind"
kvlonge Nov 6, 2026
bfdd56e
Test the Postgres verdict's opaque gap with TABLESAMPLE, which the pa…
kvlonge Nov 6, 2026
ee3a5db
Merge remote-tracking branch 'origin/main' into wip/pg-land-1
kvlonge Nov 6, 2026
c5f7a75
Merge remote-tracking branch 'origin/main' into wip/pg-land-1
kvlonge Nov 6, 2026
c7ea0f7
Merge remote-tracking branch 'origin/main' into wip/pg-land-1
kvlonge Nov 6, 2026
f2d93ee
Merge remote-tracking branch 'origin/main' into wip/pg-land-1
kvlonge Nov 6, 2026
264165c
fix: convert the clock under the built-in policy and guard only semi-…
kvlonge Nov 6, 2026
d157b5c
Let comments never change whether a statement converts (D327)
kvlonge Nov 6, 2026
26b589d
docs: state in the FROM rule's conditions which semi-structured colum…
kvlonge Nov 6, 2026
ad722dc
Merge remote-tracking branch 'origin/main' into feat/pivot-unaliased
kvlonge Nov 6, 2026
72e8064
Merge remote-tracking branch 'origin/main' into feat/table-flatten
kvlonge Nov 6, 2026
fc15d51
Merge remote-tracking branch 'origin/main' into fix/builtin-launch-re…
kvlonge Nov 6, 2026
7392627
Refuse an unaliased select item whose text holds a comment (D327)
kvlonge Nov 6, 2026
58731ec
Split the comment unwrap into named steps for fensu (D327)
kvlonge Nov 6, 2026
4d4f747
Merge feat/table-flatten into feat/pivot-unaliased
kvlonge Nov 7, 2026
9c008e0
Merge remote-tracking branch 'github/main' into fix/d327-select-comments
kvlonge Nov 7, 2026
a6e8689
Merge remote-tracking branch 'origin/main' into feat/pivot-unaliased
kvlonge Nov 7, 2026
4ea7859
Merge remote-tracking branch 'origin/main' into feat/pivot-unaliased
kvlonge Nov 7, 2026
bba7fe3
coverage: re-record the translation baseline with PIVOT without an al…
kvlonge Nov 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ members = [
"crates/sqlquack",
"crates/sqlquack-polyglot-check",
"crates/sqlquack-syntax-coverage",
"crates/sqlquack-syntax-postgres",
"crates/sqlquack-python",
]
exclude = ["fuzz"]
Expand Down Expand Up @@ -62,6 +63,7 @@ sqlquack-semantics = { path = "crates/sqlquack-semantics" }
sqlquack-snowflake = { path = "crates/sqlquack-snowflake" }
sqlquack-syntax = { path = "crates/sqlquack-syntax" }
sqlquack-syntax-derive = { path = "crates/sqlquack-syntax-derive" }
sqlquack-syntax-postgres = { path = "crates/sqlquack-syntax-postgres" }
stacker = "0.1"
syn = { version = "2", features = ["full"] }
tempfile = "3"
Expand Down
60 changes: 60 additions & 0 deletions cases/relational/pivot_unaliased.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# PIVOT without an alias column list: the names Snowflake gives the key columns, as dbt pivot
# models leave them.
category = "relational"
construct = "node:pivot"
session_profile = "utc-v1"

[[case]]
id = "pivot_star_without_alias_list"
description = "SELECT * over SUM(total) FOR channel IN ('web', 'store') with no alias list. Catches: key columns named web or WEB instead of the quoted text, a missing or NULL key, keys outside the list dropped, and the grouping column kept."
columns = [{ name = "order_id", type = "NUMBER(38,0)" }, { name = "channel", type = "VARCHAR" }, { name = "total", type = "NUMBER(12,2)" }]
rows = [
["1", "'web'", "10.50"],
["1", "'web'", "2.25"],
["1", "'store'", "4.00"],
["2", "'store'", "NULL"],
["2", "'phone'", "9.99"],
["3", "NULL", "1.00"],
["3", "'WEB'", "3.00"],
]
query = "SELECT * FROM (SELECT order_id, channel, total FROM input) PIVOT(SUM(total) FOR channel IN ('web', 'store')) ORDER BY order_id"
order = "ordered"
tags = ["null", "duplicates", "missing-key", "case-sensitive-key"]

[[case]]
id = "pivot_quoted_key_reference"
description = "The pivoted key columns read back by their quoted names, \"'web'\" and \"'store'\", through a table alias without a column list. Catches: the names not matching the quoted key text."
columns = [{ name = "order_id", type = "NUMBER(38,0)" }, { name = "channel", type = "VARCHAR" }, { name = "total", type = "NUMBER(12,2)" }]
rows = [
["1", "'web'", "10.50"],
["1", "'store'", "4.00"],
["2", "'web'", "1.00"],
]
query = "SELECT p.order_id, p.\"'web'\" AS web_total, p.\"'store'\" AS store_total FROM (SELECT order_id, channel, total FROM input) PIVOT(SUM(total) FOR channel IN ('web', 'store')) AS p ORDER BY p.order_id"
order = "ordered"
tags = ["null", "missing-key"]

[[case]]
id = "pivot_mixed_case_keys_without_alias_list"
description = "Keys with upper case, a space and an underscore, under MAX over BOOLEAN and no alias list. Catches: key names upper-cased, spaces changed, or the quotes dropped."
columns = [{ name = "customer_id", type = "VARCHAR" }, { name = "consent", type = "VARCHAR" }, { name = "granted", type = "BOOLEAN" }]
rows = [
["'c-1'", "'Email Opt'", "TRUE"],
["'c-1'", "'SMS_OPT'", "FALSE"],
["'c-2'", "'Email Opt'", "NULL"],
["'c-2'", "'other'", "TRUE"],
]
query = "SELECT * FROM (SELECT customer_id, consent, granted FROM input) PIVOT(MAX(granted) FOR consent IN ('Email Opt', 'SMS_OPT')) ORDER BY customer_id"
order = "ordered"
tags = ["null", "missing-key", "case-sensitive-key"]

[[case]]
id = "pivot_without_alias_list_over_no_rows"
description = "A PIVOT without an alias list over no rows. Catches: a row of NULLs instead of no rows, and the column names and types still described."
columns = [{ name = "order_id", type = "NUMBER(38,0)" }, { name = "channel", type = "VARCHAR" }, { name = "total", type = "NUMBER(12,2)" }]
rows = [
["1", "'web'", "10.50"],
]
query = "SELECT * FROM (SELECT order_id, channel, total FROM input WHERE total < 0) PIVOT(SUM(total) FOR channel IN ('web', 'store'))"
order = "bag"
tags = ["empty-input"]
33 changes: 33 additions & 0 deletions cases/semi-structured/table_flatten.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# FLATTEN written as TABLE(FLATTEN(...)) after a comma, with a positional input, as dbt models
# write it: the same rows as LATERAL FLATTEN(input => ...).
category = "semi-structured"
construct = "fn:FLATTEN"
session_profile = "utc-v1"

[[case]]
id = "table_flatten_positional_array"
description = "TABLE(FLATTEN(t.tags)) over an ARRAY column with a positional input: one row per element. Catches: the input not correlated to its row, empty arrays or NULL giving rows, or elements out of order."
columns = [{ name = "ticket_id", type = "NUMBER(38,0)" }, { name = "tags", type = "ARRAY" }]
rows = [
["1", "ARRAY_CONSTRUCT('billing', 'urgent')"],
["2", "ARRAY_CONSTRUCT()"],
["3", "NULL"],
["4", "ARRAY_CONSTRUCT('refund')"],
]
query = "SELECT t.ticket_id, f.index, f.value::STRING AS tag FROM input t, TABLE(FLATTEN(t.tags)) f ORDER BY t.ticket_id, f.index"
order = "ordered"
tags = ["null", "array-index"]

[[case]]
id = "table_flatten_named_variant_path"
description = "TABLE(FLATTEN(input => v:items)) over a VARIANT path, with KEY, PATH and VALUE read back. Catches: the named input ignored, objects read as arrays, or JSON null and missing paths giving rows."
columns = [{ name = "k", type = "NUMBER(2,0)" }, { name = "v", type = "VARIANT" }]
rows = [
["1", "PARSE_JSON('{\"items\":[{\"sku\":\"A-10\"},{\"sku\":\"B-20\"}]}')"],
["2", "PARSE_JSON('{\"items\":{\"b\":1,\"a\":2}}')"],
["3", "PARSE_JSON('{\"items\":null}')"],
["4", "PARSE_JSON('{}')"],
]
query = "SELECT i.k, f.index, f.key, f.path, f.value::VARCHAR AS value FROM input i, TABLE(FLATTEN(input => i.v:items)) f ORDER BY i.k, f.index, f.key"
order = "ordered"
tags = ["null", "json-null", "missing-key", "nested", "array-index", "case-sensitive-key"]
172 changes: 172 additions & 0 deletions coverage/syntax-postgres/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# PostgreSQL syntax catalogue

The denominator of SQLQuack's PostgreSQL syntax coverage: every documented PostgreSQL 18.6 syntax
form, one record per form, with a stable id `pg.<family>.<slug>[.<variant>]`. The layout and the
record formats are those of `coverage/syntax` (see `docs/syntax-coverage.md`); this file records
what differs.

## Source

The pinned source is the release tarball `postgresql-18.6.tar.bz2` (sha256 in `indexes.toml`),
not the rendered website. Its DocBook SGML is what postgresql.org/docs/18 is built from, so a
source id `doc.<docbook-id>` names the page `https://www.postgresql.org/docs/18/<docbook-id>.html`.
`indexes.toml` also binds the files the page list is read from (`reference.sgml`,
`ref/allfiles.sgml`, `filelist.sgml`, `postgres.sgml`) and the grammar the omission audit reads
(`src/backend/parser/gram.y`, `src/include/parser/kwlist.h`).

A page is either

- a SQL command reference page (a `refentry` of the SQL Commands part, 183 pages), or
- a `sect1` (or a chapter's introduction) of the SQL-language chapters: syntax, ddl, dml,
queries, datatype, json, array, rowtypes, rangetypes, func, typeconv, indices, textsearch, mvcc,
perform and parallel.

`page_sha256` is the sha256 of that SGML text; `syntax_sha256` of its synopsis blocks and
signatures.

## Regenerating

```sh
python -m scripts.fetch_syntax_docs_pg CACHE # private cache, never committed
python -m scripts.build_syntax_catalogue_pg --cache CACHE --out coverage/syntax-postgres
```

The build writes nothing while any input is unresolved: a synopsis block with no disposition, a
disposition naming no block, a restatement of an uncatalogued form, or a hand form whose page
changed. PostgreSQL 19 is an in-place rebuild against its tarball; ids follow the same keeping
rules as the Snowflake catalogue (`scripts/syntax_catalogue/_helpers/forms.py`, reused by import).

## Omission audit (`audit.toml`)

```sh
python -m scripts.audit_syntax_catalogue_pg --cache CACHE
```

An independent check against the server's own grammar, `gram.y` and `kwlist.h` of the pinned
release. It reads every rule of gram.y and spells each alternative of every rule reachable from
`toplevel_stmt`, `stmt` and the expression rules (720 of 733 rules, with no depth bound) as keyword
sequences,
expanding nonterminals that are keyword sets (`DROP object_type_any_name` checks DROP TABLE,
DROP SEQUENCE and so on). A sequence is covered when some catalogued form, with its page's
definitions inlined, contains its keywords in order; for a statement the form's leading required
keywords must also appear in the sequence, so DROP FOREIGN TABLE does not cover DROP TABLE.
Every kwlist.h keyword that a production uses must appear in some grammar.

`audit.toml` binds the sha256 of gram.y and kwlist.h and gives a reviewed reason for every
production that no form covers (`[[production]]`, keyed by rule and production text) and every
keyword that no grammar names (`[[keyword]]`). The audit fails on an unreviewed gap, a review
naming no current gap, or a changed grammar file. The reasons are of three kinds: syntax gram.y
accepts that the 18.6 documentation does not document (the spelling ANALYSE, GLOBAL and LOCAL
before TEMPORARY outside CREATE TABLE, `BETWEEN ASYMMETRIC`, `TREAT`, `NCHAR`); productions that
only raise an error (CREATE ASSERTION, `ALTER TYPE ... DROP VALUE`, UNENCRYPTED PASSWORD); and
documented values of a placeholder (`NFC`, `OUT`, `SETOF`). Single-keyword alternatives below a
statement are checked by the keyword rule only.

`[[unwalked]]` lists each of the 13 rules the walk does not reach with its reason: the start
symbol and top-level wrappers, the PL/pgSQL-only parse modes and the five keyword category lists.
The audit fails on an unwalked rule that is not listed. `limits` states what the method does not
check, such as identifiers, punctuation and adjacency of keywords.

## Form rules

1. **Command pages.** The `<refsynopsisdiv>` synopsis is split into statements at each unindented
line that starts with the command's first word (SELECT also `WITH` and `TABLE`). Each
statement is a form. `<phrase>where X is:</phrase>` (and `and X is`, `X in ... is`) starts a
sub-grammar definition, `[[definition]]` `doc.<page>::<X>`; `can be one of` / `is one of`
lists its alternatives one per line.
2. **Actions.** A statement whose grammar takes `<action> [, ... ]`, where the page lists
`action` as alternatives (ALTER TABLE and six other ALTER pages), becomes one form per action, with the
action substituted into the statement.
3. **Other synopsis blocks** (on command pages outside the Synopsis, and in the chapters) each
have a reviewed disposition in `hand.toml` `[[block]]`, keyed by page and block sha256:
`form` (each production a form; on a command page, older syntax still accepted, named
`<page>.<label>`), `calls` (signatures grouped as functions), `definition`, `restated` (the
page joins the listed forms' `also_sources`), or `fragment` / `hand` with a reason.
4. **Functions and operators.** Every `func_signature` of func.sgml is read. Plain call
signatures of one function name on one page form one `call` form, `pg.functions.<page>.<name>`;
a signature with its own keyword grammar (`substring(... FROM ... FOR ...)`, `WITHIN GROUP`,
`ORDER BY` inside the call, the SQL/JSON constructors, keyword functions written without
parentheses) is a `special` form per name and keyword skeleton. Operator signatures form one
`special` form per operator per page in `expressions`, `pg.expressions.<page>.op-<chars>` or
the keywords of a keyword operator. Table sections that catalogue no form are listed in
`hand.toml` `[[signatures]]` with the reason.
5. **Data types.** Each row of the Data Types, Special Character Types, Object Identifier Types
and Pseudo-Types tables is a form in `expressions`; aliases are alternatives.
6. **Hand forms** (`hand.toml` `[[form]]`): lexical syntax and expressions written in prose or
examples (identifiers, string and bit-string constants, comments, constructors, named
notation, array types, interval fields, range constructors, ILIKE), the comparison operators
whose table uses the generic `datatype`, SET SCHEMA and SET NAMES, the SQL function bodies
(`RETURN`, `BEGIN ATOMIC`) of CREATE FUNCTION and CREATE PROCEDURE, and the deprecated CREATE
ROLE clauses.

Families: `query`, `dml`, `ddl`, `transaction_session`, `security_admin`, `utility`, `functions`,
`expressions`. There is no `classes` or `scripting` family: PL/pgSQL bodies are string constants
to the server grammar, and DO and CREATE FUNCTION are catalogued as statements.

## Obligations and cases

```sh
python -m scripts.build_syntax_obligations_pg [--root ROOT] [--focus focus/postgres.toml]
```

Obligations are derived for every catalogued form by the shared builder
(`scripts/syntax_obligations`, reused by import). `scripts/syntax_obligations_pg` adds what is
Postgres's own: the submission context of each family (statements as written, expressions inside
`SELECT ( … )` so a trailing keyword is never read as a bare column label, data types inside
`CAST ( NULL AS … )`), placeholder fills by synopsis name, class rules for operator and function
placeholders that name a value of a type, and a grammar read that writes a form's bare words in
upper case (Postgres synopses spell keywords and type names in lower case; every placeholder is
in angle brackets), with a few list spellings rewritten so the renderer can copy them
(`GRAMMAR_REWRITES` in its constants: ONLY and `*` as alternatives, as gram.y relation_expr takes
them; LIMIT and FETCH as one clause; DISTINCT with a required select list; a with_query as
name AS ( query ); a list's second item written out; a window definition optional inside
OVER). The grammar is tokenized with Postgres's operators: a run of operator characters
(`&&`, `<->`, `?-|`, …) is one token, and `\[ \]` in a reading is a literal bracket (array
constructors, subscripts and array types) rather than an optional part. `limits.toml` holds the
readings, suppressions and hand-written limits, each with its reason, in the format of
`coverage/syntax/limits.toml`. Most expressions suppressions are one gram.y fact: every
operator token is also a prefix operator (`qual_Op a_expr`), so an operator form with its left
operand left out is valid syntax; with its right operand left out it stays a negative.
Function parameters written `<name type>` are expressions (gram.y func_arg_expr), whatever
their name suggests; the catalogue cuts a signature at its return value, so a set-returning
function's output columns are not read as call syntax.

An obligation keeps its id across rebuilds. `retired.toml` lists every id that has left the
root, grouped by the commit that retired it, with the reason; the builder reserves those numbers,
so they are never issued again, and fails if a retired id reappears in `obligations/` or if a
rebuild drops an id that `retired.toml` does not list, so a changed meaning always takes a new id. Its
`[[reused]]` rows record the two ids that were issued again with a new meaning before retirement
was recorded; both forms were approved with the new meaning, so those ids stay.

Cases are written for every catalogued form of the families in `CASED_FAMILIES`, which now
lists all eight; `focus/postgres.toml` set only the order in which they were taken up.
`pending.toml` lists cases held out of the receipts because the referee cannot yet run or judge
them as written, each with the referee change it waits on; a pending case is not verified. Each case has the referee's shape: the session
`{"TimeZone": "UTC", "statement_timeout": "30s"}`, capture `execute_in_rolled_back_transaction`,
or `execute_autocommit_in_throwaway_database` for statements Postgres refuses inside a
transaction block (the referee's `engine.toml` `autocommit` list), no setup, and one statement
without a terminating semicolon. `elisions/` is not written: the Snowflake elision rules do not
apply, and the few Postgres `...` fills are style entries.

Receipts (`receipts/*.jsonl`, format `sqlquack-syntax-receipt/2`) are recorded by the Postgres
referee (`engines/postgres`) against the pinned 18.6 image; the raw records and run audits stay
private. `runs.toml` records how each run was isolated: the earlier runs shared one long-lived
container, and the ddl, transaction_session, utility and security_admin runs each had a fresh
container of the pinned image, removed afterwards, with its start and end state and a repeat
run that matched. The case build reads them as the shared builder does: an accepted case takes its
receipt's later stage, and an observed case its receipt's outcome.

`baseline.json` is the claims snapshot (`syntax-coverage snapshot --root
coverage/syntax-postgres`), bound to catalogue commit 1a48c3c5 and to the Postgres parser's tree
on `wip/pg-integration` 5348cab6 (tree d7df6560), where `local_parser = "postgres"` runs that
parser's strict entry point in the checker's isolated worker: any parser error rejects the case.
It claims 19,346 of 22,726 obligations and the 1,384 forms the reviewers' batches through 22 and 24
to 28 approved (batch 27 is held until its parser tree lands); a statement the parser keeps as an opaque command is never verified. It holds the 822
cases Postgres rejects that the parser accepts as opaque, so `syntax-coverage diff
coverage/syntax-postgres/baseline.json --root coverage/syntax-postgres` fails on any regression
from here.

`reviews/auditor-<family>.toml` holds the independent reviewers' approvals (D235, D238). Each
`[[review]]` is copied verbatim from the reviewer's record on `wip/syntax-omission-audit`
(`coverage/syntax/audits/pg-review-*.toml`) and holds while each form's fingerprint and definition
hash are unchanged.
12 changes: 12 additions & 0 deletions coverage/syntax-postgres/aliases.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Renamed, split and merged form ids. An old id stays in the catalogue with status
# absent_from_source and is never reused; `to` lists the forms that now carry its grammar.

[[alias]]
from = "pg.transaction_session.set-role.none-reset-role"
to = ["pg.transaction_session.set-role.set-role-none", "pg.transaction_session.set-role.reset-role"]
reason = "the synopsis reader joined the documented line RESET ROLE onto SET [ SESSION | LOCAL ] ROLE NONE, giving one form for two statements that is not valid SQL; the sql-set-role synopsis lists them as separate lines, now one form each (19aa1f28)"

[[alias]]
from = "pg.transaction_session.set-session-authorization.default-reset-session-authorization"
to = ["pg.transaction_session.set-session-authorization.set-session-authorization-default", "pg.transaction_session.set-session-authorization.reset-session-authorization"]
reason = "the synopsis reader joined the documented line RESET SESSION AUTHORIZATION onto SET [ SESSION | LOCAL ] SESSION AUTHORIZATION DEFAULT, giving one form for two statements that is not valid SQL; the sql-set-session-authorization synopsis lists them as separate lines, now one form each (19aa1f28)"
Loading
Loading