EctoUnnest.Query (ecto_unnest v0.1.0)

Copy Markdown View Source

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 FROM source is the fragment unnest($1::t[], ...) AS u(col, ...). Column names and casts are dynamic (they depend on the column set), and fragment/1 as a macro requires a string literal — so from.source is built as an %Ecto.Query.FromExpr{} struct with properly alternating raw/expr parts (otherwise Ecto's Inspect blows up). The binding is named :s,
  • the SELECT is assembled with dynamic/2 via from(b in base, select: ^sel)field(s, ^col) for unnest columns, type(^val, type) for placeholders.

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

build(plan)

Builds the %Ecto.Query{} used as the source for Repo.insert_all/3.

to_sql(plan)

{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.

virtual(arrays, as)

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).