GeezerVison is showing github.com — Extend PostgreSQL COMMENT ON targets by minleejae · Pull Request #2816 · JSQLParser/JSqlParser
Conversation
minleejae
commented
Oct 14, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
Purpose
Parse the remaining common PostgreSQL COMMENT ON targets. COMMENT ON TRIGGER trg ON users IS '...', as well as POLICY, EXTENSION, DATABASE and ROLE comments, fail in every configuration. Schema dumps and migrations routinely contain these statements. #2639 added eight target kinds; this change covers most of the rest of the PostgreSQL 18 list with the same model.
Current design (As-is)
CommentTarget models INDEX, SCHEMA, SEQUENCE, DOMAIN, TYPE, MATERIALIZED VIEW, FUNCTION and CONSTRAINT.
- Each grammar alternative pairs its keyword with its own name parsing. Only
CONSTRAINT has an owning relation, and only FUNCTION has a signature.
- Every other kind fails with a
ParseException, for example Encountered: <K_TRIGGER>.
- The shared
RoutineReference production reads ORDER as an argument name. Ordered-set aggregate signatures without direct arguments, such as mode(ORDER BY anyelement), therefore fail. This also affects ALTER EXTENSION ... ADD AGGREGATE.
Target design (To-be)
- Extend
CommentTarget.Kind instead of adding a parallel model:
- Within a table:
TRIGGER, POLICY and RULE use getName() and getRelation(), like CONSTRAINT. Only CONSTRAINT accepts ON DOMAIN.
- Routine signatures:
PROCEDURE, ROUTINE and AGGREGATE use the shared RoutineReference, like FUNCTION. AGGREGATE requires a signature and accepts (*) and ORDER BY.
- Casts:
CAST (source AS target) exposes getSourceType() and getTargetType(). This is the same shape as the CAST member of ALTER EXTENSION.
- Named objects: these use
getName().
COLLATION, FOREIGN TABLE and STATISTICS, which may be schema-qualified.
DATABASE, ROLE, TABLESPACE, ACCESS METHOD, EXTENSION, FOREIGN DATA WRAPPER, SERVER, EVENT TRIGGER, PUBLICATION and SUBSCRIPTION.
[PROCEDURAL] LANGUAGE, where isProcedural() records the spelling.
Kind.isRoutine() and Kind.isOwnedByRelation() describe the reference shape. The grammar and appendTo() both use them.
- Grammar:
CommentTargetKind() reads the kind words first. CommentTarget() then uses semantic lookahead on the kind to select the reference shape.
- No new tokens. Kind words without a token, such as
ROLE, RULE and SERVER, are matched with isKeywordAhead() and ContextualKeyword(), so they remain identifiers elsewhere.
- There are no choice conflicts.
RoutineReference: skip the direct-argument list when ORDER BY immediately follows (.
- Traversal: table discovery and
StatementVisitorAdapter visit foreign tables and the tables that own triggers, policies and rules, through getReferencedRelation(). Custom deparsers can rewrite these names. Routines, roles, databases and other catalog objects are never reported as tables.
- Validation: one
Feature.commentOn... per new kind, as in feat: support additional PostgreSQL COMMENT targets #2639. All of them are enabled in the PostgreSQL feature set. PROCEDURE/ROUTINE need PostgreSQL 11, but they stay in the base set, as executeCall already does.
- Compatibility: the existing kinds keep their rendering, and the public API only gains additions.
- Not included:
OPERATOR [CLASS|FAMILY], TEXT SEARCH ..., CONVERSION, LARGE OBJECT and TRANSFORM.
Validation
- 188 new test cases:
CommentTargetTest goes from 74 to 240 and CommentValidatorTest from 10 to 32. They cover:
- every new kind: parse, then toString and deparser, then reparse, both with
Dialect.POSTGRESQL and without a dialect;
- AST fields:
- kind;
- quoted, dotted and Unicode name components;
- owning relation;
- signature modes,
* and ORDER BY;
- cast types;
PROCEDURAL;
- table discovery and custom deparser relation rewrites;
- 21 rejected forms, for example
TRIGGER t ON DOMAIN d, PROCEDURE p(*), AGGREGATE a and CAST (integer);
- kind words used as identifiers;
- a check that every
Kind maps to a validation feature.
- Java 17 offline Gradle
spotlessApply check: 10,543 tests, 10,518 passed, 25 skipped, zero failures/errors. The grammar conflict check, Checkstyle, PMD and SpotBugs pass.
- Compared with
master (bdf8ac31) on a corpus of 635 MySQL 8.4 and PostgreSQL 18 DDL/DCL statements, each accepted by the server, plus variants and keyword cases, with and without a dialect:
COMMENT ON TRIGGER/POLICY/EXTENSION/DATABASE/ROLE now parse in both the PostgreSQL dialect and the default mode.
- Zero regressions and no other status changes.
- AST dumps of all previously parsed statements are unchanged.
- MySQL 8.4 and PostgreSQL 18.3: every corpus statement this branch parses ran as written on one server and as rendered by
toString() on a second, identical server, in the same order. All 205 MySQL and 332 PostgreSQL statements give the same result (success, or the same error).
Integration validation
Applied #2806–#2819 together on master (bdf8ac31), with the stacked PRs on top of their bases (#2806 → #2807 → #2808, #2806 → #2809 → #2810 and #2811 → #2812).
- Each branch merges cleanly into
master. Between the branches, conflicts are limited to adjacent additions (README/index rows, usage sections, imports, visitor and feature lists, one enum line and one alias guard).
- The integrated build passes Java 17 offline Gradle
spotlessApply check: 11,494 tests, 11,469 passed, 25 skipped, zero failures/errors. The grammar choice conflict check passes.
- On a corpus of 635 MySQL 8.4 and PostgreSQL 18 DDL/DCL statements, each accepted by the server, the integrated build parses 265 of 271 MySQL statements (
master: 206) and 363 of 364 PostgreSQL statements (master: 328). Every MySQL 8.4 non-reserved word and PostgreSQL 18 unreserved or column-name keyword parses as a column and table name.
- On paired MySQL 8.4 and PostgreSQL 18.3 servers, all 263 MySQL and 362 PostgreSQL statements rendered by the integrated build give the same results as the originals.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Model the remaining common PostgreSQL COMMENT ON object kinds with the
existing CommentTarget: TRIGGER, POLICY and RULE within a table;
PROCEDURE, ROUTINE and AGGREGATE signatures through RoutineReference;
CAST; and ACCESS METHOD, COLLATION, DATABASE, EVENT TRIGGER, EXTENSION,
FOREIGN DATA WRAPPER, FOREIGN TABLE, [PROCEDURAL] LANGUAGE, PUBLICATION,
ROLE, SERVER, STATISTICS, SUBSCRIPTION and TABLESPACE.
The grammar reads the kind first and lets it select the reference
shape. Kind words without a token stay non-reserved. Shared routine
signatures now accept ordered-set aggregates without direct arguments,
such as mode(ORDER BY anyelement).
Signed-off-by: minleejae <[email protected]>
This was referenced Oct 14, 2026
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|