You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Slow seeding when having a large seed file and an anonymous block. #6686
Fast seed, as fast as when directly running with postgres, milliseconds at most.
Steps to reproduce
Have a seed file that looks like
DO $$
BEGIN/* 1 MB block of SQL code */
END $$;
Run the seed, e.g. by supabase db reset.
This takes over a minute to run, even if the sql itself is fast.
Removing the anonymous block makes it fast. It looks like the seed sql parser has some quadratic complexity for finding the closing $$.
Other tags with open/close semantics also cause slowness, like /* ... */ comments, a large file with those is also slow. Single line comments -- are not slow.
Reproduced on 2.117.0 and current develop. The statement splitter is quadratic in statement length. Root cause and a small fix below.
Cause:splitRaw (apps/cli/src/command-internal/sql-split.ts) builds the current statement with acc += rune, which Bun stores as a rope. The states then slice two or more characters from near the end of acc. Each such slice copies the whole rope, so it costs O(statement length). That happens:
on every rune inside a $$/$tag$ body (DollarState) or a /* */ comment (BlockState)
on every c/C (isBeginAtomic) and $ (hasIdentifierRuneBefore) outside quotes and comments
-- comments are unaffected because their delimiter is a single \n, and a one-character slice doesn't copy the rope. Migrations use the same splitter (parseMigrationContent in migration-file.ts), so a large DO $$ migration is just as slow.
Fix: track offsets and slice the flat input instead of concatenating. Only splitRaw changes:
End to end, supabase db reset with a 0.95 MiB DO $$ seed takes about 22 s on both 2.117.0 and develop, and 0.67 s with the fix. The same block as a migration takes 0.69 s with the fix. Database state and CLI output are identical.
sql-split.unit.test.ts passes unchanged. splitSqlTokens output also matches the current implementation on edge cases (nested block comments, tagged dollar quotes, BEGIN ATOMIC, doubled quotes, non-BMP characters, unterminated trailing statements) and on all the slow inputs.
Happy to open a PR with this and a regression test. Could this get the open-for-contribution label?
Activity
iamsharduld commentedon Sep 21, 2026
Reproduced on 2.117.0 and current
develop. The statement splitter is quadratic in statement length. Root cause and a small fix below.Cause:
splitRaw(apps/cli/src/command-internal/sql-split.ts) builds the current statement withacc += rune, which Bun stores as a rope. The states then slice two or more characters from near the end ofacc. Each such slice copies the whole rope, so it costs O(statement length). That happens:$$/$tag$body (DollarState) or a/* */comment (BlockState)c/C(isBeginAtomic) and$(hasIdentifierRuneBefore) outside quotes and comments--comments are unaffected because their delimiter is a single\n, and a one-character slice doesn't copy the rope. Migrations use the same splitter (parseMigrationContentinmigration-file.ts), so a largeDO $$migration is just as slow.Fix: track offsets and slice the flat input instead of concatenating. Only
splitRawchanges:Results (Bun 1.4.1, Apple M1 Pro):
splitAndTrim, one statementDO $$ … $$, before → after/* … */, before → afterEnd to end,
supabase db resetwith a 0.95 MiBDO $$seed takes about 22 s on both 2.117.0 anddevelop, and 0.67 s with the fix. The same block as a migration takes 0.69 s with the fix. Database state and CLI output are identical.sql-split.unit.test.tspasses unchanged.splitSqlTokensoutput also matches the current implementation on edge cases (nested block comments, tagged dollar quotes,BEGIN ATOMIC, doubled quotes, non-BMP characters, unterminated trailing statements) and on all the slow inputs.Happy to open a PR with this and a regression test. Could this get the
open-for-contributionlabel?fix(cli): stop large sql blocks stalling `db reset` (CLI-2469) (supab…