Builds the INSERT ... SELECT ... FROM unnest(...) query from Ecto building blocks.
Instead of assembling the whole SQL string by hand, we build an %Ecto.Query{}:
- the
FROMsource is the fragmentunnest($1::t[], ...) AS u(col, ...). Column names and casts are dynamic (they depend on the column set), andfragment/1as a macro requires a string literal — sofrom.sourceis built as an%Ecto.Query.FromExpr{}struct with properly alternatingraw/exprparts (otherwise Ecto'sInspectblows up). The binding is named:s, - the
SELECTis assembled as a%Ecto.Query.SelectExpr{}struct (the same shape Ecto compiles fromselect: ^map):field(s, col)forunnestcolumns,type(^val, type)for placeholders, andfragmentcasts for JSON columns (f0."col"::jsonb) and custom-typed placeholders ($n::type) — those need a runtime cast string adynamic/2fragment/1(literal-only) cannot express.
Execution and all of ON CONFLICT/RETURNING/prefix/struct loading are
delegated to Ecto.Repo.insert_all/3. to_sql/1 renders the same plan into the
full INSERT text with no database connection, via
Ecto.Adapters.Postgres.Connection.
Summary
Functions
Builds the %Ecto.Query{} used as the source for Repo.insert_all/3.
{sql, params} of the full INSERT — without executing, purely.
Returns an %Ecto.Query{} with just FROM unnest(...) AS u(...) and a named
binding as — a virtual table for free composition (where, select, join,
Repo.all, subquery/1).
Functions
Builds the %Ecto.Query{} used as the source for Repo.insert_all/3.
{sql, params} of the full INSERT — without executing, purely.
Uses the same building blocks as Repo.insert_all/3: it plans the query
(plan_query), reconstructs the planned on_conflict, and assembles the text
via the Postgres adapter's Connection module.
Returns an %Ecto.Query{} with just FROM unnest(...) AS u(...) and a named
binding as — a virtual table for free composition (where, select, join,
Repo.all, subquery/1).