PgFlow.Sql.Splitter (PgFlow v0.1.0)

Copy Markdown View Source

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.

Functions

join(statements)

@spec join([String.t()]) :: String.t()

Join statements back into a single script with --SPLIT-- markers.

split(sql)

@spec split(binary()) :: [String.t()]

Split a SQL script into top-level statements.