Tested against: origin/main @ a178aa5b6b0b260d105962c928f07304360b7b30 (fetched 2026-05-20)
Severity: Medium (breaks idempotent DDL patterns; PostgreSQL idiom standard)
CREATE ROLE IF NOT EXISTS <name> parses IF as the role name. Same parser-bug family as CREATE TENANT IF NOT EXISTS (filed separately).
Reproduction
-- First attempt: parser treats 'IF' as role name and CREATES role named 'IF'
CREATE ROLE IF NOT EXISTS mae8_admin;
-- → (silent success on first invocation; role 'IF' created)
-- Second attempt: now role 'IF' exists, error reveals the misparse:
CREATE ROLE IF NOT EXISTS mae8_admin;
-- → ERROR: bad request: role 'IF' already exists
The error message "role 'IF' already exists" is the dead giveaway — the parser is grabbing IF as the role identifier and ignoring everything after it.
Operational impact
Idempotent bootstrap scripts (the standard PostgreSQL pattern for cluster setup, where you re-run DDL safely) break here. Each CREATE ROLE IF NOT EXISTS X either creates a role named 'IF' (first time) or errors (subsequent times) — never creates a role named X. Combined with bug #lockout-app-errors, repeatedly trying CREATE ROLE IF NOT EXISTS in a script will lock out the superuser after 5 attempts.
CREATE COLLECTION IF NOT EXISTS and CREATE DATABASE IF NOT EXISTS appear to work correctly per spot check — so the parser handles this idiom for collections + databases but misses it for roles + tenants + users.
Suggested fix
Add IF NOT EXISTS to the CREATE ROLE grammar. Same pattern as CREATE COLLECTION / CREATE DATABASE that already work. Extend the fix to CREATE TENANT + CREATE USER in the same patch.
Workaround
Omit IF NOT EXISTS from CREATE ROLE statements; handle the "already exists" error in scripts. Also: scripts that did CREATE ROLE IF NOT EXISTS X on a fresh deployment have likely created a phantom 'IF' role on every such deployment — operators should grep audit logs for CREATE ROLE IF events.
Context
Caught during mae8 v2 Phase 0 bootstrap (2026-05-20). Full bug catalog: /home/system/rnd/mae8/docs/origin_bugs_2026-05-20.md (this is Bug 3 from that file).
Tested against:
origin/main @ a178aa5b6b0b260d105962c928f07304360b7b30(fetched 2026-05-20)Severity: Medium (breaks idempotent DDL patterns; PostgreSQL idiom standard)
CREATE ROLE IF NOT EXISTS <name>parsesIFas the role name. Same parser-bug family asCREATE TENANT IF NOT EXISTS(filed separately).Reproduction
The error message
"role 'IF' already exists"is the dead giveaway — the parser is grabbingIFas the role identifier and ignoring everything after it.Operational impact
Idempotent bootstrap scripts (the standard PostgreSQL pattern for cluster setup, where you re-run DDL safely) break here. Each
CREATE ROLE IF NOT EXISTS Xeither creates a role named'IF'(first time) or errors (subsequent times) — never creates a role namedX. Combined with bug #lockout-app-errors, repeatedly tryingCREATE ROLE IF NOT EXISTSin a script will lock out the superuser after 5 attempts.CREATE COLLECTION IF NOT EXISTSandCREATE DATABASE IF NOT EXISTSappear to work correctly per spot check — so the parser handles this idiom for collections + databases but misses it for roles + tenants + users.Suggested fix
Add
IF NOT EXISTSto the CREATE ROLE grammar. Same pattern as CREATE COLLECTION / CREATE DATABASE that already work. Extend the fix to CREATE TENANT + CREATE USER in the same patch.Workaround
Omit
IF NOT EXISTSfrom CREATE ROLE statements; handle the "already exists" error in scripts. Also: scripts that didCREATE ROLE IF NOT EXISTS Xon a fresh deployment have likely created a phantom'IF'role on every such deployment — operators should grep audit logs forCREATE ROLE IFevents.Context
Caught during mae8 v2 Phase 0 bootstrap (2026-05-20). Full bug catalog:
/home/system/rnd/mae8/docs/origin_bugs_2026-05-20.md(this is Bug 3 from that file).