Skip to content

adapter: Reject reserved role specification names in CREATE ROLE#37644

Merged
ggevay merged 1 commit into
MaterializeInc:mainfrom
ggevay:gabor/sql-502-create-role-reserved-names
Jul 15, 2026
Merged

adapter: Reject reserved role specification names in CREATE ROLE#37644
ggevay merged 1 commit into
MaterializeInc:mainfrom
ggevay:gabor/sql-502-create-role-reserved-names

Conversation

@ggevay

@ggevay ggevay commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Fixes SQL-502

Motivation

CREATE ROLE CURRENT_USER used to create a role literally named
current_user. PostgreSQL rejects CURRENT_USER, CURRENT_ROLE,
SESSION_USER, USER, and NONE as role names because they act as role
specifications in statements like GRANT ... TO CURRENT_USER, where a role
with such a name would be ambiguous. Found via the CockroachDB logic test
import (#37459).

Description

CREATE ROLE now rejects the role names current_user, current_role,
session_user, user, and none with "role name ... is reserved", the same
way it already rejects public and the mz_/pg_ prefixes. The new names
are added to is_reserved_role_name, the single choke point that covers role
creation via SQL, role creation via JWT group sync, and pgwire login
validation.

The check is on the normalized (lowercase) name rather than at parse time.
PostgreSQL rejects the unquoted keyword forms while still allowing the quoted
spelling CREATE ROLE "current_user", but our lexer does not treat these
words as keywords and does not track whether an identifier was quoted, so the
quoted lowercase forms are rejected too. That is a small deviation from
PostgreSQL that errs on the safe side: a role named current_user is exactly
the ambiguity being prevented. Quoted spellings that do not normalize to a
reserved lowercase name, such as CREATE ROLE "CURRENT_USER", remain valid,
as in PostgreSQL. GRANT ... TO PUBLIC and friends are unaffected.

Verification

Added regression tests to test/sqllogictest/role.slt covering all six
reserved names (quoted and unquoted) plus the allowed quoted-uppercase case,
and a unit test in group_sync.rs pinning the is_reserved_role_name
contract. Edge-case behavior (which names PostgreSQL rejects, with which
messages, quoted vs. unquoted) was compared against a live PostgreSQL 18.

🤖 Generated with Claude Code

@ggevay ggevay added the A-ADAPTER Topics related to the ADAPTER layer label Jul 14, 2026
CREATE ROLE CURRENT_USER used to create a role literally named
"current_user". PostgreSQL rejects CURRENT_USER, CURRENT_ROLE,
SESSION_USER, USER, and NONE as role names because they act as role
specifications in statements like GRANT ... TO CURRENT_USER, where a
role with such a name would be ambiguous.

Extend is_reserved_role_name with these names so that role creation,
JWT group sync, and pgwire logins all reject them. The check is on the
normalized lowercase name because the parser does not track whether an
identifier was quoted. Quoted uppercase spellings like "CURRENT_USER"
remain valid role names, as in PostgreSQL.

Part of SQL-502.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ggevay ggevay force-pushed the gabor/sql-502-create-role-reserved-names branch from d0fba32 to 313717f Compare July 14, 2026 17:40
@ggevay ggevay marked this pull request as ready for review July 14, 2026 19:09
@ggevay ggevay requested a review from a team as a code owner July 14, 2026 19:09
@ggevay ggevay merged commit 605cc6f into MaterializeInc:main Jul 15, 2026
121 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-ADAPTER Topics related to the ADAPTER layer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants