Skip to content

Statement splitter misparses atomic in function names as BEGIN ATOMIC keyword #5020

@ManuelCortes23

Description

@ManuelCortes23

Bug

The Supabase CLI statement splitter fails to parse multi-statement migration files when a function name contains the substring atomic (case-insensitive). It appears to misinterpret it as the SQL-standard BEGIN ATOMIC ... END; syntax, breaking $$ dollar-quoting detection.

Minimal reproduction

This 8-line migration fails on supabase db reset and supabase db push:

CREATE OR REPLACE FUNCTION fn_atomic()
RETURNS void LANGUAGE plpgsql AS $$
BEGIN
  NULL;
END;
$$;

SELECT 1;
ERROR: cannot insert multiple commands into a prepared statement (SQLSTATE 42601)

Change one character in the name and it passes:

CREATE OR REPLACE FUNCTION fn_atomix()
RETURNS void LANGUAGE plpgsql AS $$
BEGIN
  NULL;
END;
$$;

SELECT 1;

Verified behavior

  • atomic anywhere in the identifier triggers the bug: fn_atomic, atomic_fn, my_atomic_thing, xatomicx
  • Case-insensitive: ATOMIC, Atomic, atomiC all trigger it
  • Single-statement migrations (no SELECT 1 / REVOKE / GRANT after $$;) work fine regardless of name
  • The SQL is valid PostgreSQL — running the same file via psql works perfectly
  • Tested on CLI v2.75.0 and v2.84.2 on macOS (Darwin 24.6.0) — both affected

Expected behavior

The statement splitter should not treat atomic inside an identifier (e.g. fn_atomic) as the BEGIN ATOMIC keyword. BEGIN ATOMIC is only valid as a function body delimiter in SQL-standard syntax, not inside $$ dollar-quoted blocks or as part of an identifier.

Workaround

Split multi-statement migrations so each file contains a single statement, or avoid the substring atomic in function names.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions