Skip to main content

lib/ex_sql/ast/compound.ex

defmodule ExSQL.AST.Compound do
  @moduledoc """
  A compound `SELECT`: two queries joined by `UNION [ALL]`, `INTERSECT`, or
  `EXCEPT`.

  Compounds nest left-associatively, so `a UNION b UNION c` parses as
  `(a UNION b) UNION c` with `left` itself a `Compound`. The `ORDER BY` and
  `LIMIT` clauses apply to the whole compound — SQLite rejects them on any
  component but the last, and so does the parser.
  """

  alias ExSQL.AST.Select

  defstruct op: :union, left: nil, right: nil, order_by: [], limit: nil, offset: nil

  @type op :: :union | :union_all | :intersect | :except

  @type t :: %__MODULE__{
          op: op(),
          left: Select.t() | t(),
          right: Select.t(),
          order_by: [{Select.expr(), :asc | :desc}],
          limit: Select.expr() | nil,
          offset: Select.expr() | nil
        }
end