Splits a raw PostgreSQL script into individual top-level statements.
Needed because Ecto.Migration.execute/1 dispatches through Postgrex
prepared-statement protocol, which rejects multi-command input with
42601 syntax_error. EctoEvolver runs each --SPLIT---delimited chunk
as a single execute/1 call, so the vendored SQL has to be pre-split
one-statement-per-chunk.
State machine
Top-level splitting ignores semicolons inside:
- single-quoted strings (
'...'with''escape) - double-quoted identifiers (
"..."with""escape) - dollar-quoted bodies (
$$ ... $$or$tag$ ... $tag$) - single-line comments (
-- ...\n) - block comments (
/* ... */, non-nested per Postgres grammar)
Only a ; seen in the top-level state ends a statement. Leading
whitespace and trailing whitespace on each statement are stripped; empty
chunks (whitespace / comments only) are discarded.
Output shape
iex> PgFlow.Sql.Splitter.split("SELECT 1; SELECT 2;")
["SELECT 1", "SELECT 2"]
iex> PgFlow.Sql.Splitter.split("-- comment\nSELECT 1;")
["-- comment\nSELECT 1"]Returns a list of trimmed statement strings in source order.
Summary
Functions
Join statements back into a single script with --SPLIT-- markers.
Split a SQL script into top-level statements.