Skip to main content

lib/ex_sql/ast/insert.ex

defmodule ExSQL.AST.Insert do
  @moduledoc """
  An `INSERT` (or `REPLACE INTO`) statement.

  `columns` is `nil` when the column list is omitted (all table columns in
  declaration order); column names may also be `rowid`/`oid`/`_rowid_` to
  set the rowid explicitly. `source` is one of:

    * `{:values, rows}` — a list of value-expression lists
    * `{:select, query}` — `INSERT INTO ... SELECT ...`
    * `:default_values` — `INSERT INTO ... DEFAULT VALUES`

  `or_conflict` carries the `OR` clause (`REPLACE INTO` parses as
  `or_conflict: :replace`). `upsert` is the list of `ON CONFLICT` clauses in
  source order: `{:nothing, target}` or `{:update, target, assignments,
  where}`, with `target` either `nil` (catch-all, last only) or
  `{columns, where}` for a targeted clause.
  """

  defstruct table: nil,
            schema: nil,
            target_qualified: false,
            columns: nil,
            source: nil,
            or_conflict: nil,
            upsert: [],
            returning: []

  @type source ::
          {:values, [[ExSQL.Parser.expr()]]}
          | {:select, ExSQL.Parser.statement()}
          | :default_values

  @type t :: %__MODULE__{
          table: String.t(),
          schema: String.t() | nil,
          target_qualified: boolean(),
          columns: [String.t()] | nil,
          source: source(),
          or_conflict: nil | :replace | :ignore | :abort | :fail | :rollback,
          upsert: [term()],
          returning: list()
        }
end