Skip to content

WIP: PEG grammar / parser changes for FDW CREATE SERVER#43

Open
pashandor789 wants to merge 6 commits into
v2026.07.03from
wip/fdw-clickhouse-duckdb
Open

WIP: PEG grammar / parser changes for FDW CREATE SERVER#43
pashandor789 wants to merge 6 commits into
v2026.07.03from
wip/fdw-clickhouse-duckdb

Conversation

@pashandor789

@pashandor789 pashandor789 commented Jul 15, 2026

Copy link
Copy Markdown

PEG grammar + transformers for the FDW DDL statements, feeding serenedb's serenedb_* pragmas. This is the entire fork-side surface of the FDW work — everything else lives in serenedb proper (serenedb/serenedb#871).

Grammar

CreateServerStatement      <- 'CREATE' 'SERVER' IfNotExists? ColId 'FOREIGN' 'DATA'? 'WRAPPER' Identifier ServerOptions?
DropServerStatement        <- 'DROP' 'SERVER' IfExists? ColId DropBehavior?
CreateUserMappingStatement <- 'CREATE' 'USER' 'MAPPING' IfNotExists? 'FOR' UserMappingRole 'SERVER' ColId ServerOptions?
DropUserMappingStatement   <- 'DROP' 'USER' 'MAPPING' IfExists? 'FOR' UserMappingRole 'SERVER' ColId
UserMappingRole            <- 'PUBLIC' / 'CURRENT_USER' / 'USER' / ColLabel
ServerOption               <- ColLabel StringLiteral

Transformers lower each statement to a pragma (create_foreign_server, drop_foreign_server, create_user_mapping, drop_user_mapping) with the OPTIONS list as named parameters; serenedb registers the pragma implementations.

Notable decisions:

  • Server names are bare identifiers (ColId), like PGCREATE SERVER a.b is a syntax error, not a server literally named "a.b". An earlier revision used QualifiedName + a dotted-string flattening helper (copied from the tsdict template); both flattening helpers are gone.
  • CreateUserMappingStatement must be ordered before CreateRoleStatement in the statement alternation: RBAC's CREATE USER alias otherwise wins the PEG ordered choice and parses CREATE USER MAPPING as a role named MAPPING.
  • DROP SERVER reuses the standard DropBehavior rule for CASCADE/RESTRICT.

Build config

.github/config/extensions/clickhouse_scanner.cmake is deleted: serenedb now passes the extension's own extension_config.cmake through the existing DUCKDB_EXTENSION_CONFIGS embedder hook, so the fork carries no serenedb extension wiring. (The postgres/httpfs/avro/iceberg/inet shims still use the old in-fork pattern — migrating them is a separate cleanup.)

Inlined grammar regenerated via scripts/parser/build_grammar.sh; generated-file format drift was reverted so the diff stays semantic.

Testing

Via serenedb's sqllogic suites in duckdb#871: create_server_chscan (incl. the three qualified-name syntax-error pins), fdw_permissions/fdw_scenarios/fdw_creds/fdw_cascade_detach, create_server_pgscan, and both FDW recovery tests.

Stack: serenedb/serenedb#871 (main), serenedb/database-connector#1 (shared pushdown). Land this and database-connector#1 first; duckdb#871 pins the submodule pointers.

🤖 Generated with Claude Code

Pavel && Konstantin Vedernikoffs added 6 commits July 18, 2026 00:07
serenedb now passes third_party/duckdb_clickhouse/extension_config.cmake
through the DUCKDB_EXTENSION_CONFIGS variable (the embedder hook a few
lines below the .github/config resolution), so the extension's build
config lives with the extension and the fork carries no serenedb wiring.
CREATE/DROP SERVER and the SERVER reference in CREATE/DROP USER MAPPING
took a QualifiedName (copied from the schema-qualified tsdict template)
and flattened it to a dotted string, so CREATE SERVER a.b.c silently
created a server literally named "a.b.c" -- and erased the distinction
from the quoted identifier "a.b.c". PG's server_name is a plain ColId
and qualification is a syntax error; the grammar now matches, the two
copy-pasted *QualifiedNameToDottedString helpers are gone (ColId has a
registered Transform<string>, same as CREATE ROLE), and the inlined
grammar is regenerated (generated-file format drift reverted).
- DATA is required: FOREIGN WRAPPER without it is a syntax error (PG)
- UserMappingRole accepts CURRENT_ROLE and SESSION_USER (PG auth_ident)
- the mapped role is a ColId: reserved keywords are syntax errors, not
  roles literally named after them
transform_create_server.cpp + transform_create_user_mapping.cpp ->
transform_foreign_server.cpp: the verbatim-duplicated OPTIONS ->
named_parameters loop becomes one shared helper (same emplace order
and duplicate-option error); DropBehavior extraction uses the
existing TransformOptional<bool>; the two unreachable branches in
TransformUserMappingRole throw InternalException and its stale
parse-shape comment now documents the actual LIST->CHOICE->leaf
shape; RegisterCreateServer + RegisterCreateUserMapping ->
RegisterForeignServer.
Server credentials now live entirely in CREATE SERVER OPTIONS
(ClickHouse named-collection style), so USER MAPPING is gone:
create_user_mapping.gram deleted, the CREATE/DROP USER MAPPING
statements + their transformers removed. GrantObjType gains FOREIGN
SERVER so 'GRANT USAGE ON FOREIGN SERVER s TO role' parses (the
multi-keyword object type is joined in the rbac transformer).
@pashandor789
pashandor789 force-pushed the wip/fdw-clickhouse-duckdb branch from 57240a7 to b71276a Compare July 18, 2026 00:30
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