Skip to content

fix: allow GROUPS as identifier by making it a non-reserved keyword (#2473) - #2474

Merged
manticore-projects merged 1 commit into
JSQLParser:masterfrom
fudianchn:fix/groups-nonreserved-2473
Aug 16, 2026
Merged

fix: allow GROUPS as identifier by making it a non-reserved keyword (#2473)#2474
manticore-projects merged 1 commit into
JSQLParser:masterfrom
fudianchn:fix/groups-nonreserved-2473

Conversation

@fudianchn

@fudianchn fudianchn commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

What

GROUPS becomes a non-reserved keyword again, so it can be used as an identifier (column, table, alias) while the GROUPS window frame unit keeps working:

SELECT groups FROM mytable
SELECT * FROM groups
CREATE TABLE mytable (groups INT)

Why / Root cause

#2460 (commit d92f407) introduced the PostgreSQL GROUPS frame unit and declared <K_GROUPS:"GROUPS"> in the reserved keyword token section. In PostgreSQL, GROUPS is a non-reserved keyword and stays a legal identifier, so statements like the ones above parsed before #2460 and fail on master with Encountered unexpected token: "groups".

The decision in #2460

Making GROUPS reserved was a deliberate, reviewed trade-off, not an oversight. #2460 initially declared K_GROUPS inside NonReservedWord() (24cf1bd); during review the raw <S_IDENTIFIER> productions (CREATE SCHEMA, SET PATH, Oracle KEEP, interval type, COLLATE, the ColDataType lookahead) were called out, and the token was then moved to the reserved set instead of broadening those productions.

One point that was not on the table then: the sibling frame units already live in exactly the state this PR restores for GROUPS. ROWS and RANGE are non-reserved on master, and the same raw-identifier productions reject them identically:

CREATE SCHEMA rows                -- fails on master
CREATE SCHEMA range               -- fails on master
SELECT a COLLATE rows FROM t      -- fails on master

while quoted forms (CREATE SCHEMA "groups") work everywhere. "Non-reserved, raw-identifier positions need quoting" is therefore the existing status quo for frame-unit keywords in this grammar, and this PR makes GROUPS consistent with ROWS and RANGE (all three are non-reserved in PostgreSQL) rather than introducing a new inconsistency.

If keeping GROUPS reserved is preferred, closing this PR is fine. If the raw-identifier productions should accept the frame-unit words, that would be a separate change applying to ROWS, RANGE and GROUPS alike; I can prepare it on request.

How

One symmetric relocation in JSqlParserCC.jjt: the <K_GROUPS:"GROUPS"> declaration moves from the reserved token section into the NonReservedWord() production (between GRANT and GROUP_CONCAT).

Tokens declared inside NonReservedWord() fall into the MIN_NON_RESERVED_WORDMAX_NON_RESERVED_WORD kind range, which RelObjectName() and isAliasAhead() already accept, and which KeywordsTest covers parameterized as identifiers. No other grammar rule changes, and the explicit <K_GROUPS> match in WindowElement() is unaffected (only the token kind numbering moves).

Scope

Only the keyword classification changes. GROUPS frame units (ROWS / RANGE / GROUPS BETWEEN ... EXCLUDE ...) keep parsing exactly as before; GROUPS additionally works in every identifier position covered by the non-reserved range guards (column, table, schema, alias, function name).

Testing

KeywordsTest.testGroupsAsIdentifier reproduces the issue (column, table, explicit and implicit alias, CREATE TABLE column definition): fails on master with JSQLParserException, passes with this change. The parameterized KeywordsTest identifier cases pick GROUPS up automatically (732 -> 734 tests).

Performance

gradle jmh, JSQLParserBenchmark.parseSQLStatements on performance.sql, version=latest, 10 forks x 10 iterations (100 samples) on a 32-core host:

build ms/op
master (406a4d4) 3.712 ± 0.020
this PR (37b6068) 3.709 ± 0.022

The -0.08% delta lies within the 99.9% confidence intervals (the CIs overlap almost entirely): no regression.

Verification of the original issue

All statements from #2473 fail on master and parse + round-trip with this change.

Fixes #2473

@manticore-projects

Copy link
Copy Markdown
Contributor

Thanks!

@manticore-projects
manticore-projects merged commit edfbb0a into JSQLParser:master Aug 16, 2026
7 checks passed
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.

[BUG] JSQLParser 5.4-SNAPSHOT : PostgreSQL : GROUPS cannot be used as an identifier anymore (regression via #2460)

2 participants