Skip to content

Add support for PostgreSQL's CREATE/DROP EXTENSION - #329

Open
Niols wants to merge 1 commit into
ygrek:masterfrom
Niols:psql-create-drop-extension
Open

Niols wants to merge 1 commit into
ygrek:masterfrom
Niols:psql-create-drop-extension

Conversation

@Niols

@Niols Niols commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Both statements are accepted with -dialect postgresql, so that migration files that install pg_trgm and friends can be fed to sqlgg unchanged.

sqlgg keeps no extension state, so there is nothing to track: the optional SCHEMA, VERSION and CASCADE clauses are parsed and discarded, an extension can be dropped without having been created, and the statements evaluate to Stmt.Other rather than getting a statement kind of their own.

They are gated behind a new extension dialect feature, PostgreSQL only, like the existing user_defined_type gate on CREATE TYPE.

extension, schema and version become keywords, so they are added to ident to keep them unreserved, the way type already is.

CREATE EXTENSION's trailing [ WITH ] ... clause is ambiguous with a following statement that starts with a WITH (a CTE), which LR(1) cannot resolve. Both statements therefore live in a new top_statement rule used only by input, where EOF bounds the clause. Extensions are database-global DDL that has no business in a routine body anyway.

Both statements are accepted with -dialect postgresql, so that migration
files that install pg_trgm and friends can be fed to sqlgg unchanged.

sqlgg keeps no extension state, so there is nothing to track: the optional
SCHEMA, VERSION and CASCADE clauses are parsed and discarded, an extension
can be dropped without having been created, and the statements evaluate to
Stmt.Other rather than getting a statement kind of their own.

They are gated behind a new `extension` dialect feature, PostgreSQL only,
like the existing `user_defined_type` gate on CREATE TYPE.

`extension`, `schema` and `version` become keywords, so they are added to
`ident` to keep them unreserved, the way `type` already is. Being unreserved,
they also join the filter in lsp/completion.ml that already excluded `type`:
the recovering parser accepts an unreserved keyword wherever an identifier
fits, so without this they would be offered as keyword completions in every
completion list.

CREATE EXTENSION's trailing `[ WITH ] ...` clause is ambiguous with a
following statement that starts with a WITH (a CTE), which LR(1) cannot
resolve. Both statements therefore live in a new `top_statement` rule used
only by `input`, where EOF bounds the clause. Extensions are database-global
DDL that has no business in a routine body anyway.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Niols
Niols force-pushed the psql-create-drop-extension branch from bb82bcc to ae8719e Compare September 15, 2026 18:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant