From 248f137ec12df5b039d662ef667d3bc8b9cde242 Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Thu, 30 Mar 2017 16:08:27 -0600 Subject: [PATCH 01/43] start update --- lib/sonata/manipulation.ex | 41 +++++++++++++++++++++++++++++++------- lib/sonata/postgres.ex | 6 ++++++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/lib/sonata/manipulation.ex b/lib/sonata/manipulation.ex index ed81287..2265124 100644 --- a/lib/sonata/manipulation.ex +++ b/lib/sonata/manipulation.ex @@ -6,18 +6,45 @@ defmodule Sonata.Manipulation do end defmodule Update do - defstruct [table: nil] + defstruct [table: nil, + table_alias: nil, + sets: [], + where: nil, + returning: []] end defmodule Builder do - def insert_into(table, kvs) when is_map(kvs) do - # TODO figure out kvs - %Sonata.Manipulation.Insertion{table: table} + alias Sonata.Manipulation.{Insertion,Update} + + def insert_into(table) do + %Insertion{table: table} + end + + def insert_into(table, kvs) do + insert_into(table) + end + + def update(table) do + %Update{table: table} + end + + def update(table, table_alias \\ nil) do + %Update{table: table, table_alias: table_alias} + end + + def set(insertion, kvs) when is_map(kvs) do + set(insertion, :maps.to_list(kvs)) + end + def set(insertion = %Update{sets: sets}, kvs) when is_list(kvs) do + %{insertion | sets: sets ++ kvs} + end + + def set(insertion = %Update{sets: sets}, field, value) do + %{insertion | sets: sets ++ [{field, value}]} end - def update(table, kvs) when is_map(kvs) do - # TODO figure out kvs - %Sonata.Manipulation.Update{table: table} + def returning(insertion = %{returning: returning}, fields) do + %{insertion | returning: returning ++ fields} end end end diff --git a/lib/sonata/postgres.ex b/lib/sonata/postgres.ex index 2784df2..19d36c5 100644 --- a/lib/sonata/postgres.ex +++ b/lib/sonata/postgres.ex @@ -406,6 +406,12 @@ defimpl Sonata.Postgres, for: Sonata.Definition.Column do end end +defimpl Sonata.Postgres, for: Sonata.Manipulation.Update do + def to_sql(%{}, opts, idx) do + {[], [], idx} + end +end + defimpl Sonata.Postgres, for: Sonata.Misc.Call do def to_sql(%{function: fun, arguments: arguments}, opts, idx) do {arguments, {params, idx}} = Enum.map_reduce(arguments, {[], idx}, fn(arg, {params, idx}) -> From 3d81a9d8a0efdddd7392d8b944f12ed850018cd2 Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Fri, 31 Mar 2017 14:00:47 -0600 Subject: [PATCH 02/43] continue update --- lib/sonata/manipulation.ex | 13 ++++++- lib/sonata/postgres.ex | 80 +++++++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 3 deletions(-) diff --git a/lib/sonata/manipulation.ex b/lib/sonata/manipulation.ex index 2265124..48b6885 100644 --- a/lib/sonata/manipulation.ex +++ b/lib/sonata/manipulation.ex @@ -9,7 +9,7 @@ defmodule Sonata.Manipulation do defstruct [table: nil, table_alias: nil, sets: [], - where: nil, + where: [], returning: []] end @@ -43,6 +43,17 @@ defmodule Sonata.Manipulation do %{insertion | sets: sets ++ [{field, value}]} end + def where(insertion, kvs) when is_map(kvs) do + where(insertion, :maps.to_list(kvs)) + end + def where(insertion = %Update{where: where}, kvs) when is_list(kvs) do + %{insertion | where: where ++ kvs} + end + + def where(insertion = %Update{where: where}, field, value) do + %{insertion | where: where ++ [{field, value}]} + end + def returning(insertion = %{returning: returning}, fields) do %{insertion | returning: returning ++ fields} end diff --git a/lib/sonata/postgres.ex b/lib/sonata/postgres.ex index 19d36c5..c20dc13 100644 --- a/lib/sonata/postgres.ex +++ b/lib/sonata/postgres.ex @@ -407,8 +407,84 @@ defimpl Sonata.Postgres, for: Sonata.Definition.Column do end defimpl Sonata.Postgres, for: Sonata.Manipulation.Update do - def to_sql(%{}, opts, idx) do - {[], [], idx} + alias Sonata.Postgres, as: PG + import PG.Utils + + def to_sql(update, opts, idx) do + {table, table_params, idx} = table(update.table, opts, idx) + {table_alias, table_alias_params, idx} = table_alias(update.table_alias, opts, idx) + {sets, sets_params, idx} = sets(update.sets, opts, idx) + {where, where_params, idx} = where(update.where, opts, idx) + {returning, returning_params, idx} = returning(update.returning, opts, idx) + + { + join([ + "UPDATE", + table, + table_alias, + sets, + where, + returning + ], " "), + + Stream.concat([ + table_params, + table_alias_params, + sets_params, + where_params, + returning_params + ]), + + idx + } + end + + defp table(table, _, idx) when table in [nil, false, ""] do + {nil, [], idx} + end + defp table(table, opts, idx) when is_binary(table) do + {escape_keyword(table), opts, idx} + end + + defp table_alias(nil, _, idx) do + {nil, [], idx} + end + defp table_alias(alias, opts, idx) do + {[" AS ", escape_keyword(alias)], opts, idx} + end + + defp sets(sets, _, idx) when sets in [nil, false, "", []] do + {nil, [], idx} + end + defp sets(sets, opts, idx) do + {sets, {params, idx}} = Enum.map_reduce(sets, {[], idx}, fn(set, {params, idx}) -> + {set, p, idx} = Sonata.Postgres.to_sql(set, opts, idx) + {set, {Stream.concat(params, p), idx}} + end) + {["SET ", Sonata.Postgres.Utils.join(sets, ", ")], params, idx} + end + + defp where(nil, _, idx) do + {nil, [], idx} + end + defp where(expr, opts, idx) do + {where, params, idx} = PG.to_sql(expr, opts, idx) + {["WHERE ", where], params, idx} + end + + defp returning(returning, _, idx) when returning in [nil, false, "", []] do + {nil, [], idx} + end + defp returning(returning, opts, idx) do + {returning, {params, idx}} = Enum.map_reduce(returning, {[], idx}, fn + ({column, alias}, {params, idx}) -> + {column, p, idx} = Sonata.Postgres.to_sql(column, opts, idx) + {[column, " AS ", alias], {Stream.concat(params, p), idx}} + (returning, {params, idx}) -> + {returning, p, idx} = Sonata.Postgres.to_sql(returning, opts, idx) + {returning, {Stream.concat(params, p), idx}} + end) + {["RETURNING ", returning], params, idx} end end From f18a6d01312933649a4c0ad7b901a214d0bc03bd Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Fri, 31 Mar 2017 15:10:59 -0600 Subject: [PATCH 03/43] more update --- lib/sonata/manipulation.ex | 33 ++++++++++++++------------------- lib/sonata/postgres.ex | 36 +++++++++++++++++++++++------------- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/lib/sonata/manipulation.ex b/lib/sonata/manipulation.ex index 48b6885..03111ba 100644 --- a/lib/sonata/manipulation.ex +++ b/lib/sonata/manipulation.ex @@ -9,7 +9,7 @@ defmodule Sonata.Manipulation do defstruct [table: nil, table_alias: nil, sets: [], - where: [], + where: nil, returning: []] end @@ -32,26 +32,21 @@ defmodule Sonata.Manipulation do %Update{table: table, table_alias: table_alias} end - def set(insertion, kvs) when is_map(kvs) do - set(insertion, :maps.to_list(kvs)) - end - def set(insertion = %Update{sets: sets}, kvs) when is_list(kvs) do - %{insertion | sets: sets ++ kvs} - end - - def set(insertion = %Update{sets: sets}, field, value) do - %{insertion | sets: sets ++ [{field, value}]} - end - - def where(insertion, kvs) when is_map(kvs) do - where(insertion, :maps.to_list(kvs)) - end - def where(insertion = %Update{where: where}, kvs) when is_list(kvs) do - %{insertion | where: where ++ kvs} + def set(insertion = %Update{sets: sets}, kvs) do + %{insertion | sets: sets ++ Enum.map(kvs, fn + ({fields, value}) when is_list(fields) -> + {Sonata.Expr.column_list(fields), value} + ({fields, value}) when is_tuple(fields) -> + fields + |> :erlang.tuple_to_list() + |> Sonata.Expr.column_list() + ({field, value}) -> + {Sonata.Expr.column(field), value} + end)} end - def where(insertion = %Update{where: where}, field, value) do - %{insertion | where: where ++ [{field, value}]} + def set(insertion, field, value) do + set(insertion, [{field, value}]) end def returning(insertion = %{returning: returning}, fields) do diff --git a/lib/sonata/postgres.ex b/lib/sonata/postgres.ex index c20dc13..2a35ce6 100644 --- a/lib/sonata/postgres.ex +++ b/lib/sonata/postgres.ex @@ -23,9 +23,12 @@ defprotocol Sonata.Postgres do def column(column, _, idx) when is_binary(column) do {escape_keyword(column), [], idx} end + def column(column, _, idx) when is_atom(column) do + {escape_keyword(Atom.to_string(column)), [], idx} + end def column({column, alias}, opts, idx) do {column, params, idx} = column(column, opts, idx) - {[column, " ", escape_keyword(alias)], params, idx} + {[column, " AS ", escape_keyword(alias)], params, idx} end def column(column, opts, idx) do Sonata.Postgres.to_sql(column, opts, idx) @@ -248,6 +251,15 @@ defimpl Sonata.Postgres, for: [Sonata.Combination.Union, Sonata.Combination.Inte end end +defimpl Sonata.Postgres, for: Sonata.Expr.ColumnList do + alias Sonata.Postgres, as: PG + + def to_sql(%{columns: columns}, opts, idx) do + {sql, params, idx} = PG.Utils.columns(columns, opts, idx) + {["(", sql, ")"], params, idx} + end +end + defimpl Sonata.Postgres, for: Sonata.Expr.Operation do alias Sonata.Postgres, as: PG @@ -439,6 +451,10 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Update do } end + def on_row(_, _) do + nil + end + defp table(table, _, idx) when table in [nil, false, ""] do {nil, [], idx} end @@ -457,9 +473,10 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Update do {nil, [], idx} end defp sets(sets, opts, idx) do - {sets, {params, idx}} = Enum.map_reduce(sets, {[], idx}, fn(set, {params, idx}) -> - {set, p, idx} = Sonata.Postgres.to_sql(set, opts, idx) - {set, {Stream.concat(params, p), idx}} + {sets, {params, idx}} = Enum.map_reduce(sets, {[], idx}, fn({field, value}, {params, idx}) -> + {field, p, idx} = Sonata.Postgres.to_sql(field, opts, idx) + {value, p, idx} = Sonata.Postgres.to_sql(value, opts, idx) + {[field, " = (", value, ")"], {Stream.concat(params, p), idx}} end) {["SET ", Sonata.Postgres.Utils.join(sets, ", ")], params, idx} end @@ -476,15 +493,8 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Update do {nil, [], idx} end defp returning(returning, opts, idx) do - {returning, {params, idx}} = Enum.map_reduce(returning, {[], idx}, fn - ({column, alias}, {params, idx}) -> - {column, p, idx} = Sonata.Postgres.to_sql(column, opts, idx) - {[column, " AS ", alias], {Stream.concat(params, p), idx}} - (returning, {params, idx}) -> - {returning, p, idx} = Sonata.Postgres.to_sql(returning, opts, idx) - {returning, {Stream.concat(params, p), idx}} - end) - {["RETURNING ", returning], params, idx} + {sql, params, idx} = PG.Utils.columns(returning, opts, idx) + {["RETURNING ", sql], params, idx} end end From 64a185e59698ba478639e1a2ae46de959c884cc1 Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Sun, 2 Apr 2017 15:06:09 -0600 Subject: [PATCH 04/43] start insert, fix warnings --- lib/sonata/manipulation.ex | 28 ++++++++++++-- lib/sonata/postgres.ex | 77 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 4 deletions(-) diff --git a/lib/sonata/manipulation.ex b/lib/sonata/manipulation.ex index 03111ba..660e309 100644 --- a/lib/sonata/manipulation.ex +++ b/lib/sonata/manipulation.ex @@ -2,7 +2,9 @@ defmodule Sonata.Manipulation do defmodule Insertion do defstruct [table: nil, fields: [], - rows: []] + rows: [], + returning: [], + default_values: nil] end defmodule Update do @@ -20,15 +22,32 @@ defmodule Sonata.Manipulation do %Insertion{table: table} end - def insert_into(table, kvs) do + # TODO: support `kvs` + def insert_into(table, _kvs) do insert_into(table) end + def fields(insertion = %{fields: fields}, columns) do + %{insertion | fields: fields ++ columns} + end + + # TODO: support `INSERT INTO foo (valA, valB) VALUES (SELECT ...)` + def values(insertion = %{rows: rows}, [first | _ ] = values) when is_list(first) do + %{insertion | rows: Enum.into(rows, values)} + end + def values(insertion = %{rows: rows}, values) when is_list(values) do + %{insertion | rows: Enum.into(rows, [values])} + end + + def default_values(insertion = %{default_values: _}) do + %{insertion | default_values: :true} + end + def update(table) do %Update{table: table} end - def update(table, table_alias \\ nil) do + def update(table, table_alias) do %Update{table: table, table_alias: table_alias} end @@ -36,7 +55,7 @@ defmodule Sonata.Manipulation do %{insertion | sets: sets ++ Enum.map(kvs, fn ({fields, value}) when is_list(fields) -> {Sonata.Expr.column_list(fields), value} - ({fields, value}) when is_tuple(fields) -> + ({fields, _value}) when is_tuple(fields) -> fields |> :erlang.tuple_to_list() |> Sonata.Expr.column_list() @@ -49,6 +68,7 @@ defmodule Sonata.Manipulation do set(insertion, [{field, value}]) end + # TODO: support returning alias def returning(insertion = %{returning: returning}, fields) do %{insertion | returning: returning ++ fields} end diff --git a/lib/sonata/postgres.ex b/lib/sonata/postgres.ex index 2a35ce6..3512f18 100644 --- a/lib/sonata/postgres.ex +++ b/lib/sonata/postgres.ex @@ -258,6 +258,10 @@ defimpl Sonata.Postgres, for: Sonata.Expr.ColumnList do {sql, params, idx} = PG.Utils.columns(columns, opts, idx) {["(", sql, ")"], params, idx} end + + def on_row(_, _) do + nil + end end defimpl Sonata.Postgres, for: Sonata.Expr.Operation do @@ -268,6 +272,10 @@ defimpl Sonata.Postgres, for: Sonata.Expr.Operation do {rhs, rhs_params, idx} = PG.to_sql(rhs, opts, idx) {["(", lhs, " ", operator, " ", rhs, ")"], Stream.concat(lhs_params, rhs_params), idx} end + + def on_row(_, _) do + nil + end end defimpl Sonata.Postgres, for: Sonata.Expr.Reference do @@ -418,6 +426,70 @@ defimpl Sonata.Postgres, for: Sonata.Definition.Column do end end +defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do + alias Sonata.Postgres, as: PG + import PG.Utils + + def to_sql(insertion, opts, idx) do + {table, table_params, idx} = table(insertion.table, opts, idx) + {fields, fields_params, idx} = fields(insertion.fields, opts, idx) + {default_values, default_values_params, idx} = default_values(insertion.default_values, opts, idx) + {rows, rows_params, idx} = rows(insertion.rows, opts, idx) + + { + join([ + "INSERT INTO", + table, + fields, + default_values, + rows, + ], " "), + + Stream.concat([ + table_params, + fields_params, + default_values_params, + rows_params, + ]), + + idx + } + end + + defp table(table, _, idx) when table in [nil, false, ""] do + {nil, [], idx} + end + defp table(table, opts, idx) when is_binary(table) do + {escape_keyword(table), opts, idx} + end + + def fields(fields, _, idx) when fields in [nil, false, ""] do + {nil, [], idx} + end + + def default_values(:true, opts, idx) do + {"DEFAULT VALUES", opts, idx} + end + + def rows(rows, _, idx) when rows in [nil, false, ""] do + {nil, [], idx} + end + # TODO + def rows(rows, opts, idx) do + {["VALUES"] ++ rows, opts, idx} + end + + # TODO + # defp on_conflict do + # end + # defp returning do + # end + + def on_row(_, _) do + nil + end +end + defimpl Sonata.Postgres, for: Sonata.Manipulation.Update do alias Sonata.Postgres, as: PG import PG.Utils @@ -489,6 +561,7 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Update do {["WHERE ", where], params, idx} end + # TODO: support returning alias defp returning(returning, _, idx) when returning in [nil, false, "", []] do {nil, [], idx} end @@ -520,6 +593,10 @@ defimpl Sonata.Postgres, for: Sonata.Query.Value do def to_sql(%{value: value, as: as}, _, idx) do {"$#{idx} #{as}", [value], idx + 1} end + + def on_row(_, _) do + nil + end end defimpl Sonata.Postgres, for: Sonata.Expr.Value do From 2ba248cb3827f52e70a6a18dd86a77ffb9ce4f1c Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Wed, 26 Jul 2017 19:01:21 -0600 Subject: [PATCH 05/43] start refactor --- .gitignore | 1 + .tool-versions | 2 + EXTRACT_INFO.md | 21 + _snapshots/Test.Sonata.CreateTable.snapshot | 6 + bin/gen_functions.exs | 27 + bin/gen_operators.exs | 20 + config/config.exs | 9 + lib/sonata.ex | 11 + lib/sonata/alter_table.ex | 8 +- lib/sonata/builder.ex | 5 + lib/sonata/combination.ex | 62 +- lib/sonata/create_table.ex | 33 +- lib/sonata/definition.ex | 98 +- lib/sonata/definition/column.ex | 227 +- lib/sonata/expr.ex | 44 +- lib/sonata/expr/call.ex | 18 + lib/sonata/expr/column_list.ex | 16 + lib/sonata/expr/operator.ex | 17 + lib/sonata/expr/reference.ex | 14 + lib/sonata/expr/unary_operator.ex | 3 + lib/sonata/expr/value.ex | 9 + lib/sonata/function.ex | 9234 +++++++++++++++++++ lib/sonata/keyword.ex | 35 + lib/sonata/manipulation.ex | 106 +- lib/sonata/manipulation/insertion.ex | 71 + lib/sonata/manipulation/update.ex | 88 + lib/sonata/misc.ex | 15 - lib/sonata/operator.ex | 381 + lib/sonata/order_by.ex | 44 +- lib/sonata/postgres.ex | 587 -- lib/sonata/postgres/utils.ex | 56 + lib/sonata/query.ex | 327 +- lib/sonata/query/value.ex | 16 + mix.exs | 17 +- mix.lock | 11 + test/create_table_test.exs | 48 + test/definition_test.exs | 66 - test/manipulation_test.exs | 22 - test/query_test.exs | 16 - test/sonata_test.exs | 72 - test/test_helper.exs | 120 + 41 files changed, 10890 insertions(+), 1093 deletions(-) create mode 100644 .tool-versions create mode 100644 EXTRACT_INFO.md create mode 100644 _snapshots/Test.Sonata.CreateTable.snapshot create mode 100644 bin/gen_functions.exs create mode 100644 bin/gen_operators.exs create mode 100644 config/config.exs create mode 100644 lib/sonata/builder.ex create mode 100644 lib/sonata/expr/call.ex create mode 100644 lib/sonata/expr/column_list.ex create mode 100644 lib/sonata/expr/operator.ex create mode 100644 lib/sonata/expr/reference.ex create mode 100644 lib/sonata/expr/unary_operator.ex create mode 100644 lib/sonata/expr/value.ex create mode 100644 lib/sonata/function.ex create mode 100644 lib/sonata/keyword.ex create mode 100644 lib/sonata/manipulation/insertion.ex create mode 100644 lib/sonata/manipulation/update.ex delete mode 100644 lib/sonata/misc.ex create mode 100644 lib/sonata/operator.ex create mode 100644 lib/sonata/postgres/utils.ex create mode 100644 lib/sonata/query/value.ex create mode 100644 mix.lock create mode 100644 test/create_table_test.exs delete mode 100644 test/definition_test.exs delete mode 100644 test/manipulation_test.exs delete mode 100644 test/query_test.exs delete mode 100644 test/sonata_test.exs diff --git a/.gitignore b/.gitignore index 755b605..a391a60 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /deps erl_crash.dump *.ez +/*.csv diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..7bca3e6 --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +erlang 20.0 +elixir 1.5.0-rc.0 diff --git a/EXTRACT_INFO.md b/EXTRACT_INFO.md new file mode 100644 index 0000000..948d418 --- /dev/null +++ b/EXTRACT_INFO.md @@ -0,0 +1,21 @@ +# Extract all of the operators + +```sql +SELECT DISTINCT + p.oprname as "name" +FROM pg_catalog.pg_operator p +``` + +# Extract all of the functions + +```sql +SELECT DISTINCT + p.proname as "name", + p.pronargs as "arity", + d.description +FROM pg_catalog.pg_proc p +JOIN pg_catalog.pg_description d on p.oid = d.objoid +WHERE pg_catalog.pg_function_is_visible(p.oid) + AND p.prorettype != 'pg_catalog.trigger'::pg_catalog.regtype +ORDER BY 1 +``` diff --git a/_snapshots/Test.Sonata.CreateTable.snapshot b/_snapshots/Test.Sonata.CreateTable.snapshot new file mode 100644 index 0000000..e3af21e --- /dev/null +++ b/_snapshots/Test.Sonata.CreateTable.snapshot @@ -0,0 +1,6 @@ +%{"test my_first_table": [%{"column_name" => "first_column", + "data_type" => "text"}, + %{"column_name" => "second_column", "data_type" => "integer"}], + "test products": [%{"column_name" => "product_no", "data_type" => "integer"}, + %{"column_name" => "name", "data_type" => "text"}, + %{"column_name" => "price", "data_type" => "numeric"}]} \ No newline at end of file diff --git a/bin/gen_functions.exs b/bin/gen_functions.exs new file mode 100644 index 0000000..00dfba8 --- /dev/null +++ b/bin/gen_functions.exs @@ -0,0 +1,27 @@ +functions = "functions.csv" + |> File.stream!() + |> CSV.decode!(headers: true) + +str = quote do + defmodule Sonata.Function do + unquote_splicing(Enum.flat_map(functions, fn(%{ + "name" => name, + "arity" => arity, + "description" => description, + }) -> + arity = String.to_integer(arity) + fun = String.to_atom(name) + args = Macro.generate_arguments(arity, nil) + quote do + @doc unquote(description) + def unquote(fun)(unquote_splicing(args)) do + %Sonata.Expr.Call{name: unquote(name), arguments: unquote(args)} + end + end + |> elem(2) + end)) + end +end +|> Macro.to_string() + +File.write!("lib/sonata/function.ex", str) diff --git a/bin/gen_operators.exs b/bin/gen_operators.exs new file mode 100644 index 0000000..6325b39 --- /dev/null +++ b/bin/gen_operators.exs @@ -0,0 +1,20 @@ +operators = "operators.csv" + |> File.stream!() + |> CSV.decode!(headers: true) + |> Stream.map(fn(%{ + "name" => name, + }) -> + fun = String.to_atom(name) + """ + def unquote(#{inspect(fun)})(lhs, rhs) do + %Sonata.Expr.Operator{operator: #{inspect(name)}, lhs: lhs, rhs: rhs} + end + """ + end) + +str = """ +defmodule Sonata.Operator do +#{Enum.join(operators, "\n")}end +""" + +File.write!("lib/sonata/operator.ex", str) diff --git a/config/config.exs b/config/config.exs new file mode 100644 index 0000000..064ba23 --- /dev/null +++ b/config/config.exs @@ -0,0 +1,9 @@ +use Mix.Config + +if Mix.env === :test do + config :sonata, Test.Sonata.Repo, + adapter: Ecto.Adapters.Postgres, + pool: Ecto.Adapters.SQL.Sandbox, + url: {:system, "DATABASE_URL"}, + loggers: [] +end diff --git a/lib/sonata.ex b/lib/sonata.ex index 4e1bdaa..e58f1c3 100644 --- a/lib/sonata.ex +++ b/lib/sonata.ex @@ -1,3 +1,14 @@ defmodule Sonata do + defmacro __using__(_) do + quote do + import Sonata.{CreateTable,Definition.Column,Function} + end + end + def to_sql(statement, opts \\ %{}) do + opts = Enum.into(opts, %{}) + {sql, params, _idx} = Sonata.Postgres.to_sql(statement, opts, 1) + on_row = Sonata.Postgres.on_row(statement, opts) + {sql, Enum.to_list(params), on_row} + end end diff --git a/lib/sonata/alter_table.ex b/lib/sonata/alter_table.ex index 9ba851b..7ff9eac 100644 --- a/lib/sonata/alter_table.ex +++ b/lib/sonata/alter_table.ex @@ -1,11 +1,7 @@ defmodule Sonata.AlterTable do use Sonata.Definition - defmodule Builder do - use Sonata.Definition.Builder - - def alter_table(table) do - %Sonata.AlterTable{table: table} - end + def alter_table(table) do + %Sonata.AlterTable{table: table} end end diff --git a/lib/sonata/builder.ex b/lib/sonata/builder.ex new file mode 100644 index 0000000..fa0448e --- /dev/null +++ b/lib/sonata/builder.ex @@ -0,0 +1,5 @@ +defmodule Sonata.Builder do + defprotocol Constraint do + def constraint(struct, name, constraint) + end +end diff --git a/lib/sonata/combination.ex b/lib/sonata/combination.ex index d11eca9..b49fd0d 100644 --- a/lib/sonata/combination.ex +++ b/lib/sonata/combination.ex @@ -11,26 +11,48 @@ defmodule Sonata.Combination do defstruct [:rhs, :lhs, :all] end - defmodule Builder do - structs = [ - union: Sonata.Combination.Union, - intersect: Sonata.Combination.Intersect, - except: Sonata.Combination.Except - ] - - for {call, struct} <- structs do - def unquote(call)(lhs, rhs) when is_function(rhs) do - unquote(call)(lhs, rhs.()) - end - def unquote(call)(lhs, rhs) do - %unquote(struct){lhs: lhs, rhs: rhs} - end - def unquote(:"#{call}_all")(lhs, rhs) when is_function(rhs) do - unquote(:"#{call}_all")(lhs, rhs.()) - end - def unquote(:"#{call}_all")(lhs, rhs) do - %unquote(struct){lhs: lhs, rhs: rhs, all: true} - end + structs = [ + union: __MODULE__.Union, + intersect: __MODULE__.Intersect, + except: __MODULE__.Except + ] + + for {call, struct} <- structs do + def unquote(call)(lhs, rhs) when is_function(rhs) do + unquote(call)(lhs, rhs.()) + end + def unquote(call)(lhs, rhs) do + %unquote(struct){lhs: lhs, rhs: rhs} + end + def unquote(:"#{call}_all")(lhs, rhs) when is_function(rhs) do + unquote(:"#{call}_all")(lhs, rhs.()) + end + def unquote(:"#{call}_all")(lhs, rhs) do + %unquote(struct){lhs: lhs, rhs: rhs, all: true} end end end + +defimpl Sonata.Postgres, for: [Sonata.Combination.Union, Sonata.Combination.Intersect, Sonata.Combination.Except] do + alias Sonata.Postgres, as: PG + + @command [" ", (@for |> Module.split() |> List.last() |> String.upcase), " "] + + def to_sql(%{lhs: lhs, rhs: rhs, all: all}, opts, idx) do + {lhs, lhs_params, idx} = PG.to_sql(lhs, opts, idx) + {rhs, rhs_params, idx} = PG.to_sql(rhs, opts, idx) + {["(", lhs, @command, all(all), rhs, ")"], Stream.concat(lhs_params, rhs_params), idx} + end + + # TODO look at the rhs? + def on_row(_, _) do + nil + end + + defp all(true) do + " ALL" + end + defp all(_) do + "" + end +end diff --git a/lib/sonata/create_table.ex b/lib/sonata/create_table.ex index 90c39e5..90939b5 100644 --- a/lib/sonata/create_table.ex +++ b/lib/sonata/create_table.ex @@ -1,16 +1,31 @@ defmodule Sonata.CreateTable do use Sonata.Definition - defmodule Builder do - use Sonata.Definition.Builder + def create_table(table) do + %Sonata.CreateTable{table: table} + end + + def create_table(table, columns) do + create_table(table) + |> add_column(columns) + end +end - def create_table(table) do - %Sonata.CreateTable{table: table} - end +defimpl Sonata.Postgres, for: Sonata.CreateTable do + def to_sql(%{add_columns: columns, table: table}, opts, idx) do + ## TODO escape the table + sql = ["CREATE TABLE ", table, " ("] + {columns, {params, idx}} = Enum.map_reduce(columns, {[], idx}, fn(column, {acc_params, idx}) -> + {sql, params, idx} = Sonata.Postgres.to_sql(column, opts, idx) + {sql, {Stream.concat(acc_params, params), idx}} + end) + + ## TODO handle the other options + + {[sql, Sonata.Postgres.Utils.join(columns, ", "), ");"], params, idx} + end - def create_table(table, columns) do - create_table(table) - |> add_column(columns) - end + def on_row(_, _) do + nil end end diff --git a/lib/sonata/definition.ex b/lib/sonata/definition.ex index b8d11ae..e6ed9ab 100644 --- a/lib/sonata/definition.ex +++ b/lib/sonata/definition.ex @@ -8,44 +8,78 @@ defmodule Sonata.Definition do references: [], primary_key: nil, constraints: [], - unique: []] - end - end + unique: [], + if_not_exists: nil, + temporary: nil, + unlogged: nil, + inherits: [], + tablespace: nil, + on_commit: nil] - defmodule Builder do - defmacro __using__(_) do - quote do - def add_column(%{add_columns: columns} = d, c) when is_list(c) do - %{d | add_columns: columns ++ c} - end - def add_column(d, c) do - add_column(d, [c]) - end + def add_column(%{add_columns: columns} = d, c) when is_list(c) do + %{d | add_columns: columns ++ c} + end + def add_column(d, c) do + add_column(d, [c]) + end - def drop_column(%{drop_columns: columns} = d, c) when is_list(c) do - %{d | drop_columns: columns ++ c} - end - def drop_column(d, c) do - drop_column(d, [c]) - end + def add_column(d, name, type) do + col = Sonata.Definition.Column.column(name, type) + add_column(d, [col]) + end - def constraint(%{constraints: constraints} = d, name, constraint) do - %{d | constraints: constraints ++ [{name, constraint}]} - end + def drop_column(%{drop_columns: columns} = d, c) when is_list(c) do + %{d | drop_columns: columns ++ c} + end + def drop_column(d, c) do + drop_column(d, [c]) + end - def unique(%{unique: unique} = d, u) do - %{d | unique: unique ++ [u]} - end + def unique(%{unique: unique} = d, u) do + %{d | unique: unique ++ [u]} + end - def primary_key(d, key) do - %{d | primary_key: key} - end + def primary_key(d, key) do + %{d | primary_key: key} + end - def references(%{references: references} = d, r) when is_list(r) do - %{d | references: references ++ r} - end - def references(d, r) do - references(d, [r]) + def references(%{references: references} = d, r) when is_list(r) do + %{d | references: references ++ r} + end + def references(d, r) do + references(d, [r]) + end + + def if_not_exists(d) do + %{d | if_not_exists: true} + end + + def temporary(d) do + %{d | temporary: true} + end + + def unlogged(d) do + %{d | unlogged: true} + end + + def inherits(%{inherits: inherits} = d, tables) when is_list(tables) do + %{d | inherits: inherits ++ tables} + end + def inherits(d, table) do + inherits(d, [table]) + end + + def tablespace(d, name) do + %{d | tablespace: name} + end + + def on_commit(d, type) when type in [:preserve_rows, :delete_rows, :drop] do + %{d | on_commit: type} + end + + defimpl Sonata.Builder.Constraint do + def constraint(%{constraints: constraints} = d, name, constraint) do + %{d | constraints: constraints ++ [{name, constraint}]} end end end diff --git a/lib/sonata/definition/column.ex b/lib/sonata/definition/column.ex index 40fbb3f..6835026 100644 --- a/lib/sonata/definition/column.ex +++ b/lib/sonata/definition/column.ex @@ -7,35 +7,216 @@ defmodule Sonata.Definition.Column do constraint: nil, unique: nil, default: nil, - not_null: nil] + null: true, + collation: nil, + match: nil, + on_delete: nil, + on_update: nil, + deferrable: false, + initially: nil,] - defmodule Builder do - def column(name, type) do - %Sonata.Definition.Column{name: name, type: type} - end + def column(name, type) do + %Sonata.Definition.Column{name: name, type: type} + end + + def check(column, check) do + %{column | check: {:inherit, check}} + end + + def check(column, check, :no_inherit) do + %{column | check: {:no_inherit, check}} + end + + def references(column, table) do + %{column | reference: table} + end + + def primary_key(column) do + %{column | primary_key: true} + end + + def constraint(column, name, expr) do + %{column | constraint: {name, expr}} + end + + def unique(column) do + %{column | unique: true} + end + + def null(column) do + %{column | null: true} + end + + def not_null(column) do + %{column | null: false} + end + + def default(column, default) do + %{column | default: default} + end + + def collate(column, collation) do + %{column | collation: collation} + end + + # TODO + def like(column, _source_table, _opts) do + column + end + + def match_full(column) do + %{column | match: :full} + end + + def match_partial(column) do + %{column | match: :partial} + end - def check(column, check) do - %{column | check: check} - end + def match_simple(column) do + %{column | match: :simple} + end - def reference(column, reference) do - %{column | reference: reference} - end + def on_delete(column, expr) do + %{column | on_delete: expr} + end - def primary_key(column) do - %{column | primary_key: true} - end + def on_update(column, expr) do + %{column | on_update: expr} + end - def constraint(column, name, expr) do - %{column | constraint: {name, expr}} - end + def deferrable(column) do + %{column | deferrable: true} + end - def unique(column) do - %{column | unique: true} - end + def not_deferrable(column) do + %{column | deferrable: false} + end - def not_null(column) do - %{column | not_null: true} - end + def initially_deferred(column) do + %{column | initially: :deferred} + end + + def initially_immediate(column) do + %{column | initially: :immediate} + end +end + +defimpl Sonata.Postgres, for: Sonata.Definition.Column do + alias Sonata.Postgres, as: PG + import PG.Utils + + def to_sql(column, opts, idx) do + {name, name_params, idx} = name(column.name, opts, idx) + {type, type_params, idx} = type(column.type, opts, idx) + {check, check_params, idx} = check(column.check, opts, idx) + {reference, reference_params, idx} = reference(column.reference, opts, idx) + {primary_key, primary_key_params, idx} = primary_key(column.primary_key, opts, idx) + {constraint, constraint_params, idx} = constraint(column.constraint, opts, idx) + {unique, unique_params, idx} = unique(column.unique, opts, idx) + {default, default_params, idx} = default(column.default, opts, idx) + {null, null_params, idx} = null(column.null, opts, idx) + + { + join([ + name, + type, + check, + reference, + primary_key, + constraint, + unique, + default, + null + ], " "), + + Stream.concat([ + name_params, + type_params, + check_params, + reference_params, + primary_key_params, + constraint_params, + unique_params, + default_params, + null_params + ]), + + idx + } + end + + def on_row(_, _) do + nil + end + + defp name(nil, _, idx) do + {nil, [], idx} + end + defp name(name, _, idx) do + {to_string(name), [], idx} + end + + defp type(nil, _, idx) do + {nil, [], idx} + end + defp type(type, _, idx) do + {to_string(type), [], idx} + end + + defp check(nil, _, idx) do + {nil, [], idx} + end + defp check(check, opts, idx) do + {check, params, idx} = PG.to_sql(check, opts, idx) + {["CHECK ", check], params, idx} + end + + defp reference(nil, _, idx) do + {nil, [], idx} + end + defp reference({column, table}, _, idx) do + {["REFERENCES ", to_string(table), " (", to_string(column), ")"], [], idx} + end + defp reference(table, _, idx) when is_binary(table) or is_atom(table) do + {["REFERENCES ", to_string(table)], [], idx} + end + + defp primary_key(true, _, idx) do + {"PRIMARY KEY", [], idx} + end + defp primary_key(_, _, idx) do + {nil, [], idx} + end + + defp constraint(nil, _, idx) do + {nil, [], idx} + end + defp constraint(constraint, opts, idx) do + {constraint, params, idx} = PG.to_sql(constraint, opts, idx) + {["CONSTRAINT ", constraint], params, idx} + end + + defp unique(true, _, idx) do + {"UNIQUE", [], idx} + end + defp unique(_, _, idx) do + {nil, [], idx} + end + + defp null(false, _, idx) do + {"NOT NULL", [], idx} + end + defp null(_, _, idx) do + {nil, [], idx} + end + + defp default(nil, _, idx) do + {nil, [], idx} + end + defp default(default, opts, idx) do + {default, params, idx} = PG.to_sql(default, opts, idx) + {["DEFAULT ", default], params, idx} + # TODO wtf postgrex? + # {["DEFAULT ", inspect(default)], [], idx} end end diff --git a/lib/sonata/expr.ex b/lib/sonata/expr.ex index a91e9fc..a11bdf3 100644 --- a/lib/sonata/expr.ex +++ b/lib/sonata/expr.ex @@ -1,49 +1,25 @@ defmodule Sonata.Expr do - defmodule Operation do - defstruct [:operator, :rhs, :lhs] + def call(name) do + %__MODULE__.Call{name: name} end - defmodule Reference do - defstruct [:name] + def call(name, arguments) do + %__MODULE__.Call{name: name, arguments: arguments} end - defmodule Value do - defstruct [:value] - end - - def unquote(:=)(lhs, rhs) do - %Operation{operator: "=", lhs: lhs, rhs: rhs} - end - - def unquote(:>)(lhs, rhs) do - %Operation{operator: ">", lhs: lhs, rhs: rhs} - end - - def unquote(:<)(lhs, rhs) do - %Operation{operator: "<", lhs: lhs, rhs: rhs} - end - - def unquote(:>=)(lhs, rhs) do - %Operation{operator: ">=", lhs: lhs, rhs: rhs} - end - - def unquote(:<=)(lhs, rhs) do - %Operation{operator: "<=", lhs: lhs, rhs: rhs} - end - - def unquote(:and)(lhs, rhs) do - %Operation{operator: "AND", lhs: lhs, rhs: rhs} + def column(name) do + %__MODULE__.Reference{name: name} end - def column(name) do - %Reference{name: name} + def column_list(columns) do + %__MODULE__.ColumnList{columns: columns} end def table(name) do - %Reference{name: name} + %__MODULE__.Reference{name: name} end def value(value) do - %Value{value: value} + %__MODULE__.Value{value: value} end end diff --git a/lib/sonata/expr/call.ex b/lib/sonata/expr/call.ex new file mode 100644 index 0000000..79ddd2b --- /dev/null +++ b/lib/sonata/expr/call.ex @@ -0,0 +1,18 @@ +defmodule Sonata.Expr.Call do + defstruct [:name, :arguments] +end + +defimpl Sonata.Postgres, for: Sonata.Expr.Call do + def to_sql(%{name: fun, arguments: arguments}, opts, idx) do + {arguments, {params, idx}} = Enum.map_reduce(arguments, {[], idx}, fn(arg, {params, idx}) -> + {arg, p, idx} = Sonata.Postgres.to_sql(arg, opts, idx) + {arg, {Stream.concat(params, p), idx}} + end) + + {[to_string(fun), "(", Sonata.Postgres.Utils.join(arguments, ", "), ")"], params, idx} + end + + def on_row(_, _) do + nil + end +end diff --git a/lib/sonata/expr/column_list.ex b/lib/sonata/expr/column_list.ex new file mode 100644 index 0000000..93dadc6 --- /dev/null +++ b/lib/sonata/expr/column_list.ex @@ -0,0 +1,16 @@ +defmodule Sonata.Expr.ColumnList do + defstruct columns: [] +end + +defimpl Sonata.Postgres, for: Sonata.Expr.ColumnList do + alias Sonata.Postgres, as: PG + + def to_sql(%{columns: columns}, opts, idx) do + {sql, params, idx} = PG.Utils.columns(columns, opts, idx) + {["(", sql, ")"], params, idx} + end + + def on_row(_, _) do + nil + end +end diff --git a/lib/sonata/expr/operator.ex b/lib/sonata/expr/operator.ex new file mode 100644 index 0000000..c82ce0e --- /dev/null +++ b/lib/sonata/expr/operator.ex @@ -0,0 +1,17 @@ +defmodule Sonata.Expr.Operator do + defstruct [:operator, :rhs, :lhs] +end + +defimpl Sonata.Postgres, for: Sonata.Expr.Operator do + alias Sonata.Postgres, as: PG + + def to_sql(%{operator: operator, rhs: rhs, lhs: lhs}, opts, idx) do + {lhs, lhs_params, idx} = PG.to_sql(lhs, opts, idx) + {rhs, rhs_params, idx} = PG.to_sql(rhs, opts, idx) + {["(", lhs, " ", operator, " ", rhs, ")"], Stream.concat(lhs_params, rhs_params), idx} + end + + def on_row(_, _) do + nil + end +end diff --git a/lib/sonata/expr/reference.ex b/lib/sonata/expr/reference.ex new file mode 100644 index 0000000..c9cb705 --- /dev/null +++ b/lib/sonata/expr/reference.ex @@ -0,0 +1,14 @@ +defmodule Sonata.Expr.Reference do + defstruct [:name] +end + +defimpl Sonata.Postgres, for: Sonata.Expr.Reference do + def to_sql(%{name: name}, _, idx) do + # TODO escape the reference name + {to_string(name), [], idx} + end + + def on_row(_, _) do + nil + end +end diff --git a/lib/sonata/expr/unary_operator.ex b/lib/sonata/expr/unary_operator.ex new file mode 100644 index 0000000..d3dfe98 --- /dev/null +++ b/lib/sonata/expr/unary_operator.ex @@ -0,0 +1,3 @@ +defmodule Sonata.Expr.UnaryOperator do + defstruct [:operator, :rhs] +end diff --git a/lib/sonata/expr/value.ex b/lib/sonata/expr/value.ex new file mode 100644 index 0000000..ef94308 --- /dev/null +++ b/lib/sonata/expr/value.ex @@ -0,0 +1,9 @@ +defmodule Sonata.Expr.Value do + defstruct [:value] +end + +defimpl Sonata.Postgres, for: Sonata.Expr.Value do + def to_sql(%{value: value}, _, idx) do + {"$#{idx}", [value], idx + 1} + end +end diff --git a/lib/sonata/function.ex b/lib/sonata/function.ex new file mode 100644 index 0000000..71b5bdb --- /dev/null +++ b/lib/sonata/function.ex @@ -0,0 +1,9234 @@ +defmodule(Sonata.Function) do + @doc("abbreviated display of inet value") + def(abbrev(var1)) do + %Sonata.Expr.Call{name: "abbrev", arguments: [var1]} + end + @doc("absolute value") + def(abs(var1)) do + %Sonata.Expr.Call{name: "abs", arguments: [var1]} + end + @doc("convert timestamp to abstime") + def(abstime(var1)) do + %Sonata.Expr.Call{name: "abstime", arguments: [var1]} + end + @doc("implementation of = operator") + def(abstimeeq(var1, var2)) do + %Sonata.Expr.Call{name: "abstimeeq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(abstimege(var1, var2)) do + %Sonata.Expr.Call{name: "abstimege", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(abstimegt(var1, var2)) do + %Sonata.Expr.Call{name: "abstimegt", arguments: [var1, var2]} + end + @doc("I/O") + def(abstimein(var1)) do + %Sonata.Expr.Call{name: "abstimein", arguments: [var1]} + end + @doc("implementation of <= operator") + def(abstimele(var1, var2)) do + %Sonata.Expr.Call{name: "abstimele", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(abstimelt(var1, var2)) do + %Sonata.Expr.Call{name: "abstimelt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(abstimene(var1, var2)) do + %Sonata.Expr.Call{name: "abstimene", arguments: [var1, var2]} + end + @doc("I/O") + def(abstimeout(var1)) do + %Sonata.Expr.Call{name: "abstimeout", arguments: [var1]} + end + @doc("I/O") + def(abstimerecv(var1)) do + %Sonata.Expr.Call{name: "abstimerecv", arguments: [var1]} + end + @doc("I/O") + def(abstimesend(var1)) do + %Sonata.Expr.Call{name: "abstimesend", arguments: [var1]} + end + @doc("contains") + def(aclcontains(var1, var2)) do + %Sonata.Expr.Call{name: "aclcontains", arguments: [var1, var2]} + end + @doc("TODO") + def(acldefault(var1, var2)) do + %Sonata.Expr.Call{name: "acldefault", arguments: [var1, var2]} + end + @doc("convert ACL item array to table, for use by information schema") + def(aclexplode(var1)) do + %Sonata.Expr.Call{name: "aclexplode", arguments: [var1]} + end + @doc("add/update ACL item") + def(aclinsert(var1, var2)) do + %Sonata.Expr.Call{name: "aclinsert", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(aclitemeq(var1, var2)) do + %Sonata.Expr.Call{name: "aclitemeq", arguments: [var1, var2]} + end + @doc("I/O") + def(aclitemin(var1)) do + %Sonata.Expr.Call{name: "aclitemin", arguments: [var1]} + end + @doc("I/O") + def(aclitemout(var1)) do + %Sonata.Expr.Call{name: "aclitemout", arguments: [var1]} + end + @doc("remove ACL item") + def(aclremove(var1, var2)) do + %Sonata.Expr.Call{name: "aclremove", arguments: [var1, var2]} + end + @doc("arccosine") + def(acos(var1)) do + %Sonata.Expr.Call{name: "acos", arguments: [var1]} + end + @doc("date difference preserving months and years") + def(age(var1, var2)) do + %Sonata.Expr.Call{name: "age", arguments: [var1, var2]} + end + @doc("I/O") + def(any_in(var1)) do + %Sonata.Expr.Call{name: "any_in", arguments: [var1]} + end + @doc("I/O") + def(any_out(var1)) do + %Sonata.Expr.Call{name: "any_out", arguments: [var1]} + end + @doc("I/O") + def(anyarray_in(var1)) do + %Sonata.Expr.Call{name: "anyarray_in", arguments: [var1]} + end + @doc("I/O") + def(anyarray_out(var1)) do + %Sonata.Expr.Call{name: "anyarray_out", arguments: [var1]} + end + @doc("I/O") + def(anyarray_recv(var1)) do + %Sonata.Expr.Call{name: "anyarray_recv", arguments: [var1]} + end + @doc("I/O") + def(anyarray_send(var1)) do + %Sonata.Expr.Call{name: "anyarray_send", arguments: [var1]} + end + @doc("I/O") + def(anyelement_in(var1)) do + %Sonata.Expr.Call{name: "anyelement_in", arguments: [var1]} + end + @doc("I/O") + def(anyelement_out(var1)) do + %Sonata.Expr.Call{name: "anyelement_out", arguments: [var1]} + end + @doc("I/O") + def(anyenum_in(var1)) do + %Sonata.Expr.Call{name: "anyenum_in", arguments: [var1]} + end + @doc("I/O") + def(anyenum_out(var1)) do + %Sonata.Expr.Call{name: "anyenum_out", arguments: [var1]} + end + @doc("I/O") + def(anynonarray_in(var1)) do + %Sonata.Expr.Call{name: "anynonarray_in", arguments: [var1]} + end + @doc("I/O") + def(anynonarray_out(var1)) do + %Sonata.Expr.Call{name: "anynonarray_out", arguments: [var1]} + end + @doc("I/O") + def(anyrange_in(var1, var2, var3)) do + %Sonata.Expr.Call{name: "anyrange_in", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(anyrange_out(var1)) do + %Sonata.Expr.Call{name: "anyrange_out", arguments: [var1]} + end + @doc("implementation of || operator") + def(anytextcat(var1, var2)) do + %Sonata.Expr.Call{name: "anytextcat", arguments: [var1, var2]} + end + @doc("area of a closed path") + def(area(var1)) do + %Sonata.Expr.Call{name: "area", arguments: [var1]} + end + @doc("join selectivity for area-comparison operators") + def(areajoinsel(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "areajoinsel", arguments: [var1, var2, var3, var4, var5]} + end + @doc("restriction selectivity for area-comparison operators") + def(areasel(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "areasel", arguments: [var1, var2, var3, var4]} + end + @doc("concatenate aggregate input into an array") + def(array_agg(var1)) do + %Sonata.Expr.Call{name: "array_agg", arguments: [var1]} + end + @doc("aggregate final function") + def(array_agg_array_finalfn(var1, var2)) do + %Sonata.Expr.Call{name: "array_agg_array_finalfn", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(array_agg_array_transfn(var1, var2)) do + %Sonata.Expr.Call{name: "array_agg_array_transfn", arguments: [var1, var2]} + end + @doc("aggregate final function") + def(array_agg_finalfn(var1, var2)) do + %Sonata.Expr.Call{name: "array_agg_finalfn", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(array_agg_transfn(var1, var2)) do + %Sonata.Expr.Call{name: "array_agg_transfn", arguments: [var1, var2]} + end + @doc("append element onto end of array") + def(array_append(var1, var2)) do + %Sonata.Expr.Call{name: "array_append", arguments: [var1, var2]} + end + @doc("implementation of || operator") + def(array_cat(var1, var2)) do + %Sonata.Expr.Call{name: "array_cat", arguments: [var1, var2]} + end + @doc("array dimensions") + def(array_dims(var1)) do + %Sonata.Expr.Call{name: "array_dims", arguments: [var1]} + end + @doc("implementation of = operator") + def(array_eq(var1, var2)) do + %Sonata.Expr.Call{name: "array_eq", arguments: [var1, var2]} + end + @doc("array constructor with value") + def(array_fill(var1, var2, var3)) do + %Sonata.Expr.Call{name: "array_fill", arguments: [var1, var2, var3]} + end + @doc("implementation of >= operator") + def(array_ge(var1, var2)) do + %Sonata.Expr.Call{name: "array_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(array_gt(var1, var2)) do + %Sonata.Expr.Call{name: "array_gt", arguments: [var1, var2]} + end + @doc("I/O") + def(array_in(var1, var2, var3)) do + %Sonata.Expr.Call{name: "array_in", arguments: [var1, var2, var3]} + end + @doc("larger of two") + def(array_larger(var1, var2)) do + %Sonata.Expr.Call{name: "array_larger", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(array_le(var1, var2)) do + %Sonata.Expr.Call{name: "array_le", arguments: [var1, var2]} + end + @doc("array length") + def(array_length(var1, var2)) do + %Sonata.Expr.Call{name: "array_length", arguments: [var1, var2]} + end + @doc("array lower dimension") + def(array_lower(var1, var2)) do + %Sonata.Expr.Call{name: "array_lower", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(array_lt(var1, var2)) do + %Sonata.Expr.Call{name: "array_lt", arguments: [var1, var2]} + end + @doc("number of array dimensions") + def(array_ndims(var1)) do + %Sonata.Expr.Call{name: "array_ndims", arguments: [var1]} + end + @doc("implementation of <> operator") + def(array_ne(var1, var2)) do + %Sonata.Expr.Call{name: "array_ne", arguments: [var1, var2]} + end + @doc("I/O") + def(array_out(var1)) do + %Sonata.Expr.Call{name: "array_out", arguments: [var1]} + end + @doc("returns an offset of value in array with start index") + def(array_position(var1, var2, var3)) do + %Sonata.Expr.Call{name: "array_position", arguments: [var1, var2, var3]} + end + @doc("returns an array of offsets of some value in array") + def(array_positions(var1, var2)) do + %Sonata.Expr.Call{name: "array_positions", arguments: [var1, var2]} + end + @doc("prepend element onto front of array") + def(array_prepend(var1, var2)) do + %Sonata.Expr.Call{name: "array_prepend", arguments: [var1, var2]} + end + @doc("I/O") + def(array_recv(var1, var2, var3)) do + %Sonata.Expr.Call{name: "array_recv", arguments: [var1, var2, var3]} + end + @doc("remove any occurrences of an element from an array") + def(array_remove(var1, var2)) do + %Sonata.Expr.Call{name: "array_remove", arguments: [var1, var2]} + end + @doc("replace any occurrences of an element in an array") + def(array_replace(var1, var2, var3)) do + %Sonata.Expr.Call{name: "array_replace", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(array_send(var1)) do + %Sonata.Expr.Call{name: "array_send", arguments: [var1]} + end + @doc("smaller of two") + def(array_smaller(var1, var2)) do + %Sonata.Expr.Call{name: "array_smaller", arguments: [var1, var2]} + end + @doc("map array to json") + def(array_to_json(var1)) do + %Sonata.Expr.Call{name: "array_to_json", arguments: [var1]} + end + @doc("concatenate array elements, using delimiter, into text") + def(array_to_string(var1, var2)) do + %Sonata.Expr.Call{name: "array_to_string", arguments: [var1, var2]} + end + @doc("array typanalyze") + def(array_typanalyze(var1)) do + %Sonata.Expr.Call{name: "array_typanalyze", arguments: [var1]} + end + @doc("array upper dimension") + def(array_upper(var1, var2)) do + %Sonata.Expr.Call{name: "array_upper", arguments: [var1, var2]} + end + @doc("implementation of <@ operator") + def(arraycontained(var1, var2)) do + %Sonata.Expr.Call{name: "arraycontained", arguments: [var1, var2]} + end + @doc("implementation of @> operator") + def(arraycontains(var1, var2)) do + %Sonata.Expr.Call{name: "arraycontains", arguments: [var1, var2]} + end + @doc("join selectivity for array-containment operators") + def(arraycontjoinsel(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "arraycontjoinsel", arguments: [var1, var2, var3, var4, var5]} + end + @doc("restriction selectivity for array-containment operators") + def(arraycontsel(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "arraycontsel", arguments: [var1, var2, var3, var4]} + end + @doc("implementation of && operator") + def(arrayoverlap(var1, var2)) do + %Sonata.Expr.Call{name: "arrayoverlap", arguments: [var1, var2]} + end + @doc("convert first char to int4") + def(ascii(var1)) do + %Sonata.Expr.Call{name: "ascii", arguments: [var1]} + end + @doc("internal conversion function for SQL_ASCII to MULE_INTERNAL") + def(ascii_to_mic(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "ascii_to_mic", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for SQL_ASCII to UTF8") + def(ascii_to_utf8(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "ascii_to_utf8", arguments: [var1, var2, var3, var4, var5]} + end + @doc("arcsine") + def(asin(var1)) do + %Sonata.Expr.Call{name: "asin", arguments: [var1]} + end + @doc("arctangent") + def(atan(var1)) do + %Sonata.Expr.Call{name: "atan", arguments: [var1]} + end + @doc("arctangent, two arguments") + def(atan2(var1, var2)) do + %Sonata.Expr.Call{name: "atan2", arguments: [var1, var2]} + end + @doc("the average (arithmetic mean) as numeric of all bigint values") + def(avg(var1)) do + %Sonata.Expr.Call{name: "avg", arguments: [var1]} + end + @doc("BERNOULLI tablesample method handler") + def(bernoulli(var1)) do + %Sonata.Expr.Call{name: "bernoulli", arguments: [var1]} + end + @doc("internal conversion function for BIG5 to EUC_TW") + def(big5_to_euc_tw(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "big5_to_euc_tw", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for BIG5 to MULE_INTERNAL") + def(big5_to_mic(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "big5_to_mic", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for BIG5 to UTF8") + def(big5_to_utf8(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "big5_to_utf8", arguments: [var1, var2, var3, var4, var5]} + end + @doc("for use by pg_upgrade") + def(binary_upgrade_create_empty_extension(var1, var2, var3, var4, var5, var6, var7)) do + %Sonata.Expr.Call{name: "binary_upgrade_create_empty_extension", arguments: [var1, var2, var3, var4, var5, var6, var7]} + end + @doc("for use by pg_upgrade") + def(binary_upgrade_set_next_array_pg_type_oid(var1)) do + %Sonata.Expr.Call{name: "binary_upgrade_set_next_array_pg_type_oid", arguments: [var1]} + end + @doc("for use by pg_upgrade") + def(binary_upgrade_set_next_heap_pg_class_oid(var1)) do + %Sonata.Expr.Call{name: "binary_upgrade_set_next_heap_pg_class_oid", arguments: [var1]} + end + @doc("for use by pg_upgrade") + def(binary_upgrade_set_next_index_pg_class_oid(var1)) do + %Sonata.Expr.Call{name: "binary_upgrade_set_next_index_pg_class_oid", arguments: [var1]} + end + @doc("for use by pg_upgrade") + def(binary_upgrade_set_next_pg_authid_oid(var1)) do + %Sonata.Expr.Call{name: "binary_upgrade_set_next_pg_authid_oid", arguments: [var1]} + end + @doc("for use by pg_upgrade") + def(binary_upgrade_set_next_pg_enum_oid(var1)) do + %Sonata.Expr.Call{name: "binary_upgrade_set_next_pg_enum_oid", arguments: [var1]} + end + @doc("for use by pg_upgrade") + def(binary_upgrade_set_next_pg_type_oid(var1)) do + %Sonata.Expr.Call{name: "binary_upgrade_set_next_pg_type_oid", arguments: [var1]} + end + @doc("for use by pg_upgrade") + def(binary_upgrade_set_next_toast_pg_class_oid(var1)) do + %Sonata.Expr.Call{name: "binary_upgrade_set_next_toast_pg_class_oid", arguments: [var1]} + end + @doc("for use by pg_upgrade") + def(binary_upgrade_set_next_toast_pg_type_oid(var1)) do + %Sonata.Expr.Call{name: "binary_upgrade_set_next_toast_pg_type_oid", arguments: [var1]} + end + @doc("convert int4 to bitstring") + def(bit(var1, var2)) do + %Sonata.Expr.Call{name: "bit", arguments: [var1, var2]} + end + @doc("bitwise-and bit aggregate") + def(bit_and(var1)) do + %Sonata.Expr.Call{name: "bit_and", arguments: [var1]} + end + @doc("I/O") + def(bit_in(var1, var2, var3)) do + %Sonata.Expr.Call{name: "bit_in", arguments: [var1, var2, var3]} + end + @doc("length in bits") + def(bit_length(var1)) do + %Sonata.Expr.Call{name: "bit_length", arguments: [var1]} + end + @doc("bitwise-or smallint aggregate") + def(bit_or(var1)) do + %Sonata.Expr.Call{name: "bit_or", arguments: [var1]} + end + @doc("I/O") + def(bit_out(var1)) do + %Sonata.Expr.Call{name: "bit_out", arguments: [var1]} + end + @doc("I/O") + def(bit_recv(var1, var2, var3)) do + %Sonata.Expr.Call{name: "bit_recv", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(bit_send(var1)) do + %Sonata.Expr.Call{name: "bit_send", arguments: [var1]} + end + @doc("implementation of & operator") + def(bitand(var1, var2)) do + %Sonata.Expr.Call{name: "bitand", arguments: [var1, var2]} + end + @doc("implementation of || operator") + def(bitcat(var1, var2)) do + %Sonata.Expr.Call{name: "bitcat", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(bitcmp(var1, var2)) do + %Sonata.Expr.Call{name: "bitcmp", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(biteq(var1, var2)) do + %Sonata.Expr.Call{name: "biteq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(bitge(var1, var2)) do + %Sonata.Expr.Call{name: "bitge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(bitgt(var1, var2)) do + %Sonata.Expr.Call{name: "bitgt", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(bitle(var1, var2)) do + %Sonata.Expr.Call{name: "bitle", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(bitlt(var1, var2)) do + %Sonata.Expr.Call{name: "bitlt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(bitne(var1, var2)) do + %Sonata.Expr.Call{name: "bitne", arguments: [var1, var2]} + end + @doc("implementation of ~ operator") + def(bitnot(var1)) do + %Sonata.Expr.Call{name: "bitnot", arguments: [var1]} + end + @doc("implementation of | operator") + def(bitor(var1, var2)) do + %Sonata.Expr.Call{name: "bitor", arguments: [var1, var2]} + end + @doc("implementation of << operator") + def(bitshiftleft(var1, var2)) do + %Sonata.Expr.Call{name: "bitshiftleft", arguments: [var1, var2]} + end + @doc("implementation of >> operator") + def(bitshiftright(var1, var2)) do + %Sonata.Expr.Call{name: "bitshiftright", arguments: [var1, var2]} + end + @doc("I/O typmod") + def(bittypmodin(var1)) do + %Sonata.Expr.Call{name: "bittypmodin", arguments: [var1]} + end + @doc("I/O typmod") + def(bittypmodout(var1)) do + %Sonata.Expr.Call{name: "bittypmodout", arguments: [var1]} + end + @doc("implementation of # operator") + def(bitxor(var1, var2)) do + %Sonata.Expr.Call{name: "bitxor", arguments: [var1, var2]} + end + @doc("convert int4 to boolean") + def(bool(var1)) do + %Sonata.Expr.Call{name: "bool", arguments: [var1]} + end + @doc("aggregate transition function") + def(bool_accum(var1, var2)) do + %Sonata.Expr.Call{name: "bool_accum", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(bool_accum_inv(var1, var2)) do + %Sonata.Expr.Call{name: "bool_accum_inv", arguments: [var1, var2]} + end + @doc("aggregate final function") + def(bool_alltrue(var1)) do + %Sonata.Expr.Call{name: "bool_alltrue", arguments: [var1]} + end + @doc("boolean-and aggregate") + def(bool_and(var1)) do + %Sonata.Expr.Call{name: "bool_and", arguments: [var1]} + end + @doc("aggregate final function") + def(bool_anytrue(var1)) do + %Sonata.Expr.Call{name: "bool_anytrue", arguments: [var1]} + end + @doc("boolean-or aggregate") + def(bool_or(var1)) do + %Sonata.Expr.Call{name: "bool_or", arguments: [var1]} + end + @doc("aggregate transition function") + def(booland_statefunc(var1, var2)) do + %Sonata.Expr.Call{name: "booland_statefunc", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(booleq(var1, var2)) do + %Sonata.Expr.Call{name: "booleq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(boolge(var1, var2)) do + %Sonata.Expr.Call{name: "boolge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(boolgt(var1, var2)) do + %Sonata.Expr.Call{name: "boolgt", arguments: [var1, var2]} + end + @doc("I/O") + def(boolin(var1)) do + %Sonata.Expr.Call{name: "boolin", arguments: [var1]} + end + @doc("implementation of <= operator") + def(boolle(var1, var2)) do + %Sonata.Expr.Call{name: "boolle", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(boollt(var1, var2)) do + %Sonata.Expr.Call{name: "boollt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(boolne(var1, var2)) do + %Sonata.Expr.Call{name: "boolne", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(boolor_statefunc(var1, var2)) do + %Sonata.Expr.Call{name: "boolor_statefunc", arguments: [var1, var2]} + end + @doc("I/O") + def(boolout(var1)) do + %Sonata.Expr.Call{name: "boolout", arguments: [var1]} + end + @doc("I/O") + def(boolrecv(var1)) do + %Sonata.Expr.Call{name: "boolrecv", arguments: [var1]} + end + @doc("I/O") + def(boolsend(var1)) do + %Sonata.Expr.Call{name: "boolsend", arguments: [var1]} + end + @doc("bounding box of two boxes") + def(bound_box(var1, var2)) do + %Sonata.Expr.Call{name: "bound_box", arguments: [var1, var2]} + end + @doc("convert points to box") + def(box(var1, var2)) do + %Sonata.Expr.Call{name: "box", arguments: [var1, var2]} + end + @doc("implementation of |>> operator") + def(box_above(var1, var2)) do + %Sonata.Expr.Call{name: "box_above", arguments: [var1, var2]} + end + @doc("implementation of >^ operator") + def(box_above_eq(var1, var2)) do + %Sonata.Expr.Call{name: "box_above_eq", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(box_add(var1, var2)) do + %Sonata.Expr.Call{name: "box_add", arguments: [var1, var2]} + end + @doc("implementation of <<| operator") + def(box_below(var1, var2)) do + %Sonata.Expr.Call{name: "box_below", arguments: [var1, var2]} + end + @doc("implementation of <^ operator") + def(box_below_eq(var1, var2)) do + %Sonata.Expr.Call{name: "box_below_eq", arguments: [var1, var2]} + end + @doc("implementation of @@ operator") + def(box_center(var1)) do + %Sonata.Expr.Call{name: "box_center", arguments: [var1]} + end + @doc("implementation of @> operator") + def(box_contain(var1, var2)) do + %Sonata.Expr.Call{name: "box_contain", arguments: [var1, var2]} + end + @doc("implementation of @> operator") + def(box_contain_pt(var1, var2)) do + %Sonata.Expr.Call{name: "box_contain_pt", arguments: [var1, var2]} + end + @doc("implementation of <@ operator") + def(box_contained(var1, var2)) do + %Sonata.Expr.Call{name: "box_contained", arguments: [var1, var2]} + end + @doc("implementation of <-> operator") + def(box_distance(var1, var2)) do + %Sonata.Expr.Call{name: "box_distance", arguments: [var1, var2]} + end + @doc("implementation of / operator") + def(box_div(var1, var2)) do + %Sonata.Expr.Call{name: "box_div", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(box_eq(var1, var2)) do + %Sonata.Expr.Call{name: "box_eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(box_ge(var1, var2)) do + %Sonata.Expr.Call{name: "box_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(box_gt(var1, var2)) do + %Sonata.Expr.Call{name: "box_gt", arguments: [var1, var2]} + end + @doc("I/O") + def(box_in(var1)) do + %Sonata.Expr.Call{name: "box_in", arguments: [var1]} + end + @doc("implementation of # operator") + def(box_intersect(var1, var2)) do + %Sonata.Expr.Call{name: "box_intersect", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(box_le(var1, var2)) do + %Sonata.Expr.Call{name: "box_le", arguments: [var1, var2]} + end + @doc("implementation of << operator") + def(box_left(var1, var2)) do + %Sonata.Expr.Call{name: "box_left", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(box_lt(var1, var2)) do + %Sonata.Expr.Call{name: "box_lt", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(box_mul(var1, var2)) do + %Sonata.Expr.Call{name: "box_mul", arguments: [var1, var2]} + end + @doc("I/O") + def(box_out(var1)) do + %Sonata.Expr.Call{name: "box_out", arguments: [var1]} + end + @doc("implementation of |&> operator") + def(box_overabove(var1, var2)) do + %Sonata.Expr.Call{name: "box_overabove", arguments: [var1, var2]} + end + @doc("implementation of &<| operator") + def(box_overbelow(var1, var2)) do + %Sonata.Expr.Call{name: "box_overbelow", arguments: [var1, var2]} + end + @doc("implementation of && operator") + def(box_overlap(var1, var2)) do + %Sonata.Expr.Call{name: "box_overlap", arguments: [var1, var2]} + end + @doc("implementation of &< operator") + def(box_overleft(var1, var2)) do + %Sonata.Expr.Call{name: "box_overleft", arguments: [var1, var2]} + end + @doc("implementation of &> operator") + def(box_overright(var1, var2)) do + %Sonata.Expr.Call{name: "box_overright", arguments: [var1, var2]} + end + @doc("I/O") + def(box_recv(var1)) do + %Sonata.Expr.Call{name: "box_recv", arguments: [var1]} + end + @doc("implementation of >> operator") + def(box_right(var1, var2)) do + %Sonata.Expr.Call{name: "box_right", arguments: [var1, var2]} + end + @doc("implementation of ~= operator") + def(box_same(var1, var2)) do + %Sonata.Expr.Call{name: "box_same", arguments: [var1, var2]} + end + @doc("I/O") + def(box_send(var1)) do + %Sonata.Expr.Call{name: "box_send", arguments: [var1]} + end + @doc("implementation of - operator") + def(box_sub(var1, var2)) do + %Sonata.Expr.Call{name: "box_sub", arguments: [var1, var2]} + end + @doc("adjust char() to typmod length") + def(bpchar(var1, var2, var3)) do + %Sonata.Expr.Call{name: "bpchar", arguments: [var1, var2, var3]} + end + @doc("larger of two") + def(bpchar_larger(var1, var2)) do + %Sonata.Expr.Call{name: "bpchar_larger", arguments: [var1, var2]} + end + @doc("implementation of ~>=~ operator") + def(bpchar_pattern_ge(var1, var2)) do + %Sonata.Expr.Call{name: "bpchar_pattern_ge", arguments: [var1, var2]} + end + @doc("implementation of ~>~ operator") + def(bpchar_pattern_gt(var1, var2)) do + %Sonata.Expr.Call{name: "bpchar_pattern_gt", arguments: [var1, var2]} + end + @doc("implementation of ~<=~ operator") + def(bpchar_pattern_le(var1, var2)) do + %Sonata.Expr.Call{name: "bpchar_pattern_le", arguments: [var1, var2]} + end + @doc("implementation of ~<~ operator") + def(bpchar_pattern_lt(var1, var2)) do + %Sonata.Expr.Call{name: "bpchar_pattern_lt", arguments: [var1, var2]} + end + @doc("smaller of two") + def(bpchar_smaller(var1, var2)) do + %Sonata.Expr.Call{name: "bpchar_smaller", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(bpcharcmp(var1, var2)) do + %Sonata.Expr.Call{name: "bpcharcmp", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(bpchareq(var1, var2)) do + %Sonata.Expr.Call{name: "bpchareq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(bpcharge(var1, var2)) do + %Sonata.Expr.Call{name: "bpcharge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(bpchargt(var1, var2)) do + %Sonata.Expr.Call{name: "bpchargt", arguments: [var1, var2]} + end + @doc("implementation of ~~* operator") + def(bpchariclike(var1, var2)) do + %Sonata.Expr.Call{name: "bpchariclike", arguments: [var1, var2]} + end + @doc("implementation of !~~* operator") + def(bpcharicnlike(var1, var2)) do + %Sonata.Expr.Call{name: "bpcharicnlike", arguments: [var1, var2]} + end + @doc("implementation of ~* operator") + def(bpcharicregexeq(var1, var2)) do + %Sonata.Expr.Call{name: "bpcharicregexeq", arguments: [var1, var2]} + end + @doc("implementation of !~* operator") + def(bpcharicregexne(var1, var2)) do + %Sonata.Expr.Call{name: "bpcharicregexne", arguments: [var1, var2]} + end + @doc("I/O") + def(bpcharin(var1, var2, var3)) do + %Sonata.Expr.Call{name: "bpcharin", arguments: [var1, var2, var3]} + end + @doc("implementation of <= operator") + def(bpcharle(var1, var2)) do + %Sonata.Expr.Call{name: "bpcharle", arguments: [var1, var2]} + end + @doc("implementation of ~~ operator") + def(bpcharlike(var1, var2)) do + %Sonata.Expr.Call{name: "bpcharlike", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(bpcharlt(var1, var2)) do + %Sonata.Expr.Call{name: "bpcharlt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(bpcharne(var1, var2)) do + %Sonata.Expr.Call{name: "bpcharne", arguments: [var1, var2]} + end + @doc("implementation of !~~ operator") + def(bpcharnlike(var1, var2)) do + %Sonata.Expr.Call{name: "bpcharnlike", arguments: [var1, var2]} + end + @doc("I/O") + def(bpcharout(var1)) do + %Sonata.Expr.Call{name: "bpcharout", arguments: [var1]} + end + @doc("I/O") + def(bpcharrecv(var1, var2, var3)) do + %Sonata.Expr.Call{name: "bpcharrecv", arguments: [var1, var2, var3]} + end + @doc("implementation of ~ operator") + def(bpcharregexeq(var1, var2)) do + %Sonata.Expr.Call{name: "bpcharregexeq", arguments: [var1, var2]} + end + @doc("implementation of !~ operator") + def(bpcharregexne(var1, var2)) do + %Sonata.Expr.Call{name: "bpcharregexne", arguments: [var1, var2]} + end + @doc("I/O") + def(bpcharsend(var1)) do + %Sonata.Expr.Call{name: "bpcharsend", arguments: [var1]} + end + @doc("I/O typmod") + def(bpchartypmodin(var1)) do + %Sonata.Expr.Call{name: "bpchartypmodin", arguments: [var1]} + end + @doc("I/O typmod") + def(bpchartypmodout(var1)) do + %Sonata.Expr.Call{name: "bpchartypmodout", arguments: [var1]} + end + @doc("BRIN inclusion support") + def(brin_inclusion_add_value(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "brin_inclusion_add_value", arguments: [var1, var2, var3, var4]} + end + @doc("BRIN inclusion support") + def(brin_inclusion_consistent(var1, var2, var3)) do + %Sonata.Expr.Call{name: "brin_inclusion_consistent", arguments: [var1, var2, var3]} + end + @doc("BRIN inclusion support") + def(brin_inclusion_opcinfo(var1)) do + %Sonata.Expr.Call{name: "brin_inclusion_opcinfo", arguments: [var1]} + end + @doc("BRIN inclusion support") + def(brin_inclusion_union(var1, var2, var3)) do + %Sonata.Expr.Call{name: "brin_inclusion_union", arguments: [var1, var2, var3]} + end + @doc("BRIN minmax support") + def(brin_minmax_add_value(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "brin_minmax_add_value", arguments: [var1, var2, var3, var4]} + end + @doc("BRIN minmax support") + def(brin_minmax_consistent(var1, var2, var3)) do + %Sonata.Expr.Call{name: "brin_minmax_consistent", arguments: [var1, var2, var3]} + end + @doc("BRIN minmax support") + def(brin_minmax_opcinfo(var1)) do + %Sonata.Expr.Call{name: "brin_minmax_opcinfo", arguments: [var1]} + end + @doc("BRIN minmax support") + def(brin_minmax_union(var1, var2, var3)) do + %Sonata.Expr.Call{name: "brin_minmax_union", arguments: [var1, var2, var3]} + end + @doc("brin: standalone scan new table pages") + def(brin_summarize_new_values(var1)) do + %Sonata.Expr.Call{name: "brin_summarize_new_values", arguments: [var1]} + end + @doc("brin(internal)") + def(brinbeginscan(var1, var2, var3)) do + %Sonata.Expr.Call{name: "brinbeginscan", arguments: [var1, var2, var3]} + end + @doc("brin(internal)") + def(brinbuild(var1, var2, var3)) do + %Sonata.Expr.Call{name: "brinbuild", arguments: [var1, var2, var3]} + end + @doc("brin(internal)") + def(brinbuildempty(var1)) do + %Sonata.Expr.Call{name: "brinbuildempty", arguments: [var1]} + end + @doc("brin(internal)") + def(brinbulkdelete(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "brinbulkdelete", arguments: [var1, var2, var3, var4]} + end + @doc("brin(internal)") + def(brincostestimate(var1, var2, var3, var4, var5, var6, var7)) do + %Sonata.Expr.Call{name: "brincostestimate", arguments: [var1, var2, var3, var4, var5, var6, var7]} + end + @doc("brin(internal)") + def(brinendscan(var1)) do + %Sonata.Expr.Call{name: "brinendscan", arguments: [var1]} + end + @doc("brin(internal)") + def(bringetbitmap(var1, var2)) do + %Sonata.Expr.Call{name: "bringetbitmap", arguments: [var1, var2]} + end + @doc("brin(internal)") + def(brininsert(var1, var2, var3, var4, var5, var6)) do + %Sonata.Expr.Call{name: "brininsert", arguments: [var1, var2, var3, var4, var5, var6]} + end + @doc("brin(internal)") + def(brinmarkpos(var1)) do + %Sonata.Expr.Call{name: "brinmarkpos", arguments: [var1]} + end + @doc("brin(internal)") + def(brinoptions(var1, var2)) do + %Sonata.Expr.Call{name: "brinoptions", arguments: [var1, var2]} + end + @doc("brin(internal)") + def(brinrescan(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "brinrescan", arguments: [var1, var2, var3, var4, var5]} + end + @doc("brin(internal)") + def(brinrestrpos(var1)) do + %Sonata.Expr.Call{name: "brinrestrpos", arguments: [var1]} + end + @doc("brin(internal)") + def(brinvacuumcleanup(var1, var2)) do + %Sonata.Expr.Call{name: "brinvacuumcleanup", arguments: [var1, var2]} + end + @doc("broadcast address of network") + def(broadcast(var1)) do + %Sonata.Expr.Call{name: "broadcast", arguments: [var1]} + end + @doc("less-equal-greater") + def(btabstimecmp(var1, var2)) do + %Sonata.Expr.Call{name: "btabstimecmp", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(btarraycmp(var1, var2)) do + %Sonata.Expr.Call{name: "btarraycmp", arguments: [var1, var2]} + end + @doc("btree(internal)") + def(btbeginscan(var1, var2, var3)) do + %Sonata.Expr.Call{name: "btbeginscan", arguments: [var1, var2, var3]} + end + @doc("less-equal-greater") + def(btboolcmp(var1, var2)) do + %Sonata.Expr.Call{name: "btboolcmp", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(btbpchar_pattern_cmp(var1, var2)) do + %Sonata.Expr.Call{name: "btbpchar_pattern_cmp", arguments: [var1, var2]} + end + @doc("btree(internal)") + def(btbuild(var1, var2, var3)) do + %Sonata.Expr.Call{name: "btbuild", arguments: [var1, var2, var3]} + end + @doc("btree(internal)") + def(btbuildempty(var1)) do + %Sonata.Expr.Call{name: "btbuildempty", arguments: [var1]} + end + @doc("btree(internal)") + def(btbulkdelete(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "btbulkdelete", arguments: [var1, var2, var3, var4]} + end + @doc("btree(internal)") + def(btcanreturn(var1, var2)) do + %Sonata.Expr.Call{name: "btcanreturn", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(btcharcmp(var1, var2)) do + %Sonata.Expr.Call{name: "btcharcmp", arguments: [var1, var2]} + end + @doc("btree(internal)") + def(btcostestimate(var1, var2, var3, var4, var5, var6, var7)) do + %Sonata.Expr.Call{name: "btcostestimate", arguments: [var1, var2, var3, var4, var5, var6, var7]} + end + @doc("btree(internal)") + def(btendscan(var1)) do + %Sonata.Expr.Call{name: "btendscan", arguments: [var1]} + end + @doc("less-equal-greater") + def(btfloat48cmp(var1, var2)) do + %Sonata.Expr.Call{name: "btfloat48cmp", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(btfloat4cmp(var1, var2)) do + %Sonata.Expr.Call{name: "btfloat4cmp", arguments: [var1, var2]} + end + @doc("sort support") + def(btfloat4sortsupport(var1)) do + %Sonata.Expr.Call{name: "btfloat4sortsupport", arguments: [var1]} + end + @doc("less-equal-greater") + def(btfloat84cmp(var1, var2)) do + %Sonata.Expr.Call{name: "btfloat84cmp", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(btfloat8cmp(var1, var2)) do + %Sonata.Expr.Call{name: "btfloat8cmp", arguments: [var1, var2]} + end + @doc("sort support") + def(btfloat8sortsupport(var1)) do + %Sonata.Expr.Call{name: "btfloat8sortsupport", arguments: [var1]} + end + @doc("btree(internal)") + def(btgetbitmap(var1, var2)) do + %Sonata.Expr.Call{name: "btgetbitmap", arguments: [var1, var2]} + end + @doc("btree(internal)") + def(btgettuple(var1, var2)) do + %Sonata.Expr.Call{name: "btgettuple", arguments: [var1, var2]} + end + @doc("btree(internal)") + def(btinsert(var1, var2, var3, var4, var5, var6)) do + %Sonata.Expr.Call{name: "btinsert", arguments: [var1, var2, var3, var4, var5, var6]} + end + @doc("less-equal-greater") + def(btint24cmp(var1, var2)) do + %Sonata.Expr.Call{name: "btint24cmp", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(btint28cmp(var1, var2)) do + %Sonata.Expr.Call{name: "btint28cmp", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(btint2cmp(var1, var2)) do + %Sonata.Expr.Call{name: "btint2cmp", arguments: [var1, var2]} + end + @doc("sort support") + def(btint2sortsupport(var1)) do + %Sonata.Expr.Call{name: "btint2sortsupport", arguments: [var1]} + end + @doc("less-equal-greater") + def(btint42cmp(var1, var2)) do + %Sonata.Expr.Call{name: "btint42cmp", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(btint48cmp(var1, var2)) do + %Sonata.Expr.Call{name: "btint48cmp", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(btint4cmp(var1, var2)) do + %Sonata.Expr.Call{name: "btint4cmp", arguments: [var1, var2]} + end + @doc("sort support") + def(btint4sortsupport(var1)) do + %Sonata.Expr.Call{name: "btint4sortsupport", arguments: [var1]} + end + @doc("less-equal-greater") + def(btint82cmp(var1, var2)) do + %Sonata.Expr.Call{name: "btint82cmp", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(btint84cmp(var1, var2)) do + %Sonata.Expr.Call{name: "btint84cmp", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(btint8cmp(var1, var2)) do + %Sonata.Expr.Call{name: "btint8cmp", arguments: [var1, var2]} + end + @doc("sort support") + def(btint8sortsupport(var1)) do + %Sonata.Expr.Call{name: "btint8sortsupport", arguments: [var1]} + end + @doc("btree(internal)") + def(btmarkpos(var1)) do + %Sonata.Expr.Call{name: "btmarkpos", arguments: [var1]} + end + @doc("less-equal-greater") + def(btnamecmp(var1, var2)) do + %Sonata.Expr.Call{name: "btnamecmp", arguments: [var1, var2]} + end + @doc("sort support") + def(btnamesortsupport(var1)) do + %Sonata.Expr.Call{name: "btnamesortsupport", arguments: [var1]} + end + @doc("less-equal-greater") + def(btoidcmp(var1, var2)) do + %Sonata.Expr.Call{name: "btoidcmp", arguments: [var1, var2]} + end + @doc("sort support") + def(btoidsortsupport(var1)) do + %Sonata.Expr.Call{name: "btoidsortsupport", arguments: [var1]} + end + @doc("less-equal-greater") + def(btoidvectorcmp(var1, var2)) do + %Sonata.Expr.Call{name: "btoidvectorcmp", arguments: [var1, var2]} + end + @doc("btree(internal)") + def(btoptions(var1, var2)) do + %Sonata.Expr.Call{name: "btoptions", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(btrecordcmp(var1, var2)) do + %Sonata.Expr.Call{name: "btrecordcmp", arguments: [var1, var2]} + end + @doc("less-equal-greater based on byte images") + def(btrecordimagecmp(var1, var2)) do + %Sonata.Expr.Call{name: "btrecordimagecmp", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(btreltimecmp(var1, var2)) do + %Sonata.Expr.Call{name: "btreltimecmp", arguments: [var1, var2]} + end + @doc("btree(internal)") + def(btrescan(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "btrescan", arguments: [var1, var2, var3, var4, var5]} + end + @doc("btree(internal)") + def(btrestrpos(var1)) do + %Sonata.Expr.Call{name: "btrestrpos", arguments: [var1]} + end + @doc("trim both ends of string") + def(btrim(var1, var2)) do + %Sonata.Expr.Call{name: "btrim", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(bttext_pattern_cmp(var1, var2)) do + %Sonata.Expr.Call{name: "bttext_pattern_cmp", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(bttextcmp(var1, var2)) do + %Sonata.Expr.Call{name: "bttextcmp", arguments: [var1, var2]} + end + @doc("sort support") + def(bttextsortsupport(var1)) do + %Sonata.Expr.Call{name: "bttextsortsupport", arguments: [var1]} + end + @doc("less-equal-greater") + def(bttidcmp(var1, var2)) do + %Sonata.Expr.Call{name: "bttidcmp", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(bttintervalcmp(var1, var2)) do + %Sonata.Expr.Call{name: "bttintervalcmp", arguments: [var1, var2]} + end + @doc("btree(internal)") + def(btvacuumcleanup(var1, var2)) do + %Sonata.Expr.Call{name: "btvacuumcleanup", arguments: [var1, var2]} + end + @doc("aggregate final function") + def(bytea_string_agg_finalfn(var1)) do + %Sonata.Expr.Call{name: "bytea_string_agg_finalfn", arguments: [var1]} + end + @doc("aggregate transition function") + def(bytea_string_agg_transfn(var1, var2, var3)) do + %Sonata.Expr.Call{name: "bytea_string_agg_transfn", arguments: [var1, var2, var3]} + end + @doc("implementation of || operator") + def(byteacat(var1, var2)) do + %Sonata.Expr.Call{name: "byteacat", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(byteacmp(var1, var2)) do + %Sonata.Expr.Call{name: "byteacmp", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(byteaeq(var1, var2)) do + %Sonata.Expr.Call{name: "byteaeq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(byteage(var1, var2)) do + %Sonata.Expr.Call{name: "byteage", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(byteagt(var1, var2)) do + %Sonata.Expr.Call{name: "byteagt", arguments: [var1, var2]} + end + @doc("I/O") + def(byteain(var1)) do + %Sonata.Expr.Call{name: "byteain", arguments: [var1]} + end + @doc("implementation of <= operator") + def(byteale(var1, var2)) do + %Sonata.Expr.Call{name: "byteale", arguments: [var1, var2]} + end + @doc("implementation of ~~ operator") + def(bytealike(var1, var2)) do + %Sonata.Expr.Call{name: "bytealike", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(bytealt(var1, var2)) do + %Sonata.Expr.Call{name: "bytealt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(byteane(var1, var2)) do + %Sonata.Expr.Call{name: "byteane", arguments: [var1, var2]} + end + @doc("implementation of !~~ operator") + def(byteanlike(var1, var2)) do + %Sonata.Expr.Call{name: "byteanlike", arguments: [var1, var2]} + end + @doc("I/O") + def(byteaout(var1)) do + %Sonata.Expr.Call{name: "byteaout", arguments: [var1]} + end + @doc("I/O") + def(bytearecv(var1)) do + %Sonata.Expr.Call{name: "bytearecv", arguments: [var1]} + end + @doc("I/O") + def(byteasend(var1)) do + %Sonata.Expr.Call{name: "byteasend", arguments: [var1]} + end + @doc("array cardinality") + def(cardinality(var1)) do + %Sonata.Expr.Call{name: "cardinality", arguments: [var1]} + end + @doc("less-equal-greater") + def(cash_cmp(var1, var2)) do + %Sonata.Expr.Call{name: "cash_cmp", arguments: [var1, var2]} + end + @doc("implementation of / operator") + def(cash_div_cash(var1, var2)) do + %Sonata.Expr.Call{name: "cash_div_cash", arguments: [var1, var2]} + end + @doc("implementation of / operator") + def(cash_div_flt4(var1, var2)) do + %Sonata.Expr.Call{name: "cash_div_flt4", arguments: [var1, var2]} + end + @doc("implementation of / operator") + def(cash_div_flt8(var1, var2)) do + %Sonata.Expr.Call{name: "cash_div_flt8", arguments: [var1, var2]} + end + @doc("implementation of / operator") + def(cash_div_int2(var1, var2)) do + %Sonata.Expr.Call{name: "cash_div_int2", arguments: [var1, var2]} + end + @doc("implementation of / operator") + def(cash_div_int4(var1, var2)) do + %Sonata.Expr.Call{name: "cash_div_int4", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(cash_eq(var1, var2)) do + %Sonata.Expr.Call{name: "cash_eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(cash_ge(var1, var2)) do + %Sonata.Expr.Call{name: "cash_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(cash_gt(var1, var2)) do + %Sonata.Expr.Call{name: "cash_gt", arguments: [var1, var2]} + end + @doc("I/O") + def(cash_in(var1)) do + %Sonata.Expr.Call{name: "cash_in", arguments: [var1]} + end + @doc("implementation of <= operator") + def(cash_le(var1, var2)) do + %Sonata.Expr.Call{name: "cash_le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(cash_lt(var1, var2)) do + %Sonata.Expr.Call{name: "cash_lt", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(cash_mi(var1, var2)) do + %Sonata.Expr.Call{name: "cash_mi", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(cash_mul_flt4(var1, var2)) do + %Sonata.Expr.Call{name: "cash_mul_flt4", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(cash_mul_flt8(var1, var2)) do + %Sonata.Expr.Call{name: "cash_mul_flt8", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(cash_mul_int2(var1, var2)) do + %Sonata.Expr.Call{name: "cash_mul_int2", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(cash_mul_int4(var1, var2)) do + %Sonata.Expr.Call{name: "cash_mul_int4", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(cash_ne(var1, var2)) do + %Sonata.Expr.Call{name: "cash_ne", arguments: [var1, var2]} + end + @doc("I/O") + def(cash_out(var1)) do + %Sonata.Expr.Call{name: "cash_out", arguments: [var1]} + end + @doc("implementation of + operator") + def(cash_pl(var1, var2)) do + %Sonata.Expr.Call{name: "cash_pl", arguments: [var1, var2]} + end + @doc("I/O") + def(cash_recv(var1)) do + %Sonata.Expr.Call{name: "cash_recv", arguments: [var1]} + end + @doc("I/O") + def(cash_send(var1)) do + %Sonata.Expr.Call{name: "cash_send", arguments: [var1]} + end + @doc("output money amount as words") + def(cash_words(var1)) do + %Sonata.Expr.Call{name: "cash_words", arguments: [var1]} + end + @doc("larger of two") + def(cashlarger(var1, var2)) do + %Sonata.Expr.Call{name: "cashlarger", arguments: [var1, var2]} + end + @doc("smaller of two") + def(cashsmaller(var1, var2)) do + %Sonata.Expr.Call{name: "cashsmaller", arguments: [var1, var2]} + end + @doc("cube root") + def(cbrt(var1)) do + %Sonata.Expr.Call{name: "cbrt", arguments: [var1]} + end + @doc("smallest integer >= value") + def(ceil(var1)) do + %Sonata.Expr.Call{name: "ceil", arguments: [var1]} + end + @doc("smallest integer >= value") + def(ceiling(var1)) do + %Sonata.Expr.Call{name: "ceiling", arguments: [var1]} + end + @doc("center of") + def(center(var1)) do + %Sonata.Expr.Call{name: "center", arguments: [var1]} + end + @doc("convert text to char") + def(char(var1)) do + %Sonata.Expr.Call{name: "char", arguments: [var1]} + end + @doc("character length") + def(char_length(var1)) do + %Sonata.Expr.Call{name: "char_length", arguments: [var1]} + end + @doc("character length") + def(character_length(var1)) do + %Sonata.Expr.Call{name: "character_length", arguments: [var1]} + end + @doc("implementation of = operator") + def(chareq(var1, var2)) do + %Sonata.Expr.Call{name: "chareq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(charge(var1, var2)) do + %Sonata.Expr.Call{name: "charge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(chargt(var1, var2)) do + %Sonata.Expr.Call{name: "chargt", arguments: [var1, var2]} + end + @doc("I/O") + def(charin(var1)) do + %Sonata.Expr.Call{name: "charin", arguments: [var1]} + end + @doc("implementation of <= operator") + def(charle(var1, var2)) do + %Sonata.Expr.Call{name: "charle", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(charlt(var1, var2)) do + %Sonata.Expr.Call{name: "charlt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(charne(var1, var2)) do + %Sonata.Expr.Call{name: "charne", arguments: [var1, var2]} + end + @doc("I/O") + def(charout(var1)) do + %Sonata.Expr.Call{name: "charout", arguments: [var1]} + end + @doc("I/O") + def(charrecv(var1)) do + %Sonata.Expr.Call{name: "charrecv", arguments: [var1]} + end + @doc("I/O") + def(charsend(var1)) do + %Sonata.Expr.Call{name: "charsend", arguments: [var1]} + end + @doc("convert int4 to char") + def(chr(var1)) do + %Sonata.Expr.Call{name: "chr", arguments: [var1]} + end + @doc("implementation of = operator") + def(cideq(var1, var2)) do + %Sonata.Expr.Call{name: "cideq", arguments: [var1, var2]} + end + @doc("I/O") + def(cidin(var1)) do + %Sonata.Expr.Call{name: "cidin", arguments: [var1]} + end + @doc("I/O") + def(cidout(var1)) do + %Sonata.Expr.Call{name: "cidout", arguments: [var1]} + end + @doc("convert inet to cidr") + def(cidr(var1)) do + %Sonata.Expr.Call{name: "cidr", arguments: [var1]} + end + @doc("I/O") + def(cidr_in(var1)) do + %Sonata.Expr.Call{name: "cidr_in", arguments: [var1]} + end + @doc("I/O") + def(cidr_out(var1)) do + %Sonata.Expr.Call{name: "cidr_out", arguments: [var1]} + end + @doc("I/O") + def(cidr_recv(var1)) do + %Sonata.Expr.Call{name: "cidr_recv", arguments: [var1]} + end + @doc("I/O") + def(cidr_send(var1)) do + %Sonata.Expr.Call{name: "cidr_send", arguments: [var1]} + end + @doc("I/O") + def(cidrecv(var1)) do + %Sonata.Expr.Call{name: "cidrecv", arguments: [var1]} + end + @doc("I/O") + def(cidsend(var1)) do + %Sonata.Expr.Call{name: "cidsend", arguments: [var1]} + end + @doc("convert point and radius to circle") + def(circle(var1, var2)) do + %Sonata.Expr.Call{name: "circle", arguments: [var1, var2]} + end + @doc("implementation of |>> operator") + def(circle_above(var1, var2)) do + %Sonata.Expr.Call{name: "circle_above", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(circle_add_pt(var1, var2)) do + %Sonata.Expr.Call{name: "circle_add_pt", arguments: [var1, var2]} + end + @doc("implementation of <<| operator") + def(circle_below(var1, var2)) do + %Sonata.Expr.Call{name: "circle_below", arguments: [var1, var2]} + end + @doc("implementation of @@ operator") + def(circle_center(var1)) do + %Sonata.Expr.Call{name: "circle_center", arguments: [var1]} + end + @doc("implementation of @> operator") + def(circle_contain(var1, var2)) do + %Sonata.Expr.Call{name: "circle_contain", arguments: [var1, var2]} + end + @doc("implementation of @> operator") + def(circle_contain_pt(var1, var2)) do + %Sonata.Expr.Call{name: "circle_contain_pt", arguments: [var1, var2]} + end + @doc("implementation of <@ operator") + def(circle_contained(var1, var2)) do + %Sonata.Expr.Call{name: "circle_contained", arguments: [var1, var2]} + end + @doc("implementation of <-> operator") + def(circle_distance(var1, var2)) do + %Sonata.Expr.Call{name: "circle_distance", arguments: [var1, var2]} + end + @doc("implementation of / operator") + def(circle_div_pt(var1, var2)) do + %Sonata.Expr.Call{name: "circle_div_pt", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(circle_eq(var1, var2)) do + %Sonata.Expr.Call{name: "circle_eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(circle_ge(var1, var2)) do + %Sonata.Expr.Call{name: "circle_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(circle_gt(var1, var2)) do + %Sonata.Expr.Call{name: "circle_gt", arguments: [var1, var2]} + end + @doc("I/O") + def(circle_in(var1)) do + %Sonata.Expr.Call{name: "circle_in", arguments: [var1]} + end + @doc("implementation of <= operator") + def(circle_le(var1, var2)) do + %Sonata.Expr.Call{name: "circle_le", arguments: [var1, var2]} + end + @doc("implementation of << operator") + def(circle_left(var1, var2)) do + %Sonata.Expr.Call{name: "circle_left", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(circle_lt(var1, var2)) do + %Sonata.Expr.Call{name: "circle_lt", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(circle_mul_pt(var1, var2)) do + %Sonata.Expr.Call{name: "circle_mul_pt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(circle_ne(var1, var2)) do + %Sonata.Expr.Call{name: "circle_ne", arguments: [var1, var2]} + end + @doc("I/O") + def(circle_out(var1)) do + %Sonata.Expr.Call{name: "circle_out", arguments: [var1]} + end + @doc("implementation of |&> operator") + def(circle_overabove(var1, var2)) do + %Sonata.Expr.Call{name: "circle_overabove", arguments: [var1, var2]} + end + @doc("implementation of &<| operator") + def(circle_overbelow(var1, var2)) do + %Sonata.Expr.Call{name: "circle_overbelow", arguments: [var1, var2]} + end + @doc("implementation of && operator") + def(circle_overlap(var1, var2)) do + %Sonata.Expr.Call{name: "circle_overlap", arguments: [var1, var2]} + end + @doc("implementation of &< operator") + def(circle_overleft(var1, var2)) do + %Sonata.Expr.Call{name: "circle_overleft", arguments: [var1, var2]} + end + @doc("implementation of &> operator") + def(circle_overright(var1, var2)) do + %Sonata.Expr.Call{name: "circle_overright", arguments: [var1, var2]} + end + @doc("I/O") + def(circle_recv(var1)) do + %Sonata.Expr.Call{name: "circle_recv", arguments: [var1]} + end + @doc("implementation of >> operator") + def(circle_right(var1, var2)) do + %Sonata.Expr.Call{name: "circle_right", arguments: [var1, var2]} + end + @doc("implementation of ~= operator") + def(circle_same(var1, var2)) do + %Sonata.Expr.Call{name: "circle_same", arguments: [var1, var2]} + end + @doc("I/O") + def(circle_send(var1)) do + %Sonata.Expr.Call{name: "circle_send", arguments: [var1]} + end + @doc("implementation of - operator") + def(circle_sub_pt(var1, var2)) do + %Sonata.Expr.Call{name: "circle_sub_pt", arguments: [var1, var2]} + end + @doc("current clock time") + def(clock_timestamp()) do + %Sonata.Expr.Call{name: "clock_timestamp", arguments: []} + end + @doc("implementation of ## operator") + def(close_lb(var1, var2)) do + %Sonata.Expr.Call{name: "close_lb", arguments: [var1, var2]} + end + @doc("implementation of ## operator") + def(close_ls(var1, var2)) do + %Sonata.Expr.Call{name: "close_ls", arguments: [var1, var2]} + end + @doc("implementation of ## operator") + def(close_lseg(var1, var2)) do + %Sonata.Expr.Call{name: "close_lseg", arguments: [var1, var2]} + end + @doc("implementation of ## operator") + def(close_pb(var1, var2)) do + %Sonata.Expr.Call{name: "close_pb", arguments: [var1, var2]} + end + @doc("implementation of ## operator") + def(close_pl(var1, var2)) do + %Sonata.Expr.Call{name: "close_pl", arguments: [var1, var2]} + end + @doc("implementation of ## operator") + def(close_ps(var1, var2)) do + %Sonata.Expr.Call{name: "close_ps", arguments: [var1, var2]} + end + @doc("implementation of ## operator") + def(close_sb(var1, var2)) do + %Sonata.Expr.Call{name: "close_sb", arguments: [var1, var2]} + end + @doc("implementation of ## operator") + def(close_sl(var1, var2)) do + %Sonata.Expr.Call{name: "close_sl", arguments: [var1, var2]} + end + @doc("get description for table column") + def(col_description(var1, var2)) do + %Sonata.Expr.Call{name: "col_description", arguments: [var1, var2]} + end + @doc("concatenate values") + def(concat(var1)) do + %Sonata.Expr.Call{name: "concat", arguments: [var1]} + end + @doc("concatenate values with separators") + def(concat_ws(var1, var2)) do + %Sonata.Expr.Call{name: "concat_ws", arguments: [var1, var2]} + end + @doc("join selectivity for containment comparison operators") + def(contjoinsel(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "contjoinsel", arguments: [var1, var2, var3, var4, var5]} + end + @doc("restriction selectivity for containment comparison operators") + def(contsel(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "contsel", arguments: [var1, var2, var3, var4]} + end + @doc("convert string with specified encoding names") + def(convert(var1, var2, var3)) do + %Sonata.Expr.Call{name: "convert", arguments: [var1, var2, var3]} + end + @doc("convert string with specified source encoding name") + def(convert_from(var1, var2)) do + %Sonata.Expr.Call{name: "convert_from", arguments: [var1, var2]} + end + @doc("convert string with specified destination encoding name") + def(convert_to(var1, var2)) do + %Sonata.Expr.Call{name: "convert_to", arguments: [var1, var2]} + end + @doc("correlation coefficient") + def(corr(var1, var2)) do + %Sonata.Expr.Call{name: "corr", arguments: [var1, var2]} + end + @doc("cosine") + def(cos(var1)) do + %Sonata.Expr.Call{name: "cos", arguments: [var1]} + end + @doc("cotangent") + def(cot(var1)) do + %Sonata.Expr.Call{name: "cot", arguments: [var1]} + end + @doc("number of input rows for which the input expression is not null") + def(count(var1)) do + %Sonata.Expr.Call{name: "count", arguments: [var1]} + end + @doc("population covariance") + def(covar_pop(var1, var2)) do + %Sonata.Expr.Call{name: "covar_pop", arguments: [var1, var2]} + end + @doc("sample covariance") + def(covar_samp(var1, var2)) do + %Sonata.Expr.Call{name: "covar_samp", arguments: [var1, var2]} + end + @doc("I/O") + def(cstring_in(var1)) do + %Sonata.Expr.Call{name: "cstring_in", arguments: [var1]} + end + @doc("I/O") + def(cstring_out(var1)) do + %Sonata.Expr.Call{name: "cstring_out", arguments: [var1]} + end + @doc("I/O") + def(cstring_recv(var1)) do + %Sonata.Expr.Call{name: "cstring_recv", arguments: [var1]} + end + @doc("I/O") + def(cstring_send(var1)) do + %Sonata.Expr.Call{name: "cstring_send", arguments: [var1]} + end + @doc("cumulative distribution of hypothetical row") + def(cume_dist(var1)) do + %Sonata.Expr.Call{name: "cume_dist", arguments: [var1]} + end + @doc("aggregate final function") + def(cume_dist_final(var1, var2)) do + %Sonata.Expr.Call{name: "cume_dist_final", arguments: [var1, var2]} + end + @doc("name of the current database") + def(current_database()) do + %Sonata.Expr.Call{name: "current_database", arguments: []} + end + @doc("get the currently executing query") + def(current_query()) do + %Sonata.Expr.Call{name: "current_query", arguments: []} + end + @doc("current schema name") + def(current_schema()) do + %Sonata.Expr.Call{name: "current_schema", arguments: []} + end + @doc("current schema search list") + def(current_schemas(var1)) do + %Sonata.Expr.Call{name: "current_schemas", arguments: [var1]} + end + @doc("SHOW X as a function") + def(current_setting(var1)) do + %Sonata.Expr.Call{name: "current_setting", arguments: [var1]} + end + @doc("current user name") + def(current_user()) do + %Sonata.Expr.Call{name: "current_user", arguments: []} + end + @doc("latest tid of a tuple") + def(currtid(var1, var2)) do + %Sonata.Expr.Call{name: "currtid", arguments: [var1, var2]} + end + @doc("latest tid of a tuple") + def(currtid2(var1, var2)) do + %Sonata.Expr.Call{name: "currtid2", arguments: [var1, var2]} + end + @doc("sequence current value") + def(currval(var1)) do + %Sonata.Expr.Call{name: "currval", arguments: [var1]} + end + @doc("map rows from cursor to XML") + def(cursor_to_xml(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "cursor_to_xml", arguments: [var1, var2, var3, var4, var5]} + end + @doc("map cursor structure to XML Schema") + def(cursor_to_xmlschema(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "cursor_to_xmlschema", arguments: [var1, var2, var3, var4]} + end + @doc("map database contents to XML") + def(database_to_xml(var1, var2, var3)) do + %Sonata.Expr.Call{name: "database_to_xml", arguments: [var1, var2, var3]} + end + @doc("map database contents and structure to XML and XML Schema") + def(database_to_xml_and_xmlschema(var1, var2, var3)) do + %Sonata.Expr.Call{name: "database_to_xml_and_xmlschema", arguments: [var1, var2, var3]} + end + @doc("map database structure to XML Schema") + def(database_to_xmlschema(var1, var2, var3)) do + %Sonata.Expr.Call{name: "database_to_xmlschema", arguments: [var1, var2, var3]} + end + @doc("convert timestamp to date") + def(date(var1)) do + %Sonata.Expr.Call{name: "date", arguments: [var1]} + end + @doc("less-equal-greater") + def(date_cmp(var1, var2)) do + %Sonata.Expr.Call{name: "date_cmp", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(date_cmp_timestamp(var1, var2)) do + %Sonata.Expr.Call{name: "date_cmp_timestamp", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(date_cmp_timestamptz(var1, var2)) do + %Sonata.Expr.Call{name: "date_cmp_timestamptz", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(date_eq(var1, var2)) do + %Sonata.Expr.Call{name: "date_eq", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(date_eq_timestamp(var1, var2)) do + %Sonata.Expr.Call{name: "date_eq_timestamp", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(date_eq_timestamptz(var1, var2)) do + %Sonata.Expr.Call{name: "date_eq_timestamptz", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(date_ge(var1, var2)) do + %Sonata.Expr.Call{name: "date_ge", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(date_ge_timestamp(var1, var2)) do + %Sonata.Expr.Call{name: "date_ge_timestamp", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(date_ge_timestamptz(var1, var2)) do + %Sonata.Expr.Call{name: "date_ge_timestamptz", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(date_gt(var1, var2)) do + %Sonata.Expr.Call{name: "date_gt", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(date_gt_timestamp(var1, var2)) do + %Sonata.Expr.Call{name: "date_gt_timestamp", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(date_gt_timestamptz(var1, var2)) do + %Sonata.Expr.Call{name: "date_gt_timestamptz", arguments: [var1, var2]} + end + @doc("I/O") + def(date_in(var1)) do + %Sonata.Expr.Call{name: "date_in", arguments: [var1]} + end + @doc("larger of two") + def(date_larger(var1, var2)) do + %Sonata.Expr.Call{name: "date_larger", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(date_le(var1, var2)) do + %Sonata.Expr.Call{name: "date_le", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(date_le_timestamp(var1, var2)) do + %Sonata.Expr.Call{name: "date_le_timestamp", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(date_le_timestamptz(var1, var2)) do + %Sonata.Expr.Call{name: "date_le_timestamptz", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(date_lt(var1, var2)) do + %Sonata.Expr.Call{name: "date_lt", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(date_lt_timestamp(var1, var2)) do + %Sonata.Expr.Call{name: "date_lt_timestamp", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(date_lt_timestamptz(var1, var2)) do + %Sonata.Expr.Call{name: "date_lt_timestamptz", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(date_mi(var1, var2)) do + %Sonata.Expr.Call{name: "date_mi", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(date_mi_interval(var1, var2)) do + %Sonata.Expr.Call{name: "date_mi_interval", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(date_mii(var1, var2)) do + %Sonata.Expr.Call{name: "date_mii", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(date_ne(var1, var2)) do + %Sonata.Expr.Call{name: "date_ne", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(date_ne_timestamp(var1, var2)) do + %Sonata.Expr.Call{name: "date_ne_timestamp", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(date_ne_timestamptz(var1, var2)) do + %Sonata.Expr.Call{name: "date_ne_timestamptz", arguments: [var1, var2]} + end + @doc("I/O") + def(date_out(var1)) do + %Sonata.Expr.Call{name: "date_out", arguments: [var1]} + end + @doc("extract field from abstime") + def(date_part(var1, var2)) do + %Sonata.Expr.Call{name: "date_part", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(date_pl_interval(var1, var2)) do + %Sonata.Expr.Call{name: "date_pl_interval", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(date_pli(var1, var2)) do + %Sonata.Expr.Call{name: "date_pli", arguments: [var1, var2]} + end + @doc("I/O") + def(date_recv(var1)) do + %Sonata.Expr.Call{name: "date_recv", arguments: [var1]} + end + @doc("I/O") + def(date_send(var1)) do + %Sonata.Expr.Call{name: "date_send", arguments: [var1]} + end + @doc("smaller of two") + def(date_smaller(var1, var2)) do + %Sonata.Expr.Call{name: "date_smaller", arguments: [var1, var2]} + end + @doc("sort support") + def(date_sortsupport(var1)) do + %Sonata.Expr.Call{name: "date_sortsupport", arguments: [var1]} + end + @doc("truncate interval to specified units") + def(date_trunc(var1, var2)) do + %Sonata.Expr.Call{name: "date_trunc", arguments: [var1, var2]} + end + @doc("daterange constructor") + def(daterange(var1, var2, var3)) do + %Sonata.Expr.Call{name: "daterange", arguments: [var1, var2, var3]} + end + @doc("convert a date range to canonical form") + def(daterange_canonical(var1)) do + %Sonata.Expr.Call{name: "daterange_canonical", arguments: [var1]} + end + @doc("float8 difference of two date values") + def(daterange_subdiff(var1, var2)) do + %Sonata.Expr.Call{name: "daterange_subdiff", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(datetime_pl(var1, var2)) do + %Sonata.Expr.Call{name: "datetime_pl", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(datetimetz_pl(var1, var2)) do + %Sonata.Expr.Call{name: "datetimetz_pl", arguments: [var1, var2]} + end + @doc("implementation of ||/ operator") + def(dcbrt(var1)) do + %Sonata.Expr.Call{name: "dcbrt", arguments: [var1]} + end + @doc("convert ascii-encoded text string into bytea value") + def(decode(var1, var2)) do + %Sonata.Expr.Call{name: "decode", arguments: [var1, var2]} + end + @doc("radians to degrees") + def(degrees(var1)) do + %Sonata.Expr.Call{name: "degrees", arguments: [var1]} + end + @doc("rank of hypothetical row without gaps") + def(dense_rank(var1)) do + %Sonata.Expr.Call{name: "dense_rank", arguments: [var1]} + end + @doc("aggregate final function") + def(dense_rank_final(var1, var2)) do + %Sonata.Expr.Call{name: "dense_rank_final", arguments: [var1, var2]} + end + @doc("natural exponential (e^x)") + def(dexp(var1)) do + %Sonata.Expr.Call{name: "dexp", arguments: [var1]} + end + @doc("box diagonal") + def(diagonal(var1)) do + %Sonata.Expr.Call{name: "diagonal", arguments: [var1]} + end + @doc("diameter of circle") + def(diameter(var1)) do + %Sonata.Expr.Call{name: "diameter", arguments: [var1]} + end + @doc("(internal)") + def(dispell_init(var1)) do + %Sonata.Expr.Call{name: "dispell_init", arguments: [var1]} + end + @doc("(internal)") + def(dispell_lexize(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "dispell_lexize", arguments: [var1, var2, var3, var4]} + end + @doc("implementation of <-> operator") + def(dist_cpoint(var1, var2)) do + %Sonata.Expr.Call{name: "dist_cpoint", arguments: [var1, var2]} + end + @doc("implementation of <-> operator") + def(dist_cpoly(var1, var2)) do + %Sonata.Expr.Call{name: "dist_cpoly", arguments: [var1, var2]} + end + @doc("implementation of <-> operator") + def(dist_lb(var1, var2)) do + %Sonata.Expr.Call{name: "dist_lb", arguments: [var1, var2]} + end + @doc("implementation of <-> operator") + def(dist_pb(var1, var2)) do + %Sonata.Expr.Call{name: "dist_pb", arguments: [var1, var2]} + end + @doc("implementation of <-> operator") + def(dist_pc(var1, var2)) do + %Sonata.Expr.Call{name: "dist_pc", arguments: [var1, var2]} + end + @doc("implementation of <-> operator") + def(dist_pl(var1, var2)) do + %Sonata.Expr.Call{name: "dist_pl", arguments: [var1, var2]} + end + @doc("implementation of <-> operator") + def(dist_polyp(var1, var2)) do + %Sonata.Expr.Call{name: "dist_polyp", arguments: [var1, var2]} + end + @doc("implementation of <-> operator") + def(dist_ppath(var1, var2)) do + %Sonata.Expr.Call{name: "dist_ppath", arguments: [var1, var2]} + end + @doc("implementation of <-> operator") + def(dist_ppoly(var1, var2)) do + %Sonata.Expr.Call{name: "dist_ppoly", arguments: [var1, var2]} + end + @doc("implementation of <-> operator") + def(dist_ps(var1, var2)) do + %Sonata.Expr.Call{name: "dist_ps", arguments: [var1, var2]} + end + @doc("implementation of <-> operator") + def(dist_sb(var1, var2)) do + %Sonata.Expr.Call{name: "dist_sb", arguments: [var1, var2]} + end + @doc("implementation of <-> operator") + def(dist_sl(var1, var2)) do + %Sonata.Expr.Call{name: "dist_sl", arguments: [var1, var2]} + end + @doc("trunc(x/y)") + def(div(var1, var2)) do + %Sonata.Expr.Call{name: "div", arguments: [var1, var2]} + end + @doc("natural logarithm") + def(dlog1(var1)) do + %Sonata.Expr.Call{name: "dlog1", arguments: [var1]} + end + @doc("base 10 logarithm") + def(dlog10(var1)) do + %Sonata.Expr.Call{name: "dlog10", arguments: [var1]} + end + @doc("I/O") + def(domain_in(var1, var2, var3)) do + %Sonata.Expr.Call{name: "domain_in", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(domain_recv(var1, var2, var3)) do + %Sonata.Expr.Call{name: "domain_recv", arguments: [var1, var2, var3]} + end + @doc("implementation of ^ operator") + def(dpow(var1, var2)) do + %Sonata.Expr.Call{name: "dpow", arguments: [var1, var2]} + end + @doc("round to nearest integer") + def(dround(var1)) do + %Sonata.Expr.Call{name: "dround", arguments: [var1]} + end + @doc("(internal)") + def(dsimple_init(var1)) do + %Sonata.Expr.Call{name: "dsimple_init", arguments: [var1]} + end + @doc("(internal)") + def(dsimple_lexize(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "dsimple_lexize", arguments: [var1, var2, var3, var4]} + end + @doc("implementation of |/ operator") + def(dsqrt(var1)) do + %Sonata.Expr.Call{name: "dsqrt", arguments: [var1]} + end + @doc("(internal)") + def(dsynonym_init(var1)) do + %Sonata.Expr.Call{name: "dsynonym_init", arguments: [var1]} + end + @doc("(internal)") + def(dsynonym_lexize(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "dsynonym_lexize", arguments: [var1, var2, var3, var4]} + end + @doc("truncate to integer") + def(dtrunc(var1)) do + %Sonata.Expr.Call{name: "dtrunc", arguments: [var1]} + end + @doc("implementation of <@ operator") + def(elem_contained_by_range(var1, var2)) do + %Sonata.Expr.Call{name: "elem_contained_by_range", arguments: [var1, var2]} + end + @doc("convert bytea value into some ascii-only text string") + def(encode(var1, var2)) do + %Sonata.Expr.Call{name: "encode", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(enum_cmp(var1, var2)) do + %Sonata.Expr.Call{name: "enum_cmp", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(enum_eq(var1, var2)) do + %Sonata.Expr.Call{name: "enum_eq", arguments: [var1, var2]} + end + @doc("first value of the input enum type") + def(enum_first(var1)) do + %Sonata.Expr.Call{name: "enum_first", arguments: [var1]} + end + @doc("implementation of >= operator") + def(enum_ge(var1, var2)) do + %Sonata.Expr.Call{name: "enum_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(enum_gt(var1, var2)) do + %Sonata.Expr.Call{name: "enum_gt", arguments: [var1, var2]} + end + @doc("I/O") + def(enum_in(var1, var2)) do + %Sonata.Expr.Call{name: "enum_in", arguments: [var1, var2]} + end + @doc("larger of two") + def(enum_larger(var1, var2)) do + %Sonata.Expr.Call{name: "enum_larger", arguments: [var1, var2]} + end + @doc("last value of the input enum type") + def(enum_last(var1)) do + %Sonata.Expr.Call{name: "enum_last", arguments: [var1]} + end + @doc("implementation of <= operator") + def(enum_le(var1, var2)) do + %Sonata.Expr.Call{name: "enum_le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(enum_lt(var1, var2)) do + %Sonata.Expr.Call{name: "enum_lt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(enum_ne(var1, var2)) do + %Sonata.Expr.Call{name: "enum_ne", arguments: [var1, var2]} + end + @doc("I/O") + def(enum_out(var1)) do + %Sonata.Expr.Call{name: "enum_out", arguments: [var1]} + end + @doc("range between the two given enum values, as an ordered array") + def(enum_range(var1, var2)) do + %Sonata.Expr.Call{name: "enum_range", arguments: [var1, var2]} + end + @doc("I/O") + def(enum_recv(var1, var2)) do + %Sonata.Expr.Call{name: "enum_recv", arguments: [var1, var2]} + end + @doc("I/O") + def(enum_send(var1)) do + %Sonata.Expr.Call{name: "enum_send", arguments: [var1]} + end + @doc("smaller of two") + def(enum_smaller(var1, var2)) do + %Sonata.Expr.Call{name: "enum_smaller", arguments: [var1, var2]} + end + @doc("join selectivity of = and related operators") + def(eqjoinsel(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "eqjoinsel", arguments: [var1, var2, var3, var4, var5]} + end + @doc("restriction selectivity of = and related operators") + def(eqsel(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "eqsel", arguments: [var1, var2, var3, var4]} + end + @doc("internal conversion function for EUC_CN to MULE_INTERNAL") + def(euc_cn_to_mic(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "euc_cn_to_mic", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for EUC_CN to UTF8") + def(euc_cn_to_utf8(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "euc_cn_to_utf8", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for EUC_JIS_2004 to SHIFT_JIS_2004") + def(euc_jis_2004_to_shift_jis_2004(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "euc_jis_2004_to_shift_jis_2004", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for EUC_JIS_2004 to UTF8") + def(euc_jis_2004_to_utf8(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "euc_jis_2004_to_utf8", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for EUC_JP to MULE_INTERNAL") + def(euc_jp_to_mic(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "euc_jp_to_mic", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for EUC_JP to SJIS") + def(euc_jp_to_sjis(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "euc_jp_to_sjis", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for EUC_JP to UTF8") + def(euc_jp_to_utf8(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "euc_jp_to_utf8", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for EUC_KR to MULE_INTERNAL") + def(euc_kr_to_mic(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "euc_kr_to_mic", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for EUC_KR to UTF8") + def(euc_kr_to_utf8(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "euc_kr_to_utf8", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for EUC_TW to BIG5") + def(euc_tw_to_big5(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "euc_tw_to_big5", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for EUC_TW to MULE_INTERNAL") + def(euc_tw_to_mic(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "euc_tw_to_mic", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for EUC_TW to UTF8") + def(euc_tw_to_utf8(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "euc_tw_to_utf8", arguments: [var1, var2, var3, var4, var5]} + end + @doc("I/O") + def(event_trigger_in(var1)) do + %Sonata.Expr.Call{name: "event_trigger_in", arguments: [var1]} + end + @doc("I/O") + def(event_trigger_out(var1)) do + %Sonata.Expr.Call{name: "event_trigger_out", arguments: [var1]} + end + @doc("boolean-and aggregate") + def(every(var1)) do + %Sonata.Expr.Call{name: "every", arguments: [var1]} + end + @doc("natural exponential (e^x)") + def(exp(var1)) do + %Sonata.Expr.Call{name: "exp", arguments: [var1]} + end + @doc("factorial") + def(factorial(var1)) do + %Sonata.Expr.Call{name: "factorial", arguments: [var1]} + end + @doc("address family (4 for IPv4, 6 for IPv6)") + def(family(var1)) do + %Sonata.Expr.Call{name: "family", arguments: [var1]} + end + @doc("I/O") + def(fdw_handler_in(var1)) do + %Sonata.Expr.Call{name: "fdw_handler_in", arguments: [var1]} + end + @doc("I/O") + def(fdw_handler_out(var1)) do + %Sonata.Expr.Call{name: "fdw_handler_out", arguments: [var1]} + end + @doc("fetch the first row value") + def(first_value(var1)) do + %Sonata.Expr.Call{name: "first_value", arguments: [var1]} + end + @doc("convert float8 to float4") + def(float4(var1)) do + %Sonata.Expr.Call{name: "float4", arguments: [var1]} + end + @doc("implementation of / operator") + def(float48div(var1, var2)) do + %Sonata.Expr.Call{name: "float48div", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(float48eq(var1, var2)) do + %Sonata.Expr.Call{name: "float48eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(float48ge(var1, var2)) do + %Sonata.Expr.Call{name: "float48ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(float48gt(var1, var2)) do + %Sonata.Expr.Call{name: "float48gt", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(float48le(var1, var2)) do + %Sonata.Expr.Call{name: "float48le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(float48lt(var1, var2)) do + %Sonata.Expr.Call{name: "float48lt", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(float48mi(var1, var2)) do + %Sonata.Expr.Call{name: "float48mi", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(float48mul(var1, var2)) do + %Sonata.Expr.Call{name: "float48mul", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(float48ne(var1, var2)) do + %Sonata.Expr.Call{name: "float48ne", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(float48pl(var1, var2)) do + %Sonata.Expr.Call{name: "float48pl", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(float4_accum(var1, var2)) do + %Sonata.Expr.Call{name: "float4_accum", arguments: [var1, var2]} + end + @doc("implementation of @ operator") + def(float4abs(var1)) do + %Sonata.Expr.Call{name: "float4abs", arguments: [var1]} + end + @doc("implementation of / operator") + def(float4div(var1, var2)) do + %Sonata.Expr.Call{name: "float4div", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(float4eq(var1, var2)) do + %Sonata.Expr.Call{name: "float4eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(float4ge(var1, var2)) do + %Sonata.Expr.Call{name: "float4ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(float4gt(var1, var2)) do + %Sonata.Expr.Call{name: "float4gt", arguments: [var1, var2]} + end + @doc("I/O") + def(float4in(var1)) do + %Sonata.Expr.Call{name: "float4in", arguments: [var1]} + end + @doc("larger of two") + def(float4larger(var1, var2)) do + %Sonata.Expr.Call{name: "float4larger", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(float4le(var1, var2)) do + %Sonata.Expr.Call{name: "float4le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(float4lt(var1, var2)) do + %Sonata.Expr.Call{name: "float4lt", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(float4mi(var1, var2)) do + %Sonata.Expr.Call{name: "float4mi", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(float4mul(var1, var2)) do + %Sonata.Expr.Call{name: "float4mul", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(float4ne(var1, var2)) do + %Sonata.Expr.Call{name: "float4ne", arguments: [var1, var2]} + end + @doc("I/O") + def(float4out(var1)) do + %Sonata.Expr.Call{name: "float4out", arguments: [var1]} + end + @doc("implementation of + operator") + def(float4pl(var1, var2)) do + %Sonata.Expr.Call{name: "float4pl", arguments: [var1, var2]} + end + @doc("I/O") + def(float4recv(var1)) do + %Sonata.Expr.Call{name: "float4recv", arguments: [var1]} + end + @doc("I/O") + def(float4send(var1)) do + %Sonata.Expr.Call{name: "float4send", arguments: [var1]} + end + @doc("smaller of two") + def(float4smaller(var1, var2)) do + %Sonata.Expr.Call{name: "float4smaller", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(float4um(var1)) do + %Sonata.Expr.Call{name: "float4um", arguments: [var1]} + end + @doc("implementation of + operator") + def(float4up(var1)) do + %Sonata.Expr.Call{name: "float4up", arguments: [var1]} + end + @doc("convert int4 to float8") + def(float8(var1)) do + %Sonata.Expr.Call{name: "float8", arguments: [var1]} + end + @doc("implementation of / operator") + def(float84div(var1, var2)) do + %Sonata.Expr.Call{name: "float84div", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(float84eq(var1, var2)) do + %Sonata.Expr.Call{name: "float84eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(float84ge(var1, var2)) do + %Sonata.Expr.Call{name: "float84ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(float84gt(var1, var2)) do + %Sonata.Expr.Call{name: "float84gt", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(float84le(var1, var2)) do + %Sonata.Expr.Call{name: "float84le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(float84lt(var1, var2)) do + %Sonata.Expr.Call{name: "float84lt", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(float84mi(var1, var2)) do + %Sonata.Expr.Call{name: "float84mi", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(float84mul(var1, var2)) do + %Sonata.Expr.Call{name: "float84mul", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(float84ne(var1, var2)) do + %Sonata.Expr.Call{name: "float84ne", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(float84pl(var1, var2)) do + %Sonata.Expr.Call{name: "float84pl", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(float8_accum(var1, var2)) do + %Sonata.Expr.Call{name: "float8_accum", arguments: [var1, var2]} + end + @doc("aggregate final function") + def(float8_avg(var1)) do + %Sonata.Expr.Call{name: "float8_avg", arguments: [var1]} + end + @doc("aggregate final function") + def(float8_corr(var1)) do + %Sonata.Expr.Call{name: "float8_corr", arguments: [var1]} + end + @doc("aggregate final function") + def(float8_covar_pop(var1)) do + %Sonata.Expr.Call{name: "float8_covar_pop", arguments: [var1]} + end + @doc("aggregate final function") + def(float8_covar_samp(var1)) do + %Sonata.Expr.Call{name: "float8_covar_samp", arguments: [var1]} + end + @doc("aggregate transition function") + def(float8_regr_accum(var1, var2, var3)) do + %Sonata.Expr.Call{name: "float8_regr_accum", arguments: [var1, var2, var3]} + end + @doc("aggregate final function") + def(float8_regr_avgx(var1)) do + %Sonata.Expr.Call{name: "float8_regr_avgx", arguments: [var1]} + end + @doc("aggregate final function") + def(float8_regr_avgy(var1)) do + %Sonata.Expr.Call{name: "float8_regr_avgy", arguments: [var1]} + end + @doc("aggregate final function") + def(float8_regr_intercept(var1)) do + %Sonata.Expr.Call{name: "float8_regr_intercept", arguments: [var1]} + end + @doc("aggregate final function") + def(float8_regr_r2(var1)) do + %Sonata.Expr.Call{name: "float8_regr_r2", arguments: [var1]} + end + @doc("aggregate final function") + def(float8_regr_slope(var1)) do + %Sonata.Expr.Call{name: "float8_regr_slope", arguments: [var1]} + end + @doc("aggregate final function") + def(float8_regr_sxx(var1)) do + %Sonata.Expr.Call{name: "float8_regr_sxx", arguments: [var1]} + end + @doc("aggregate final function") + def(float8_regr_sxy(var1)) do + %Sonata.Expr.Call{name: "float8_regr_sxy", arguments: [var1]} + end + @doc("aggregate final function") + def(float8_regr_syy(var1)) do + %Sonata.Expr.Call{name: "float8_regr_syy", arguments: [var1]} + end + @doc("aggregate final function") + def(float8_stddev_pop(var1)) do + %Sonata.Expr.Call{name: "float8_stddev_pop", arguments: [var1]} + end + @doc("aggregate final function") + def(float8_stddev_samp(var1)) do + %Sonata.Expr.Call{name: "float8_stddev_samp", arguments: [var1]} + end + @doc("aggregate final function") + def(float8_var_pop(var1)) do + %Sonata.Expr.Call{name: "float8_var_pop", arguments: [var1]} + end + @doc("aggregate final function") + def(float8_var_samp(var1)) do + %Sonata.Expr.Call{name: "float8_var_samp", arguments: [var1]} + end + @doc("implementation of @ operator") + def(float8abs(var1)) do + %Sonata.Expr.Call{name: "float8abs", arguments: [var1]} + end + @doc("implementation of / operator") + def(float8div(var1, var2)) do + %Sonata.Expr.Call{name: "float8div", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(float8eq(var1, var2)) do + %Sonata.Expr.Call{name: "float8eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(float8ge(var1, var2)) do + %Sonata.Expr.Call{name: "float8ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(float8gt(var1, var2)) do + %Sonata.Expr.Call{name: "float8gt", arguments: [var1, var2]} + end + @doc("I/O") + def(float8in(var1)) do + %Sonata.Expr.Call{name: "float8in", arguments: [var1]} + end + @doc("larger of two") + def(float8larger(var1, var2)) do + %Sonata.Expr.Call{name: "float8larger", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(float8le(var1, var2)) do + %Sonata.Expr.Call{name: "float8le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(float8lt(var1, var2)) do + %Sonata.Expr.Call{name: "float8lt", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(float8mi(var1, var2)) do + %Sonata.Expr.Call{name: "float8mi", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(float8mul(var1, var2)) do + %Sonata.Expr.Call{name: "float8mul", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(float8ne(var1, var2)) do + %Sonata.Expr.Call{name: "float8ne", arguments: [var1, var2]} + end + @doc("I/O") + def(float8out(var1)) do + %Sonata.Expr.Call{name: "float8out", arguments: [var1]} + end + @doc("implementation of + operator") + def(float8pl(var1, var2)) do + %Sonata.Expr.Call{name: "float8pl", arguments: [var1, var2]} + end + @doc("I/O") + def(float8recv(var1)) do + %Sonata.Expr.Call{name: "float8recv", arguments: [var1]} + end + @doc("I/O") + def(float8send(var1)) do + %Sonata.Expr.Call{name: "float8send", arguments: [var1]} + end + @doc("smaller of two") + def(float8smaller(var1, var2)) do + %Sonata.Expr.Call{name: "float8smaller", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(float8um(var1)) do + %Sonata.Expr.Call{name: "float8um", arguments: [var1]} + end + @doc("implementation of + operator") + def(float8up(var1)) do + %Sonata.Expr.Call{name: "float8up", arguments: [var1]} + end + @doc("largest integer <= value") + def(floor(var1)) do + %Sonata.Expr.Call{name: "floor", arguments: [var1]} + end + @doc("implementation of * operator") + def(flt4_mul_cash(var1, var2)) do + %Sonata.Expr.Call{name: "flt4_mul_cash", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(flt8_mul_cash(var1, var2)) do + %Sonata.Expr.Call{name: "flt8_mul_cash", arguments: [var1, var2]} + end + @doc("(internal)") + def(fmgr_c_validator(var1)) do + %Sonata.Expr.Call{name: "fmgr_c_validator", arguments: [var1]} + end + @doc("(internal)") + def(fmgr_internal_validator(var1)) do + %Sonata.Expr.Call{name: "fmgr_internal_validator", arguments: [var1]} + end + @doc("(internal)") + def(fmgr_sql_validator(var1)) do + %Sonata.Expr.Call{name: "fmgr_sql_validator", arguments: [var1]} + end + @doc("format text message") + def(format(var1, var2)) do + %Sonata.Expr.Call{name: "format", arguments: [var1, var2]} + end + @doc("format a type oid and atttypmod to canonical SQL") + def(format_type(var1, var2)) do + %Sonata.Expr.Call{name: "format_type", arguments: [var1, var2]} + end + @doc("internal conversion function for GB18030 to UTF8") + def(gb18030_to_utf8(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "gb18030_to_utf8", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for GBK to UTF8") + def(gbk_to_utf8(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "gbk_to_utf8", arguments: [var1, var2, var3, var4, var5]} + end + @doc("non-persistent series generator") + def(generate_series(var1, var2)) do + %Sonata.Expr.Call{name: "generate_series", arguments: [var1, var2]} + end + @doc("array subscripts generator") + def(generate_subscripts(var1, var2, var3)) do + %Sonata.Expr.Call{name: "generate_subscripts", arguments: [var1, var2, var3]} + end + @doc("get bit") + def(get_bit(var1, var2)) do + %Sonata.Expr.Call{name: "get_bit", arguments: [var1, var2]} + end + @doc("get byte") + def(get_byte(var1, var2)) do + %Sonata.Expr.Call{name: "get_byte", arguments: [var1, var2]} + end + @doc("get current tsearch configuration") + def(get_current_ts_config()) do + %Sonata.Expr.Call{name: "get_current_ts_config", arguments: []} + end + @doc("encoding name of current database") + def(getdatabaseencoding()) do + %Sonata.Expr.Call{name: "getdatabaseencoding", arguments: []} + end + @doc("deprecated, use current_user instead") + def(getpgusername()) do + %Sonata.Expr.Call{name: "getpgusername", arguments: []} + end + @doc("GIN tsvector support") + def(gin_cmp_prefix(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "gin_cmp_prefix", arguments: [var1, var2, var3, var4]} + end + @doc("GIN tsvector support") + def(gin_cmp_tslexeme(var1, var2)) do + %Sonata.Expr.Call{name: "gin_cmp_tslexeme", arguments: [var1, var2]} + end + @doc("GIN support") + def(gin_compare_jsonb(var1, var2)) do + %Sonata.Expr.Call{name: "gin_compare_jsonb", arguments: [var1, var2]} + end + @doc("GIN support") + def(gin_consistent_jsonb(var1, var2, var3, var4, var5, var6, var7, var8)) do + %Sonata.Expr.Call{name: "gin_consistent_jsonb", arguments: [var1, var2, var3, var4, var5, var6, var7, var8]} + end + @doc("GIN support") + def(gin_consistent_jsonb_path(var1, var2, var3, var4, var5, var6, var7, var8)) do + %Sonata.Expr.Call{name: "gin_consistent_jsonb_path", arguments: [var1, var2, var3, var4, var5, var6, var7, var8]} + end + @doc("GIN support") + def(gin_extract_jsonb(var1, var2, var3)) do + %Sonata.Expr.Call{name: "gin_extract_jsonb", arguments: [var1, var2, var3]} + end + @doc("GIN support") + def(gin_extract_jsonb_path(var1, var2, var3)) do + %Sonata.Expr.Call{name: "gin_extract_jsonb_path", arguments: [var1, var2, var3]} + end + @doc("GIN support") + def(gin_extract_jsonb_query(var1, var2, var3, var4, var5, var6, var7)) do + %Sonata.Expr.Call{name: "gin_extract_jsonb_query", arguments: [var1, var2, var3, var4, var5, var6, var7]} + end + @doc("GIN support") + def(gin_extract_jsonb_query_path(var1, var2, var3, var4, var5, var6, var7)) do + %Sonata.Expr.Call{name: "gin_extract_jsonb_query_path", arguments: [var1, var2, var3, var4, var5, var6, var7]} + end + @doc("GIN tsvector support (obsolete)") + def(gin_extract_tsquery(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "gin_extract_tsquery", arguments: [var1, var2, var3, var4, var5]} + end + @doc("GIN tsvector support (obsolete)") + def(gin_extract_tsvector(var1, var2)) do + %Sonata.Expr.Call{name: "gin_extract_tsvector", arguments: [var1, var2]} + end + @doc("GIN support") + def(gin_triconsistent_jsonb(var1, var2, var3, var4, var5, var6, var7)) do + %Sonata.Expr.Call{name: "gin_triconsistent_jsonb", arguments: [var1, var2, var3, var4, var5, var6, var7]} + end + @doc("GIN support") + def(gin_triconsistent_jsonb_path(var1, var2, var3, var4, var5, var6, var7)) do + %Sonata.Expr.Call{name: "gin_triconsistent_jsonb_path", arguments: [var1, var2, var3, var4, var5, var6, var7]} + end + @doc("GIN tsvector support (obsolete)") + def(gin_tsquery_consistent(var1, var2, var3, var4, var5, var6)) do + %Sonata.Expr.Call{name: "gin_tsquery_consistent", arguments: [var1, var2, var3, var4, var5, var6]} + end + @doc("GIN tsvector support") + def(gin_tsquery_triconsistent(var1, var2, var3, var4, var5, var6, var7)) do + %Sonata.Expr.Call{name: "gin_tsquery_triconsistent", arguments: [var1, var2, var3, var4, var5, var6, var7]} + end + @doc("GIN array support") + def(ginarrayconsistent(var1, var2, var3, var4, var5, var6, var7, var8)) do + %Sonata.Expr.Call{name: "ginarrayconsistent", arguments: [var1, var2, var3, var4, var5, var6, var7, var8]} + end + @doc("GIN array support (obsolete)") + def(ginarrayextract(var1, var2)) do + %Sonata.Expr.Call{name: "ginarrayextract", arguments: [var1, var2]} + end + @doc("GIN array support") + def(ginarraytriconsistent(var1, var2, var3, var4, var5, var6, var7)) do + %Sonata.Expr.Call{name: "ginarraytriconsistent", arguments: [var1, var2, var3, var4, var5, var6, var7]} + end + @doc("gin(internal)") + def(ginbeginscan(var1, var2, var3)) do + %Sonata.Expr.Call{name: "ginbeginscan", arguments: [var1, var2, var3]} + end + @doc("gin(internal)") + def(ginbuild(var1, var2, var3)) do + %Sonata.Expr.Call{name: "ginbuild", arguments: [var1, var2, var3]} + end + @doc("gin(internal)") + def(ginbuildempty(var1)) do + %Sonata.Expr.Call{name: "ginbuildempty", arguments: [var1]} + end + @doc("gin(internal)") + def(ginbulkdelete(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "ginbulkdelete", arguments: [var1, var2, var3, var4]} + end + @doc("gin(internal)") + def(gincostestimate(var1, var2, var3, var4, var5, var6, var7)) do + %Sonata.Expr.Call{name: "gincostestimate", arguments: [var1, var2, var3, var4, var5, var6, var7]} + end + @doc("gin(internal)") + def(ginendscan(var1)) do + %Sonata.Expr.Call{name: "ginendscan", arguments: [var1]} + end + @doc("gin(internal)") + def(gingetbitmap(var1, var2)) do + %Sonata.Expr.Call{name: "gingetbitmap", arguments: [var1, var2]} + end + @doc("gin(internal)") + def(gininsert(var1, var2, var3, var4, var5, var6)) do + %Sonata.Expr.Call{name: "gininsert", arguments: [var1, var2, var3, var4, var5, var6]} + end + @doc("gin(internal)") + def(ginmarkpos(var1)) do + %Sonata.Expr.Call{name: "ginmarkpos", arguments: [var1]} + end + @doc("gin(internal)") + def(ginoptions(var1, var2)) do + %Sonata.Expr.Call{name: "ginoptions", arguments: [var1, var2]} + end + @doc("GIN array support") + def(ginqueryarrayextract(var1, var2, var3, var4, var5, var6, var7)) do + %Sonata.Expr.Call{name: "ginqueryarrayextract", arguments: [var1, var2, var3, var4, var5, var6, var7]} + end + @doc("gin(internal)") + def(ginrescan(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "ginrescan", arguments: [var1, var2, var3, var4, var5]} + end + @doc("gin(internal)") + def(ginrestrpos(var1)) do + %Sonata.Expr.Call{name: "ginrestrpos", arguments: [var1]} + end + @doc("gin(internal)") + def(ginvacuumcleanup(var1, var2)) do + %Sonata.Expr.Call{name: "ginvacuumcleanup", arguments: [var1, var2]} + end + @doc("GiST support") + def(gist_bbox_distance(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "gist_bbox_distance", arguments: [var1, var2, var3, var4]} + end + @doc("GiST support") + def(gist_box_compress(var1)) do + %Sonata.Expr.Call{name: "gist_box_compress", arguments: [var1]} + end + @doc("GiST support") + def(gist_box_consistent(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "gist_box_consistent", arguments: [var1, var2, var3, var4, var5]} + end + @doc("GiST support") + def(gist_box_decompress(var1)) do + %Sonata.Expr.Call{name: "gist_box_decompress", arguments: [var1]} + end + @doc("GiST support") + def(gist_box_fetch(var1)) do + %Sonata.Expr.Call{name: "gist_box_fetch", arguments: [var1]} + end + @doc("GiST support") + def(gist_box_penalty(var1, var2, var3)) do + %Sonata.Expr.Call{name: "gist_box_penalty", arguments: [var1, var2, var3]} + end + @doc("GiST support") + def(gist_box_picksplit(var1, var2)) do + %Sonata.Expr.Call{name: "gist_box_picksplit", arguments: [var1, var2]} + end + @doc("GiST support") + def(gist_box_same(var1, var2, var3)) do + %Sonata.Expr.Call{name: "gist_box_same", arguments: [var1, var2, var3]} + end + @doc("GiST support") + def(gist_box_union(var1, var2)) do + %Sonata.Expr.Call{name: "gist_box_union", arguments: [var1, var2]} + end + @doc("GiST support") + def(gist_circle_compress(var1)) do + %Sonata.Expr.Call{name: "gist_circle_compress", arguments: [var1]} + end + @doc("GiST support") + def(gist_circle_consistent(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "gist_circle_consistent", arguments: [var1, var2, var3, var4, var5]} + end + @doc("GiST support") + def(gist_point_compress(var1)) do + %Sonata.Expr.Call{name: "gist_point_compress", arguments: [var1]} + end + @doc("GiST support") + def(gist_point_consistent(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "gist_point_consistent", arguments: [var1, var2, var3, var4, var5]} + end + @doc("GiST support") + def(gist_point_distance(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "gist_point_distance", arguments: [var1, var2, var3, var4]} + end + @doc("GiST support") + def(gist_point_fetch(var1)) do + %Sonata.Expr.Call{name: "gist_point_fetch", arguments: [var1]} + end + @doc("GiST support") + def(gist_poly_compress(var1)) do + %Sonata.Expr.Call{name: "gist_poly_compress", arguments: [var1]} + end + @doc("GiST support") + def(gist_poly_consistent(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "gist_poly_consistent", arguments: [var1, var2, var3, var4, var5]} + end + @doc("gist(internal)") + def(gistbeginscan(var1, var2, var3)) do + %Sonata.Expr.Call{name: "gistbeginscan", arguments: [var1, var2, var3]} + end + @doc("gist(internal)") + def(gistbuild(var1, var2, var3)) do + %Sonata.Expr.Call{name: "gistbuild", arguments: [var1, var2, var3]} + end + @doc("gist(internal)") + def(gistbuildempty(var1)) do + %Sonata.Expr.Call{name: "gistbuildempty", arguments: [var1]} + end + @doc("gist(internal)") + def(gistbulkdelete(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "gistbulkdelete", arguments: [var1, var2, var3, var4]} + end + @doc("gist(internal)") + def(gistcanreturn(var1, var2)) do + %Sonata.Expr.Call{name: "gistcanreturn", arguments: [var1, var2]} + end + @doc("gist(internal)") + def(gistcostestimate(var1, var2, var3, var4, var5, var6, var7)) do + %Sonata.Expr.Call{name: "gistcostestimate", arguments: [var1, var2, var3, var4, var5, var6, var7]} + end + @doc("gist(internal)") + def(gistendscan(var1)) do + %Sonata.Expr.Call{name: "gistendscan", arguments: [var1]} + end + @doc("gist(internal)") + def(gistgetbitmap(var1, var2)) do + %Sonata.Expr.Call{name: "gistgetbitmap", arguments: [var1, var2]} + end + @doc("gist(internal)") + def(gistgettuple(var1, var2)) do + %Sonata.Expr.Call{name: "gistgettuple", arguments: [var1, var2]} + end + @doc("gist(internal)") + def(gistinsert(var1, var2, var3, var4, var5, var6)) do + %Sonata.Expr.Call{name: "gistinsert", arguments: [var1, var2, var3, var4, var5, var6]} + end + @doc("gist(internal)") + def(gistmarkpos(var1)) do + %Sonata.Expr.Call{name: "gistmarkpos", arguments: [var1]} + end + @doc("gist(internal)") + def(gistoptions(var1, var2)) do + %Sonata.Expr.Call{name: "gistoptions", arguments: [var1, var2]} + end + @doc("gist(internal)") + def(gistrescan(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "gistrescan", arguments: [var1, var2, var3, var4, var5]} + end + @doc("gist(internal)") + def(gistrestrpos(var1)) do + %Sonata.Expr.Call{name: "gistrestrpos", arguments: [var1]} + end + @doc("gist(internal)") + def(gistvacuumcleanup(var1, var2)) do + %Sonata.Expr.Call{name: "gistvacuumcleanup", arguments: [var1, var2]} + end + @doc("GiST tsquery support") + def(gtsquery_compress(var1)) do + %Sonata.Expr.Call{name: "gtsquery_compress", arguments: [var1]} + end + @doc("GiST tsquery support") + def(gtsquery_consistent(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "gtsquery_consistent", arguments: [var1, var2, var3, var4, var5]} + end + @doc("GiST tsquery support") + def(gtsquery_decompress(var1)) do + %Sonata.Expr.Call{name: "gtsquery_decompress", arguments: [var1]} + end + @doc("GiST tsquery support") + def(gtsquery_penalty(var1, var2, var3)) do + %Sonata.Expr.Call{name: "gtsquery_penalty", arguments: [var1, var2, var3]} + end + @doc("GiST tsquery support") + def(gtsquery_picksplit(var1, var2)) do + %Sonata.Expr.Call{name: "gtsquery_picksplit", arguments: [var1, var2]} + end + @doc("GiST tsquery support") + def(gtsquery_same(var1, var2, var3)) do + %Sonata.Expr.Call{name: "gtsquery_same", arguments: [var1, var2, var3]} + end + @doc("GiST tsquery support") + def(gtsquery_union(var1, var2)) do + %Sonata.Expr.Call{name: "gtsquery_union", arguments: [var1, var2]} + end + @doc("GiST tsvector support") + def(gtsvector_compress(var1)) do + %Sonata.Expr.Call{name: "gtsvector_compress", arguments: [var1]} + end + @doc("GiST tsvector support") + def(gtsvector_consistent(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "gtsvector_consistent", arguments: [var1, var2, var3, var4, var5]} + end + @doc("GiST tsvector support") + def(gtsvector_decompress(var1)) do + %Sonata.Expr.Call{name: "gtsvector_decompress", arguments: [var1]} + end + @doc("GiST tsvector support") + def(gtsvector_penalty(var1, var2, var3)) do + %Sonata.Expr.Call{name: "gtsvector_penalty", arguments: [var1, var2, var3]} + end + @doc("GiST tsvector support") + def(gtsvector_picksplit(var1, var2)) do + %Sonata.Expr.Call{name: "gtsvector_picksplit", arguments: [var1, var2]} + end + @doc("GiST tsvector support") + def(gtsvector_same(var1, var2, var3)) do + %Sonata.Expr.Call{name: "gtsvector_same", arguments: [var1, var2, var3]} + end + @doc("GiST tsvector support") + def(gtsvector_union(var1, var2)) do + %Sonata.Expr.Call{name: "gtsvector_union", arguments: [var1, var2]} + end + @doc("I/O") + def(gtsvectorin(var1)) do + %Sonata.Expr.Call{name: "gtsvectorin", arguments: [var1]} + end + @doc("I/O") + def(gtsvectorout(var1)) do + %Sonata.Expr.Call{name: "gtsvectorout", arguments: [var1]} + end + @doc("user privilege on any column by user oid, rel name") + def(has_any_column_privilege(var1, var2, var3)) do + %Sonata.Expr.Call{name: "has_any_column_privilege", arguments: [var1, var2, var3]} + end + @doc("user privilege on column by username, rel oid, col name") + def(has_column_privilege(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "has_column_privilege", arguments: [var1, var2, var3, var4]} + end + @doc("user privilege on database by username, database name") + def(has_database_privilege(var1, var2, var3)) do + %Sonata.Expr.Call{name: "has_database_privilege", arguments: [var1, var2, var3]} + end + @doc("user privilege on foreign data wrapper by username, foreign data wrapper oid") + def(has_foreign_data_wrapper_privilege(var1, var2, var3)) do + %Sonata.Expr.Call{name: "has_foreign_data_wrapper_privilege", arguments: [var1, var2, var3]} + end + @doc("user privilege on function by user oid, function name") + def(has_function_privilege(var1, var2, var3)) do + %Sonata.Expr.Call{name: "has_function_privilege", arguments: [var1, var2, var3]} + end + @doc("current user privilege on language by language name") + def(has_language_privilege(var1, var2)) do + %Sonata.Expr.Call{name: "has_language_privilege", arguments: [var1, var2]} + end + @doc("user privilege on schema by user oid, schema oid") + def(has_schema_privilege(var1, var2, var3)) do + %Sonata.Expr.Call{name: "has_schema_privilege", arguments: [var1, var2, var3]} + end + @doc("user privilege on sequence by user oid, seq oid") + def(has_sequence_privilege(var1, var2, var3)) do + %Sonata.Expr.Call{name: "has_sequence_privilege", arguments: [var1, var2, var3]} + end + @doc("user privilege on server by user oid, server oid") + def(has_server_privilege(var1, var2, var3)) do + %Sonata.Expr.Call{name: "has_server_privilege", arguments: [var1, var2, var3]} + end + @doc("user privilege on relation by username, rel oid") + def(has_table_privilege(var1, var2, var3)) do + %Sonata.Expr.Call{name: "has_table_privilege", arguments: [var1, var2, var3]} + end + @doc("user privilege on tablespace by username, tablespace oid") + def(has_tablespace_privilege(var1, var2, var3)) do + %Sonata.Expr.Call{name: "has_tablespace_privilege", arguments: [var1, var2, var3]} + end + @doc("current user privilege on type by type name") + def(has_type_privilege(var1, var2)) do + %Sonata.Expr.Call{name: "has_type_privilege", arguments: [var1, var2]} + end + @doc("hash") + def(hash_aclitem(var1)) do + %Sonata.Expr.Call{name: "hash_aclitem", arguments: [var1]} + end + @doc("hash") + def(hash_array(var1)) do + %Sonata.Expr.Call{name: "hash_array", arguments: [var1]} + end + @doc("hash") + def(hash_numeric(var1)) do + %Sonata.Expr.Call{name: "hash_numeric", arguments: [var1]} + end + @doc("hash a range") + def(hash_range(var1)) do + %Sonata.Expr.Call{name: "hash_range", arguments: [var1]} + end + @doc("hash(internal)") + def(hashbeginscan(var1, var2, var3)) do + %Sonata.Expr.Call{name: "hashbeginscan", arguments: [var1, var2, var3]} + end + @doc("hash") + def(hashbpchar(var1)) do + %Sonata.Expr.Call{name: "hashbpchar", arguments: [var1]} + end + @doc("hash(internal)") + def(hashbuild(var1, var2, var3)) do + %Sonata.Expr.Call{name: "hashbuild", arguments: [var1, var2, var3]} + end + @doc("hash(internal)") + def(hashbuildempty(var1)) do + %Sonata.Expr.Call{name: "hashbuildempty", arguments: [var1]} + end + @doc("hash(internal)") + def(hashbulkdelete(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "hashbulkdelete", arguments: [var1, var2, var3, var4]} + end + @doc("hash") + def(hashchar(var1)) do + %Sonata.Expr.Call{name: "hashchar", arguments: [var1]} + end + @doc("hash(internal)") + def(hashcostestimate(var1, var2, var3, var4, var5, var6, var7)) do + %Sonata.Expr.Call{name: "hashcostestimate", arguments: [var1, var2, var3, var4, var5, var6, var7]} + end + @doc("hash(internal)") + def(hashendscan(var1)) do + %Sonata.Expr.Call{name: "hashendscan", arguments: [var1]} + end + @doc("hash") + def(hashenum(var1)) do + %Sonata.Expr.Call{name: "hashenum", arguments: [var1]} + end + @doc("hash") + def(hashfloat4(var1)) do + %Sonata.Expr.Call{name: "hashfloat4", arguments: [var1]} + end + @doc("hash") + def(hashfloat8(var1)) do + %Sonata.Expr.Call{name: "hashfloat8", arguments: [var1]} + end + @doc("hash(internal)") + def(hashgetbitmap(var1, var2)) do + %Sonata.Expr.Call{name: "hashgetbitmap", arguments: [var1, var2]} + end + @doc("hash(internal)") + def(hashgettuple(var1, var2)) do + %Sonata.Expr.Call{name: "hashgettuple", arguments: [var1, var2]} + end + @doc("hash") + def(hashinet(var1)) do + %Sonata.Expr.Call{name: "hashinet", arguments: [var1]} + end + @doc("hash(internal)") + def(hashinsert(var1, var2, var3, var4, var5, var6)) do + %Sonata.Expr.Call{name: "hashinsert", arguments: [var1, var2, var3, var4, var5, var6]} + end + @doc("hash") + def(hashint2(var1)) do + %Sonata.Expr.Call{name: "hashint2", arguments: [var1]} + end + @doc("hash") + def(hashint2vector(var1)) do + %Sonata.Expr.Call{name: "hashint2vector", arguments: [var1]} + end + @doc("hash") + def(hashint4(var1)) do + %Sonata.Expr.Call{name: "hashint4", arguments: [var1]} + end + @doc("hash") + def(hashint8(var1)) do + %Sonata.Expr.Call{name: "hashint8", arguments: [var1]} + end + @doc("hash") + def(hashmacaddr(var1)) do + %Sonata.Expr.Call{name: "hashmacaddr", arguments: [var1]} + end + @doc("hash(internal)") + def(hashmarkpos(var1)) do + %Sonata.Expr.Call{name: "hashmarkpos", arguments: [var1]} + end + @doc("hash") + def(hashname(var1)) do + %Sonata.Expr.Call{name: "hashname", arguments: [var1]} + end + @doc("hash") + def(hashoid(var1)) do + %Sonata.Expr.Call{name: "hashoid", arguments: [var1]} + end + @doc("hash") + def(hashoidvector(var1)) do + %Sonata.Expr.Call{name: "hashoidvector", arguments: [var1]} + end + @doc("hash(internal)") + def(hashoptions(var1, var2)) do + %Sonata.Expr.Call{name: "hashoptions", arguments: [var1, var2]} + end + @doc("hash(internal)") + def(hashrescan(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "hashrescan", arguments: [var1, var2, var3, var4, var5]} + end + @doc("hash(internal)") + def(hashrestrpos(var1)) do + %Sonata.Expr.Call{name: "hashrestrpos", arguments: [var1]} + end + @doc("hash") + def(hashtext(var1)) do + %Sonata.Expr.Call{name: "hashtext", arguments: [var1]} + end + @doc("hash(internal)") + def(hashvacuumcleanup(var1, var2)) do + %Sonata.Expr.Call{name: "hashvacuumcleanup", arguments: [var1, var2]} + end + @doc("hash") + def(hashvarlena(var1)) do + %Sonata.Expr.Call{name: "hashvarlena", arguments: [var1]} + end + @doc("box height") + def(height(var1)) do + %Sonata.Expr.Call{name: "height", arguments: [var1]} + end + @doc("show address octets only") + def(host(var1)) do + %Sonata.Expr.Call{name: "host", arguments: [var1]} + end + @doc("hostmask of address") + def(hostmask(var1)) do + %Sonata.Expr.Call{name: "hostmask", arguments: [var1]} + end + @doc("join selectivity of ILIKE") + def(iclikejoinsel(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "iclikejoinsel", arguments: [var1, var2, var3, var4, var5]} + end + @doc("restriction selectivity of ILIKE") + def(iclikesel(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "iclikesel", arguments: [var1, var2, var3, var4]} + end + @doc("join selectivity of NOT ILIKE") + def(icnlikejoinsel(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "icnlikejoinsel", arguments: [var1, var2, var3, var4, var5]} + end + @doc("restriction selectivity of NOT ILIKE") + def(icnlikesel(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "icnlikesel", arguments: [var1, var2, var3, var4]} + end + @doc("join selectivity of case-insensitive regex match") + def(icregexeqjoinsel(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "icregexeqjoinsel", arguments: [var1, var2, var3, var4, var5]} + end + @doc("restriction selectivity of case-insensitive regex match") + def(icregexeqsel(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "icregexeqsel", arguments: [var1, var2, var3, var4]} + end + @doc("join selectivity of case-insensitive regex non-match") + def(icregexnejoinsel(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "icregexnejoinsel", arguments: [var1, var2, var3, var4, var5]} + end + @doc("restriction selectivity of case-insensitive regex non-match") + def(icregexnesel(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "icregexnesel", arguments: [var1, var2, var3, var4]} + end + @doc("inet address of the client") + def(inet_client_addr()) do + %Sonata.Expr.Call{name: "inet_client_addr", arguments: []} + end + @doc("client's port number for this connection") + def(inet_client_port()) do + %Sonata.Expr.Call{name: "inet_client_port", arguments: []} + end + @doc("GiST support") + def(inet_gist_compress(var1)) do + %Sonata.Expr.Call{name: "inet_gist_compress", arguments: [var1]} + end + @doc("GiST support") + def(inet_gist_consistent(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "inet_gist_consistent", arguments: [var1, var2, var3, var4, var5]} + end + @doc("GiST support") + def(inet_gist_decompress(var1)) do + %Sonata.Expr.Call{name: "inet_gist_decompress", arguments: [var1]} + end + @doc("GiST support") + def(inet_gist_fetch(var1)) do + %Sonata.Expr.Call{name: "inet_gist_fetch", arguments: [var1]} + end + @doc("GiST support") + def(inet_gist_penalty(var1, var2, var3)) do + %Sonata.Expr.Call{name: "inet_gist_penalty", arguments: [var1, var2, var3]} + end + @doc("GiST support") + def(inet_gist_picksplit(var1, var2)) do + %Sonata.Expr.Call{name: "inet_gist_picksplit", arguments: [var1, var2]} + end + @doc("GiST support") + def(inet_gist_same(var1, var2, var3)) do + %Sonata.Expr.Call{name: "inet_gist_same", arguments: [var1, var2, var3]} + end + @doc("GiST support") + def(inet_gist_union(var1, var2)) do + %Sonata.Expr.Call{name: "inet_gist_union", arguments: [var1, var2]} + end + @doc("I/O") + def(inet_in(var1)) do + %Sonata.Expr.Call{name: "inet_in", arguments: [var1]} + end + @doc("the smallest network which includes both of the given networks") + def(inet_merge(var1, var2)) do + %Sonata.Expr.Call{name: "inet_merge", arguments: [var1, var2]} + end + @doc("I/O") + def(inet_out(var1)) do + %Sonata.Expr.Call{name: "inet_out", arguments: [var1]} + end + @doc("I/O") + def(inet_recv(var1)) do + %Sonata.Expr.Call{name: "inet_recv", arguments: [var1]} + end + @doc("are the addresses from the same family?") + def(inet_same_family(var1, var2)) do + %Sonata.Expr.Call{name: "inet_same_family", arguments: [var1, var2]} + end + @doc("I/O") + def(inet_send(var1)) do + %Sonata.Expr.Call{name: "inet_send", arguments: [var1]} + end + @doc("inet address of the server") + def(inet_server_addr()) do + %Sonata.Expr.Call{name: "inet_server_addr", arguments: []} + end + @doc("server's port number for this connection") + def(inet_server_port()) do + %Sonata.Expr.Call{name: "inet_server_port", arguments: []} + end + @doc("implementation of & operator") + def(inetand(var1, var2)) do + %Sonata.Expr.Call{name: "inetand", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(inetmi(var1, var2)) do + %Sonata.Expr.Call{name: "inetmi", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(inetmi_int8(var1, var2)) do + %Sonata.Expr.Call{name: "inetmi_int8", arguments: [var1, var2]} + end + @doc("implementation of ~ operator") + def(inetnot(var1)) do + %Sonata.Expr.Call{name: "inetnot", arguments: [var1]} + end + @doc("implementation of | operator") + def(inetor(var1, var2)) do + %Sonata.Expr.Call{name: "inetor", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(inetpl(var1, var2)) do + %Sonata.Expr.Call{name: "inetpl", arguments: [var1, var2]} + end + @doc("capitalize each word") + def(initcap(var1)) do + %Sonata.Expr.Call{name: "initcap", arguments: [var1]} + end + @doc("convert int8 to int2") + def(int2(var1)) do + %Sonata.Expr.Call{name: "int2", arguments: [var1]} + end + @doc("implementation of / operator") + def(int24div(var1, var2)) do + %Sonata.Expr.Call{name: "int24div", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(int24eq(var1, var2)) do + %Sonata.Expr.Call{name: "int24eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(int24ge(var1, var2)) do + %Sonata.Expr.Call{name: "int24ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(int24gt(var1, var2)) do + %Sonata.Expr.Call{name: "int24gt", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(int24le(var1, var2)) do + %Sonata.Expr.Call{name: "int24le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(int24lt(var1, var2)) do + %Sonata.Expr.Call{name: "int24lt", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(int24mi(var1, var2)) do + %Sonata.Expr.Call{name: "int24mi", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(int24mul(var1, var2)) do + %Sonata.Expr.Call{name: "int24mul", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(int24ne(var1, var2)) do + %Sonata.Expr.Call{name: "int24ne", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(int24pl(var1, var2)) do + %Sonata.Expr.Call{name: "int24pl", arguments: [var1, var2]} + end + @doc("implementation of / operator") + def(int28div(var1, var2)) do + %Sonata.Expr.Call{name: "int28div", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(int28eq(var1, var2)) do + %Sonata.Expr.Call{name: "int28eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(int28ge(var1, var2)) do + %Sonata.Expr.Call{name: "int28ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(int28gt(var1, var2)) do + %Sonata.Expr.Call{name: "int28gt", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(int28le(var1, var2)) do + %Sonata.Expr.Call{name: "int28le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(int28lt(var1, var2)) do + %Sonata.Expr.Call{name: "int28lt", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(int28mi(var1, var2)) do + %Sonata.Expr.Call{name: "int28mi", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(int28mul(var1, var2)) do + %Sonata.Expr.Call{name: "int28mul", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(int28ne(var1, var2)) do + %Sonata.Expr.Call{name: "int28ne", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(int28pl(var1, var2)) do + %Sonata.Expr.Call{name: "int28pl", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(int2_accum(var1, var2)) do + %Sonata.Expr.Call{name: "int2_accum", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(int2_accum_inv(var1, var2)) do + %Sonata.Expr.Call{name: "int2_accum_inv", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(int2_avg_accum(var1, var2)) do + %Sonata.Expr.Call{name: "int2_avg_accum", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(int2_avg_accum_inv(var1, var2)) do + %Sonata.Expr.Call{name: "int2_avg_accum_inv", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(int2_mul_cash(var1, var2)) do + %Sonata.Expr.Call{name: "int2_mul_cash", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(int2_sum(var1, var2)) do + %Sonata.Expr.Call{name: "int2_sum", arguments: [var1, var2]} + end + @doc("implementation of @ operator") + def(int2abs(var1)) do + %Sonata.Expr.Call{name: "int2abs", arguments: [var1]} + end + @doc("implementation of & operator") + def(int2and(var1, var2)) do + %Sonata.Expr.Call{name: "int2and", arguments: [var1, var2]} + end + @doc("implementation of / operator") + def(int2div(var1, var2)) do + %Sonata.Expr.Call{name: "int2div", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(int2eq(var1, var2)) do + %Sonata.Expr.Call{name: "int2eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(int2ge(var1, var2)) do + %Sonata.Expr.Call{name: "int2ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(int2gt(var1, var2)) do + %Sonata.Expr.Call{name: "int2gt", arguments: [var1, var2]} + end + @doc("I/O") + def(int2in(var1)) do + %Sonata.Expr.Call{name: "int2in", arguments: [var1]} + end + @doc("aggregate final function") + def(int2int4_sum(var1)) do + %Sonata.Expr.Call{name: "int2int4_sum", arguments: [var1]} + end + @doc("larger of two") + def(int2larger(var1, var2)) do + %Sonata.Expr.Call{name: "int2larger", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(int2le(var1, var2)) do + %Sonata.Expr.Call{name: "int2le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(int2lt(var1, var2)) do + %Sonata.Expr.Call{name: "int2lt", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(int2mi(var1, var2)) do + %Sonata.Expr.Call{name: "int2mi", arguments: [var1, var2]} + end + @doc("implementation of % operator") + def(int2mod(var1, var2)) do + %Sonata.Expr.Call{name: "int2mod", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(int2mul(var1, var2)) do + %Sonata.Expr.Call{name: "int2mul", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(int2ne(var1, var2)) do + %Sonata.Expr.Call{name: "int2ne", arguments: [var1, var2]} + end + @doc("implementation of ~ operator") + def(int2not(var1)) do + %Sonata.Expr.Call{name: "int2not", arguments: [var1]} + end + @doc("implementation of | operator") + def(int2or(var1, var2)) do + %Sonata.Expr.Call{name: "int2or", arguments: [var1, var2]} + end + @doc("I/O") + def(int2out(var1)) do + %Sonata.Expr.Call{name: "int2out", arguments: [var1]} + end + @doc("implementation of + operator") + def(int2pl(var1, var2)) do + %Sonata.Expr.Call{name: "int2pl", arguments: [var1, var2]} + end + @doc("I/O") + def(int2recv(var1)) do + %Sonata.Expr.Call{name: "int2recv", arguments: [var1]} + end + @doc("I/O") + def(int2send(var1)) do + %Sonata.Expr.Call{name: "int2send", arguments: [var1]} + end + @doc("implementation of << operator") + def(int2shl(var1, var2)) do + %Sonata.Expr.Call{name: "int2shl", arguments: [var1, var2]} + end + @doc("implementation of >> operator") + def(int2shr(var1, var2)) do + %Sonata.Expr.Call{name: "int2shr", arguments: [var1, var2]} + end + @doc("smaller of two") + def(int2smaller(var1, var2)) do + %Sonata.Expr.Call{name: "int2smaller", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(int2um(var1)) do + %Sonata.Expr.Call{name: "int2um", arguments: [var1]} + end + @doc("implementation of + operator") + def(int2up(var1)) do + %Sonata.Expr.Call{name: "int2up", arguments: [var1]} + end + @doc("implementation of = operator") + def(int2vectoreq(var1, var2)) do + %Sonata.Expr.Call{name: "int2vectoreq", arguments: [var1, var2]} + end + @doc("I/O") + def(int2vectorin(var1)) do + %Sonata.Expr.Call{name: "int2vectorin", arguments: [var1]} + end + @doc("I/O") + def(int2vectorout(var1)) do + %Sonata.Expr.Call{name: "int2vectorout", arguments: [var1]} + end + @doc("I/O") + def(int2vectorrecv(var1)) do + %Sonata.Expr.Call{name: "int2vectorrecv", arguments: [var1]} + end + @doc("I/O") + def(int2vectorsend(var1)) do + %Sonata.Expr.Call{name: "int2vectorsend", arguments: [var1]} + end + @doc("implementation of # operator") + def(int2xor(var1, var2)) do + %Sonata.Expr.Call{name: "int2xor", arguments: [var1, var2]} + end + @doc("convert boolean to int4") + def(int4(var1)) do + %Sonata.Expr.Call{name: "int4", arguments: [var1]} + end + @doc("implementation of / operator") + def(int42div(var1, var2)) do + %Sonata.Expr.Call{name: "int42div", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(int42eq(var1, var2)) do + %Sonata.Expr.Call{name: "int42eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(int42ge(var1, var2)) do + %Sonata.Expr.Call{name: "int42ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(int42gt(var1, var2)) do + %Sonata.Expr.Call{name: "int42gt", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(int42le(var1, var2)) do + %Sonata.Expr.Call{name: "int42le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(int42lt(var1, var2)) do + %Sonata.Expr.Call{name: "int42lt", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(int42mi(var1, var2)) do + %Sonata.Expr.Call{name: "int42mi", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(int42mul(var1, var2)) do + %Sonata.Expr.Call{name: "int42mul", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(int42ne(var1, var2)) do + %Sonata.Expr.Call{name: "int42ne", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(int42pl(var1, var2)) do + %Sonata.Expr.Call{name: "int42pl", arguments: [var1, var2]} + end + @doc("implementation of / operator") + def(int48div(var1, var2)) do + %Sonata.Expr.Call{name: "int48div", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(int48eq(var1, var2)) do + %Sonata.Expr.Call{name: "int48eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(int48ge(var1, var2)) do + %Sonata.Expr.Call{name: "int48ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(int48gt(var1, var2)) do + %Sonata.Expr.Call{name: "int48gt", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(int48le(var1, var2)) do + %Sonata.Expr.Call{name: "int48le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(int48lt(var1, var2)) do + %Sonata.Expr.Call{name: "int48lt", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(int48mi(var1, var2)) do + %Sonata.Expr.Call{name: "int48mi", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(int48mul(var1, var2)) do + %Sonata.Expr.Call{name: "int48mul", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(int48ne(var1, var2)) do + %Sonata.Expr.Call{name: "int48ne", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(int48pl(var1, var2)) do + %Sonata.Expr.Call{name: "int48pl", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(int4_accum(var1, var2)) do + %Sonata.Expr.Call{name: "int4_accum", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(int4_accum_inv(var1, var2)) do + %Sonata.Expr.Call{name: "int4_accum_inv", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(int4_avg_accum(var1, var2)) do + %Sonata.Expr.Call{name: "int4_avg_accum", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(int4_avg_accum_inv(var1, var2)) do + %Sonata.Expr.Call{name: "int4_avg_accum_inv", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(int4_mul_cash(var1, var2)) do + %Sonata.Expr.Call{name: "int4_mul_cash", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(int4_sum(var1, var2)) do + %Sonata.Expr.Call{name: "int4_sum", arguments: [var1, var2]} + end + @doc("implementation of @ operator") + def(int4abs(var1)) do + %Sonata.Expr.Call{name: "int4abs", arguments: [var1]} + end + @doc("implementation of & operator") + def(int4and(var1, var2)) do + %Sonata.Expr.Call{name: "int4and", arguments: [var1, var2]} + end + @doc("implementation of / operator") + def(int4div(var1, var2)) do + %Sonata.Expr.Call{name: "int4div", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(int4eq(var1, var2)) do + %Sonata.Expr.Call{name: "int4eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(int4ge(var1, var2)) do + %Sonata.Expr.Call{name: "int4ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(int4gt(var1, var2)) do + %Sonata.Expr.Call{name: "int4gt", arguments: [var1, var2]} + end + @doc("I/O") + def(int4in(var1)) do + %Sonata.Expr.Call{name: "int4in", arguments: [var1]} + end + @doc("increment") + def(int4inc(var1)) do + %Sonata.Expr.Call{name: "int4inc", arguments: [var1]} + end + @doc("larger of two") + def(int4larger(var1, var2)) do + %Sonata.Expr.Call{name: "int4larger", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(int4le(var1, var2)) do + %Sonata.Expr.Call{name: "int4le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(int4lt(var1, var2)) do + %Sonata.Expr.Call{name: "int4lt", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(int4mi(var1, var2)) do + %Sonata.Expr.Call{name: "int4mi", arguments: [var1, var2]} + end + @doc("implementation of % operator") + def(int4mod(var1, var2)) do + %Sonata.Expr.Call{name: "int4mod", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(int4mul(var1, var2)) do + %Sonata.Expr.Call{name: "int4mul", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(int4ne(var1, var2)) do + %Sonata.Expr.Call{name: "int4ne", arguments: [var1, var2]} + end + @doc("implementation of ~ operator") + def(int4not(var1)) do + %Sonata.Expr.Call{name: "int4not", arguments: [var1]} + end + @doc("implementation of | operator") + def(int4or(var1, var2)) do + %Sonata.Expr.Call{name: "int4or", arguments: [var1, var2]} + end + @doc("I/O") + def(int4out(var1)) do + %Sonata.Expr.Call{name: "int4out", arguments: [var1]} + end + @doc("implementation of + operator") + def(int4pl(var1, var2)) do + %Sonata.Expr.Call{name: "int4pl", arguments: [var1, var2]} + end + @doc("int4range constructor") + def(int4range(var1, var2)) do + %Sonata.Expr.Call{name: "int4range", arguments: [var1, var2]} + end + @doc("convert an int4 range to canonical form") + def(int4range_canonical(var1)) do + %Sonata.Expr.Call{name: "int4range_canonical", arguments: [var1]} + end + @doc("float8 difference of two int4 values") + def(int4range_subdiff(var1, var2)) do + %Sonata.Expr.Call{name: "int4range_subdiff", arguments: [var1, var2]} + end + @doc("I/O") + def(int4recv(var1)) do + %Sonata.Expr.Call{name: "int4recv", arguments: [var1]} + end + @doc("I/O") + def(int4send(var1)) do + %Sonata.Expr.Call{name: "int4send", arguments: [var1]} + end + @doc("implementation of << operator") + def(int4shl(var1, var2)) do + %Sonata.Expr.Call{name: "int4shl", arguments: [var1, var2]} + end + @doc("implementation of >> operator") + def(int4shr(var1, var2)) do + %Sonata.Expr.Call{name: "int4shr", arguments: [var1, var2]} + end + @doc("smaller of two") + def(int4smaller(var1, var2)) do + %Sonata.Expr.Call{name: "int4smaller", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(int4um(var1)) do + %Sonata.Expr.Call{name: "int4um", arguments: [var1]} + end + @doc("implementation of + operator") + def(int4up(var1)) do + %Sonata.Expr.Call{name: "int4up", arguments: [var1]} + end + @doc("implementation of # operator") + def(int4xor(var1, var2)) do + %Sonata.Expr.Call{name: "int4xor", arguments: [var1, var2]} + end + @doc("convert numeric to int8") + def(int8(var1)) do + %Sonata.Expr.Call{name: "int8", arguments: [var1]} + end + @doc("implementation of / operator") + def(int82div(var1, var2)) do + %Sonata.Expr.Call{name: "int82div", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(int82eq(var1, var2)) do + %Sonata.Expr.Call{name: "int82eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(int82ge(var1, var2)) do + %Sonata.Expr.Call{name: "int82ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(int82gt(var1, var2)) do + %Sonata.Expr.Call{name: "int82gt", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(int82le(var1, var2)) do + %Sonata.Expr.Call{name: "int82le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(int82lt(var1, var2)) do + %Sonata.Expr.Call{name: "int82lt", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(int82mi(var1, var2)) do + %Sonata.Expr.Call{name: "int82mi", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(int82mul(var1, var2)) do + %Sonata.Expr.Call{name: "int82mul", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(int82ne(var1, var2)) do + %Sonata.Expr.Call{name: "int82ne", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(int82pl(var1, var2)) do + %Sonata.Expr.Call{name: "int82pl", arguments: [var1, var2]} + end + @doc("implementation of / operator") + def(int84div(var1, var2)) do + %Sonata.Expr.Call{name: "int84div", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(int84eq(var1, var2)) do + %Sonata.Expr.Call{name: "int84eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(int84ge(var1, var2)) do + %Sonata.Expr.Call{name: "int84ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(int84gt(var1, var2)) do + %Sonata.Expr.Call{name: "int84gt", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(int84le(var1, var2)) do + %Sonata.Expr.Call{name: "int84le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(int84lt(var1, var2)) do + %Sonata.Expr.Call{name: "int84lt", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(int84mi(var1, var2)) do + %Sonata.Expr.Call{name: "int84mi", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(int84mul(var1, var2)) do + %Sonata.Expr.Call{name: "int84mul", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(int84ne(var1, var2)) do + %Sonata.Expr.Call{name: "int84ne", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(int84pl(var1, var2)) do + %Sonata.Expr.Call{name: "int84pl", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(int8_accum(var1, var2)) do + %Sonata.Expr.Call{name: "int8_accum", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(int8_accum_inv(var1, var2)) do + %Sonata.Expr.Call{name: "int8_accum_inv", arguments: [var1, var2]} + end + @doc("aggregate final function") + def(int8_avg(var1)) do + %Sonata.Expr.Call{name: "int8_avg", arguments: [var1]} + end + @doc("aggregate transition function") + def(int8_avg_accum(var1, var2)) do + %Sonata.Expr.Call{name: "int8_avg_accum", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(int8_avg_accum_inv(var1, var2)) do + %Sonata.Expr.Call{name: "int8_avg_accum_inv", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(int8_sum(var1, var2)) do + %Sonata.Expr.Call{name: "int8_sum", arguments: [var1, var2]} + end + @doc("implementation of @ operator") + def(int8abs(var1)) do + %Sonata.Expr.Call{name: "int8abs", arguments: [var1]} + end + @doc("implementation of & operator") + def(int8and(var1, var2)) do + %Sonata.Expr.Call{name: "int8and", arguments: [var1, var2]} + end + @doc("decrement") + def(int8dec(var1)) do + %Sonata.Expr.Call{name: "int8dec", arguments: [var1]} + end + @doc("decrement, ignores second argument") + def(int8dec_any(var1, var2)) do + %Sonata.Expr.Call{name: "int8dec_any", arguments: [var1, var2]} + end + @doc("implementation of / operator") + def(int8div(var1, var2)) do + %Sonata.Expr.Call{name: "int8div", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(int8eq(var1, var2)) do + %Sonata.Expr.Call{name: "int8eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(int8ge(var1, var2)) do + %Sonata.Expr.Call{name: "int8ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(int8gt(var1, var2)) do + %Sonata.Expr.Call{name: "int8gt", arguments: [var1, var2]} + end + @doc("I/O") + def(int8in(var1)) do + %Sonata.Expr.Call{name: "int8in", arguments: [var1]} + end + @doc("increment") + def(int8inc(var1)) do + %Sonata.Expr.Call{name: "int8inc", arguments: [var1]} + end + @doc("increment, ignores second argument") + def(int8inc_any(var1, var2)) do + %Sonata.Expr.Call{name: "int8inc_any", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(int8inc_float8_float8(var1, var2, var3)) do + %Sonata.Expr.Call{name: "int8inc_float8_float8", arguments: [var1, var2, var3]} + end + @doc("larger of two") + def(int8larger(var1, var2)) do + %Sonata.Expr.Call{name: "int8larger", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(int8le(var1, var2)) do + %Sonata.Expr.Call{name: "int8le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(int8lt(var1, var2)) do + %Sonata.Expr.Call{name: "int8lt", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(int8mi(var1, var2)) do + %Sonata.Expr.Call{name: "int8mi", arguments: [var1, var2]} + end + @doc("implementation of % operator") + def(int8mod(var1, var2)) do + %Sonata.Expr.Call{name: "int8mod", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(int8mul(var1, var2)) do + %Sonata.Expr.Call{name: "int8mul", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(int8ne(var1, var2)) do + %Sonata.Expr.Call{name: "int8ne", arguments: [var1, var2]} + end + @doc("implementation of ~ operator") + def(int8not(var1)) do + %Sonata.Expr.Call{name: "int8not", arguments: [var1]} + end + @doc("implementation of | operator") + def(int8or(var1, var2)) do + %Sonata.Expr.Call{name: "int8or", arguments: [var1, var2]} + end + @doc("I/O") + def(int8out(var1)) do + %Sonata.Expr.Call{name: "int8out", arguments: [var1]} + end + @doc("implementation of + operator") + def(int8pl(var1, var2)) do + %Sonata.Expr.Call{name: "int8pl", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(int8pl_inet(var1, var2)) do + %Sonata.Expr.Call{name: "int8pl_inet", arguments: [var1, var2]} + end + @doc("int8range constructor") + def(int8range(var1, var2)) do + %Sonata.Expr.Call{name: "int8range", arguments: [var1, var2]} + end + @doc("convert an int8 range to canonical form") + def(int8range_canonical(var1)) do + %Sonata.Expr.Call{name: "int8range_canonical", arguments: [var1]} + end + @doc("float8 difference of two int8 values") + def(int8range_subdiff(var1, var2)) do + %Sonata.Expr.Call{name: "int8range_subdiff", arguments: [var1, var2]} + end + @doc("I/O") + def(int8recv(var1)) do + %Sonata.Expr.Call{name: "int8recv", arguments: [var1]} + end + @doc("I/O") + def(int8send(var1)) do + %Sonata.Expr.Call{name: "int8send", arguments: [var1]} + end + @doc("implementation of << operator") + def(int8shl(var1, var2)) do + %Sonata.Expr.Call{name: "int8shl", arguments: [var1, var2]} + end + @doc("implementation of >> operator") + def(int8shr(var1, var2)) do + %Sonata.Expr.Call{name: "int8shr", arguments: [var1, var2]} + end + @doc("smaller of two") + def(int8smaller(var1, var2)) do + %Sonata.Expr.Call{name: "int8smaller", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(int8um(var1)) do + %Sonata.Expr.Call{name: "int8um", arguments: [var1]} + end + @doc("implementation of + operator") + def(int8up(var1)) do + %Sonata.Expr.Call{name: "int8up", arguments: [var1]} + end + @doc("implementation of # operator") + def(int8xor(var1, var2)) do + %Sonata.Expr.Call{name: "int8xor", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(integer_pl_date(var1, var2)) do + %Sonata.Expr.Call{name: "integer_pl_date", arguments: [var1, var2]} + end + @doc("implementation of ?# operator") + def(inter_lb(var1, var2)) do + %Sonata.Expr.Call{name: "inter_lb", arguments: [var1, var2]} + end + @doc("implementation of ?# operator") + def(inter_sb(var1, var2)) do + %Sonata.Expr.Call{name: "inter_sb", arguments: [var1, var2]} + end + @doc("implementation of ?# operator") + def(inter_sl(var1, var2)) do + %Sonata.Expr.Call{name: "inter_sl", arguments: [var1, var2]} + end + @doc("I/O") + def(internal_in(var1)) do + %Sonata.Expr.Call{name: "internal_in", arguments: [var1]} + end + @doc("I/O") + def(internal_out(var1)) do + %Sonata.Expr.Call{name: "internal_out", arguments: [var1]} + end + @doc("convert reltime to interval") + def(interval(var1)) do + %Sonata.Expr.Call{name: "interval", arguments: [var1]} + end + @doc("aggregate transition function") + def(interval_accum(var1, var2)) do + %Sonata.Expr.Call{name: "interval_accum", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(interval_accum_inv(var1, var2)) do + %Sonata.Expr.Call{name: "interval_accum_inv", arguments: [var1, var2]} + end + @doc("aggregate final function") + def(interval_avg(var1)) do + %Sonata.Expr.Call{name: "interval_avg", arguments: [var1]} + end + @doc("less-equal-greater") + def(interval_cmp(var1, var2)) do + %Sonata.Expr.Call{name: "interval_cmp", arguments: [var1, var2]} + end + @doc("implementation of / operator") + def(interval_div(var1, var2)) do + %Sonata.Expr.Call{name: "interval_div", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(interval_eq(var1, var2)) do + %Sonata.Expr.Call{name: "interval_eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(interval_ge(var1, var2)) do + %Sonata.Expr.Call{name: "interval_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(interval_gt(var1, var2)) do + %Sonata.Expr.Call{name: "interval_gt", arguments: [var1, var2]} + end + @doc("hash") + def(interval_hash(var1)) do + %Sonata.Expr.Call{name: "interval_hash", arguments: [var1]} + end + @doc("I/O") + def(interval_in(var1, var2, var3)) do + %Sonata.Expr.Call{name: "interval_in", arguments: [var1, var2, var3]} + end + @doc("larger of two") + def(interval_larger(var1, var2)) do + %Sonata.Expr.Call{name: "interval_larger", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(interval_le(var1, var2)) do + %Sonata.Expr.Call{name: "interval_le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(interval_lt(var1, var2)) do + %Sonata.Expr.Call{name: "interval_lt", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(interval_mi(var1, var2)) do + %Sonata.Expr.Call{name: "interval_mi", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(interval_mul(var1, var2)) do + %Sonata.Expr.Call{name: "interval_mul", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(interval_ne(var1, var2)) do + %Sonata.Expr.Call{name: "interval_ne", arguments: [var1, var2]} + end + @doc("I/O") + def(interval_out(var1)) do + %Sonata.Expr.Call{name: "interval_out", arguments: [var1]} + end + @doc("implementation of + operator") + def(interval_pl(var1, var2)) do + %Sonata.Expr.Call{name: "interval_pl", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(interval_pl_date(var1, var2)) do + %Sonata.Expr.Call{name: "interval_pl_date", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(interval_pl_time(var1, var2)) do + %Sonata.Expr.Call{name: "interval_pl_time", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(interval_pl_timestamp(var1, var2)) do + %Sonata.Expr.Call{name: "interval_pl_timestamp", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(interval_pl_timestamptz(var1, var2)) do + %Sonata.Expr.Call{name: "interval_pl_timestamptz", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(interval_pl_timetz(var1, var2)) do + %Sonata.Expr.Call{name: "interval_pl_timetz", arguments: [var1, var2]} + end + @doc("I/O") + def(interval_recv(var1, var2, var3)) do + %Sonata.Expr.Call{name: "interval_recv", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(interval_send(var1)) do + %Sonata.Expr.Call{name: "interval_send", arguments: [var1]} + end + @doc("smaller of two") + def(interval_smaller(var1, var2)) do + %Sonata.Expr.Call{name: "interval_smaller", arguments: [var1, var2]} + end + @doc("transform an interval length coercion") + def(interval_transform(var1)) do + %Sonata.Expr.Call{name: "interval_transform", arguments: [var1]} + end + @doc("implementation of - operator") + def(interval_um(var1)) do + %Sonata.Expr.Call{name: "interval_um", arguments: [var1]} + end + @doc("I/O typmod") + def(intervaltypmodin(var1)) do + %Sonata.Expr.Call{name: "intervaltypmodin", arguments: [var1]} + end + @doc("I/O typmod") + def(intervaltypmodout(var1)) do + %Sonata.Expr.Call{name: "intervaltypmodout", arguments: [var1]} + end + @doc("implementation of operator") + def(intinterval(var1, var2)) do + %Sonata.Expr.Call{name: "intinterval", arguments: [var1, var2]} + end + @doc("path closed?") + def(isclosed(var1)) do + %Sonata.Expr.Call{name: "isclosed", arguments: [var1]} + end + @doc("is the range empty?") + def(isempty(var1)) do + %Sonata.Expr.Call{name: "isempty", arguments: [var1]} + end + @doc("finite timestamp?") + def(isfinite(var1)) do + %Sonata.Expr.Call{name: "isfinite", arguments: [var1]} + end + @doc("horizontally aligned") + def(ishorizontal(var1, var2)) do + %Sonata.Expr.Call{name: "ishorizontal", arguments: [var1, var2]} + end + @doc("internal conversion function for LATIN1 to UTF8") + def(iso8859_1_to_utf8(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "iso8859_1_to_utf8", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for ISO-8859-8 to UTF8") + def(iso8859_to_utf8(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "iso8859_to_utf8", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for ISO-8859-5 to KOI8R") + def(iso_to_koi8r(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "iso_to_koi8r", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for ISO-8859-5 to MULE_INTERNAL") + def(iso_to_mic(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "iso_to_mic", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for ISO-8859-5 to WIN1251") + def(iso_to_win1251(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "iso_to_win1251", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for ISO-8859-5 to WIN866") + def(iso_to_win866(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "iso_to_win866", arguments: [var1, var2, var3, var4, var5]} + end + @doc("path open?") + def(isopen(var1)) do + %Sonata.Expr.Call{name: "isopen", arguments: [var1]} + end + @doc("parallel") + def(isparallel(var1, var2)) do + %Sonata.Expr.Call{name: "isparallel", arguments: [var1, var2]} + end + @doc("perpendicular") + def(isperp(var1, var2)) do + %Sonata.Expr.Call{name: "isperp", arguments: [var1, var2]} + end + @doc("vertically aligned") + def(isvertical(var1, var2)) do + %Sonata.Expr.Call{name: "isvertical", arguments: [var1, var2]} + end + @doc("internal conversion function for JOHAB to UTF8") + def(johab_to_utf8(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "johab_to_utf8", arguments: [var1, var2, var3, var4, var5]} + end + @doc("aggregate input into json") + def(json_agg(var1)) do + %Sonata.Expr.Call{name: "json_agg", arguments: [var1]} + end + @doc("json aggregate final function") + def(json_agg_finalfn(var1)) do + %Sonata.Expr.Call{name: "json_agg_finalfn", arguments: [var1]} + end + @doc("json aggregate transition function") + def(json_agg_transfn(var1, var2)) do + %Sonata.Expr.Call{name: "json_agg_transfn", arguments: [var1, var2]} + end + @doc("implementation of -> operator") + def(json_array_element(var1, var2)) do + %Sonata.Expr.Call{name: "json_array_element", arguments: [var1, var2]} + end + @doc("implementation of ->> operator") + def(json_array_element_text(var1, var2)) do + %Sonata.Expr.Call{name: "json_array_element_text", arguments: [var1, var2]} + end + @doc("key value pairs of a json object") + def(json_array_elements(var1)) do + %Sonata.Expr.Call{name: "json_array_elements", arguments: [var1]} + end + @doc("elements of json array") + def(json_array_elements_text(var1)) do + %Sonata.Expr.Call{name: "json_array_elements_text", arguments: [var1]} + end + @doc("length of json array") + def(json_array_length(var1)) do + %Sonata.Expr.Call{name: "json_array_length", arguments: [var1]} + end + @doc("build an empty json array") + def(json_build_array()) do + %Sonata.Expr.Call{name: "json_build_array", arguments: []} + end + @doc("build an empty json object") + def(json_build_object()) do + %Sonata.Expr.Call{name: "json_build_object", arguments: []} + end + @doc("key value pairs of a json object") + def(json_each(var1)) do + %Sonata.Expr.Call{name: "json_each", arguments: [var1]} + end + @doc("key value pairs of a json object") + def(json_each_text(var1)) do + %Sonata.Expr.Call{name: "json_each_text", arguments: [var1]} + end + @doc("get value from json with path elements") + def(json_extract_path(var1, var2)) do + %Sonata.Expr.Call{name: "json_extract_path", arguments: [var1, var2]} + end + @doc("get value from json as text with path elements") + def(json_extract_path_text(var1, var2)) do + %Sonata.Expr.Call{name: "json_extract_path_text", arguments: [var1, var2]} + end + @doc("I/O") + def(json_in(var1)) do + %Sonata.Expr.Call{name: "json_in", arguments: [var1]} + end + @doc("map text array of key value pairs to json object") + def(json_object(var1)) do + %Sonata.Expr.Call{name: "json_object", arguments: [var1]} + end + @doc("aggregate input into a json object") + def(json_object_agg(var1, var2)) do + %Sonata.Expr.Call{name: "json_object_agg", arguments: [var1, var2]} + end + @doc("json object aggregate final function") + def(json_object_agg_finalfn(var1)) do + %Sonata.Expr.Call{name: "json_object_agg_finalfn", arguments: [var1]} + end + @doc("json object aggregate transition function") + def(json_object_agg_transfn(var1, var2, var3)) do + %Sonata.Expr.Call{name: "json_object_agg_transfn", arguments: [var1, var2, var3]} + end + @doc("implementation of -> operator") + def(json_object_field(var1, var2)) do + %Sonata.Expr.Call{name: "json_object_field", arguments: [var1, var2]} + end + @doc("implementation of ->> operator") + def(json_object_field_text(var1, var2)) do + %Sonata.Expr.Call{name: "json_object_field_text", arguments: [var1, var2]} + end + @doc("get json object keys") + def(json_object_keys(var1)) do + %Sonata.Expr.Call{name: "json_object_keys", arguments: [var1]} + end + @doc("I/O") + def(json_out(var1)) do + %Sonata.Expr.Call{name: "json_out", arguments: [var1]} + end + @doc("get record fields from a json object") + def(json_populate_record(var1, var2, var3)) do + %Sonata.Expr.Call{name: "json_populate_record", arguments: [var1, var2, var3]} + end + @doc("get set of records with fields from a json array of objects") + def(json_populate_recordset(var1, var2, var3)) do + %Sonata.Expr.Call{name: "json_populate_recordset", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(json_recv(var1)) do + %Sonata.Expr.Call{name: "json_recv", arguments: [var1]} + end + @doc("I/O") + def(json_send(var1)) do + %Sonata.Expr.Call{name: "json_send", arguments: [var1]} + end + @doc("remove object fields with null values from json") + def(json_strip_nulls(var1)) do + %Sonata.Expr.Call{name: "json_strip_nulls", arguments: [var1]} + end + @doc("get record fields from a json object") + def(json_to_record(var1)) do + %Sonata.Expr.Call{name: "json_to_record", arguments: [var1]} + end + @doc("get set of records with fields from a json array of objects") + def(json_to_recordset(var1)) do + %Sonata.Expr.Call{name: "json_to_recordset", arguments: [var1]} + end + @doc("get the type of a json value") + def(json_typeof(var1)) do + %Sonata.Expr.Call{name: "json_typeof", arguments: [var1]} + end + @doc("aggregate input into jsonb") + def(jsonb_agg(var1)) do + %Sonata.Expr.Call{name: "jsonb_agg", arguments: [var1]} + end + @doc("jsonb aggregate final function") + def(jsonb_agg_finalfn(var1)) do + %Sonata.Expr.Call{name: "jsonb_agg_finalfn", arguments: [var1]} + end + @doc("jsonb aggregate transition function") + def(jsonb_agg_transfn(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_agg_transfn", arguments: [var1, var2]} + end + @doc("implementation of -> operator") + def(jsonb_array_element(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_array_element", arguments: [var1, var2]} + end + @doc("implementation of ->> operator") + def(jsonb_array_element_text(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_array_element_text", arguments: [var1, var2]} + end + @doc("elements of a jsonb array") + def(jsonb_array_elements(var1)) do + %Sonata.Expr.Call{name: "jsonb_array_elements", arguments: [var1]} + end + @doc("elements of jsonb array") + def(jsonb_array_elements_text(var1)) do + %Sonata.Expr.Call{name: "jsonb_array_elements_text", arguments: [var1]} + end + @doc("length of jsonb array") + def(jsonb_array_length(var1)) do + %Sonata.Expr.Call{name: "jsonb_array_length", arguments: [var1]} + end + @doc("build an empty jsonb array") + def(jsonb_build_array()) do + %Sonata.Expr.Call{name: "jsonb_build_array", arguments: []} + end + @doc("build a jsonb object from pairwise key/value inputs") + def(jsonb_build_object(var1)) do + %Sonata.Expr.Call{name: "jsonb_build_object", arguments: [var1]} + end + @doc("less-equal-greater") + def(jsonb_cmp(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_cmp", arguments: [var1, var2]} + end + @doc("implementation of || operator") + def(jsonb_concat(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_concat", arguments: [var1, var2]} + end + @doc("implementation of <@ operator") + def(jsonb_contained(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_contained", arguments: [var1, var2]} + end + @doc("implementation of @> operator") + def(jsonb_contains(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_contains", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(jsonb_delete(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_delete", arguments: [var1, var2]} + end + @doc("implementation of #- operator") + def(jsonb_delete_path(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_delete_path", arguments: [var1, var2]} + end + @doc("key value pairs of a jsonb object") + def(jsonb_each(var1)) do + %Sonata.Expr.Call{name: "jsonb_each", arguments: [var1]} + end + @doc("key value pairs of a jsonb object") + def(jsonb_each_text(var1)) do + %Sonata.Expr.Call{name: "jsonb_each_text", arguments: [var1]} + end + @doc("implementation of = operator") + def(jsonb_eq(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_eq", arguments: [var1, var2]} + end + @doc("implementation of ? operator") + def(jsonb_exists(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_exists", arguments: [var1, var2]} + end + @doc("implementation of ?& operator") + def(jsonb_exists_all(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_exists_all", arguments: [var1, var2]} + end + @doc("implementation of ?| operator") + def(jsonb_exists_any(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_exists_any", arguments: [var1, var2]} + end + @doc("get value from jsonb with path elements") + def(jsonb_extract_path(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_extract_path", arguments: [var1, var2]} + end + @doc("get value from jsonb as text with path elements") + def(jsonb_extract_path_text(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_extract_path_text", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(jsonb_ge(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(jsonb_gt(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_gt", arguments: [var1, var2]} + end + @doc("hash") + def(jsonb_hash(var1)) do + %Sonata.Expr.Call{name: "jsonb_hash", arguments: [var1]} + end + @doc("I/O") + def(jsonb_in(var1)) do + %Sonata.Expr.Call{name: "jsonb_in", arguments: [var1]} + end + @doc("implementation of <= operator") + def(jsonb_le(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(jsonb_lt(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_lt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(jsonb_ne(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_ne", arguments: [var1, var2]} + end + @doc("map text array of key value pairs to jsonb object") + def(jsonb_object(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_object", arguments: [var1, var2]} + end + @doc("aggregate inputs into jsonb object") + def(jsonb_object_agg(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_object_agg", arguments: [var1, var2]} + end + @doc("jsonb object aggregate final function") + def(jsonb_object_agg_finalfn(var1)) do + %Sonata.Expr.Call{name: "jsonb_object_agg_finalfn", arguments: [var1]} + end + @doc("jsonb object aggregate transition function") + def(jsonb_object_agg_transfn(var1, var2, var3)) do + %Sonata.Expr.Call{name: "jsonb_object_agg_transfn", arguments: [var1, var2, var3]} + end + @doc("implementation of -> operator") + def(jsonb_object_field(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_object_field", arguments: [var1, var2]} + end + @doc("implementation of ->> operator") + def(jsonb_object_field_text(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_object_field_text", arguments: [var1, var2]} + end + @doc("get jsonb object keys") + def(jsonb_object_keys(var1)) do + %Sonata.Expr.Call{name: "jsonb_object_keys", arguments: [var1]} + end + @doc("I/O") + def(jsonb_out(var1)) do + %Sonata.Expr.Call{name: "jsonb_out", arguments: [var1]} + end + @doc("get record fields from a jsonb object") + def(jsonb_populate_record(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_populate_record", arguments: [var1, var2]} + end + @doc("get set of records with fields from a jsonb array of objects") + def(jsonb_populate_recordset(var1, var2)) do + %Sonata.Expr.Call{name: "jsonb_populate_recordset", arguments: [var1, var2]} + end + @doc("Indented text from jsonb") + def(jsonb_pretty(var1)) do + %Sonata.Expr.Call{name: "jsonb_pretty", arguments: [var1]} + end + @doc("I/O") + def(jsonb_recv(var1)) do + %Sonata.Expr.Call{name: "jsonb_recv", arguments: [var1]} + end + @doc("I/O") + def(jsonb_send(var1)) do + %Sonata.Expr.Call{name: "jsonb_send", arguments: [var1]} + end + @doc("Set part of a jsonb") + def(jsonb_set(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "jsonb_set", arguments: [var1, var2, var3, var4]} + end + @doc("remove object fields with null values from jsonb") + def(jsonb_strip_nulls(var1)) do + %Sonata.Expr.Call{name: "jsonb_strip_nulls", arguments: [var1]} + end + @doc("get record fields from a jsonb object") + def(jsonb_to_record(var1)) do + %Sonata.Expr.Call{name: "jsonb_to_record", arguments: [var1]} + end + @doc("get set of records with fields from a jsonb array of objects") + def(jsonb_to_recordset(var1)) do + %Sonata.Expr.Call{name: "jsonb_to_recordset", arguments: [var1]} + end + @doc("get the type of a jsonb value") + def(jsonb_typeof(var1)) do + %Sonata.Expr.Call{name: "jsonb_typeof", arguments: [var1]} + end + @doc("promote groups of 30 days to numbers of months") + def(justify_days(var1)) do + %Sonata.Expr.Call{name: "justify_days", arguments: [var1]} + end + @doc("promote groups of 24 hours to numbers of days") + def(justify_hours(var1)) do + %Sonata.Expr.Call{name: "justify_hours", arguments: [var1]} + end + @doc("promote groups of 24 hours to numbers of days and promote groups of 30 days to numbers of months") + def(justify_interval(var1)) do + %Sonata.Expr.Call{name: "justify_interval", arguments: [var1]} + end + @doc("internal conversion function for KOI8R to ISO-8859-5") + def(koi8r_to_iso(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "koi8r_to_iso", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for KOI8R to MULE_INTERNAL") + def(koi8r_to_mic(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "koi8r_to_mic", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for KOI8R to UTF8") + def(koi8r_to_utf8(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "koi8r_to_utf8", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for KOI8R to WIN1251") + def(koi8r_to_win1251(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "koi8r_to_win1251", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for KOI8R to WIN866") + def(koi8r_to_win866(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "koi8r_to_win866", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for KOI8U to UTF8") + def(koi8u_to_utf8(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "koi8u_to_utf8", arguments: [var1, var2, var3, var4, var5]} + end + @doc("fetch the Nth preceding row value with default") + def(lag(var1, var2, var3)) do + %Sonata.Expr.Call{name: "lag", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(language_handler_in(var1)) do + %Sonata.Expr.Call{name: "language_handler_in", arguments: [var1]} + end + @doc("I/O") + def(language_handler_out(var1)) do + %Sonata.Expr.Call{name: "language_handler_out", arguments: [var1]} + end + @doc("fetch the last row value") + def(last_value(var1)) do + %Sonata.Expr.Call{name: "last_value", arguments: [var1]} + end + @doc("current value from last used sequence") + def(lastval()) do + %Sonata.Expr.Call{name: "lastval", arguments: []} + end + @doc("internal conversion function for LATIN1 to MULE_INTERNAL") + def(latin1_to_mic(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "latin1_to_mic", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for LATIN2 to MULE_INTERNAL") + def(latin2_to_mic(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "latin2_to_mic", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for LATIN2 to WIN1250") + def(latin2_to_win1250(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "latin2_to_win1250", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for LATIN3 to MULE_INTERNAL") + def(latin3_to_mic(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "latin3_to_mic", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for LATIN4 to MULE_INTERNAL") + def(latin4_to_mic(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "latin4_to_mic", arguments: [var1, var2, var3, var4, var5]} + end + @doc("fetch the Nth following row value") + def(lead(var1, var2)) do + %Sonata.Expr.Call{name: "lead", arguments: [var1, var2]} + end + @doc("extract the first n characters") + def(left(var1, var2)) do + %Sonata.Expr.Call{name: "left", arguments: [var1, var2]} + end + @doc("distance between endpoints") + def(length(var1)) do + %Sonata.Expr.Call{name: "length", arguments: [var1]} + end + @doc("matches LIKE expression") + def(like(var1, var2)) do + %Sonata.Expr.Call{name: "like", arguments: [var1, var2]} + end + @doc("convert LIKE pattern to use backslash escapes") + def(like_escape(var1, var2)) do + %Sonata.Expr.Call{name: "like_escape", arguments: [var1, var2]} + end + @doc("join selectivity of LIKE") + def(likejoinsel(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "likejoinsel", arguments: [var1, var2, var3, var4, var5]} + end + @doc("restriction selectivity of LIKE") + def(likesel(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "likesel", arguments: [var1, var2, var3, var4]} + end + @doc("construct line from points") + def(line(var1, var2)) do + %Sonata.Expr.Call{name: "line", arguments: [var1, var2]} + end + @doc("implementation of <-> operator") + def(line_distance(var1, var2)) do + %Sonata.Expr.Call{name: "line_distance", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(line_eq(var1, var2)) do + %Sonata.Expr.Call{name: "line_eq", arguments: [var1, var2]} + end + @doc("implementation of ?- operator") + def(line_horizontal(var1)) do + %Sonata.Expr.Call{name: "line_horizontal", arguments: [var1]} + end + @doc("I/O") + def(line_in(var1)) do + %Sonata.Expr.Call{name: "line_in", arguments: [var1]} + end + @doc("implementation of # operator") + def(line_interpt(var1, var2)) do + %Sonata.Expr.Call{name: "line_interpt", arguments: [var1, var2]} + end + @doc("implementation of ?# operator") + def(line_intersect(var1, var2)) do + %Sonata.Expr.Call{name: "line_intersect", arguments: [var1, var2]} + end + @doc("I/O") + def(line_out(var1)) do + %Sonata.Expr.Call{name: "line_out", arguments: [var1]} + end + @doc("implementation of ?|| operator") + def(line_parallel(var1, var2)) do + %Sonata.Expr.Call{name: "line_parallel", arguments: [var1, var2]} + end + @doc("implementation of ?-| operator") + def(line_perp(var1, var2)) do + %Sonata.Expr.Call{name: "line_perp", arguments: [var1, var2]} + end + @doc("I/O") + def(line_recv(var1)) do + %Sonata.Expr.Call{name: "line_recv", arguments: [var1]} + end + @doc("I/O") + def(line_send(var1)) do + %Sonata.Expr.Call{name: "line_send", arguments: [var1]} + end + @doc("implementation of ?| operator") + def(line_vertical(var1)) do + %Sonata.Expr.Call{name: "line_vertical", arguments: [var1]} + end + @doc("natural logarithm") + def(ln(var1)) do + %Sonata.Expr.Call{name: "ln", arguments: [var1]} + end + @doc("large object close") + def(lo_close(var1)) do + %Sonata.Expr.Call{name: "lo_close", arguments: [var1]} + end + @doc("large object create") + def(lo_creat(var1)) do + %Sonata.Expr.Call{name: "lo_creat", arguments: [var1]} + end + @doc("large object create") + def(lo_create(var1)) do + %Sonata.Expr.Call{name: "lo_create", arguments: [var1]} + end + @doc("large object export") + def(lo_export(var1, var2)) do + %Sonata.Expr.Call{name: "lo_export", arguments: [var1, var2]} + end + @doc("create new large object with given content") + def(lo_from_bytea(var1, var2)) do + %Sonata.Expr.Call{name: "lo_from_bytea", arguments: [var1, var2]} + end + @doc("read entire large object") + def(lo_get(var1)) do + %Sonata.Expr.Call{name: "lo_get", arguments: [var1]} + end + @doc("large object import") + def(lo_import(var1)) do + %Sonata.Expr.Call{name: "lo_import", arguments: [var1]} + end + @doc("large object seek") + def(lo_lseek(var1, var2, var3)) do + %Sonata.Expr.Call{name: "lo_lseek", arguments: [var1, var2, var3]} + end + @doc("large object seek (64 bit)") + def(lo_lseek64(var1, var2, var3)) do + %Sonata.Expr.Call{name: "lo_lseek64", arguments: [var1, var2, var3]} + end + @doc("large object open") + def(lo_open(var1, var2)) do + %Sonata.Expr.Call{name: "lo_open", arguments: [var1, var2]} + end + @doc("write data at offset") + def(lo_put(var1, var2, var3)) do + %Sonata.Expr.Call{name: "lo_put", arguments: [var1, var2, var3]} + end + @doc("large object position") + def(lo_tell(var1)) do + %Sonata.Expr.Call{name: "lo_tell", arguments: [var1]} + end + @doc("large object position (64 bit)") + def(lo_tell64(var1)) do + %Sonata.Expr.Call{name: "lo_tell64", arguments: [var1]} + end + @doc("truncate large object") + def(lo_truncate(var1, var2)) do + %Sonata.Expr.Call{name: "lo_truncate", arguments: [var1, var2]} + end + @doc("truncate large object (64 bit)") + def(lo_truncate64(var1, var2)) do + %Sonata.Expr.Call{name: "lo_truncate64", arguments: [var1, var2]} + end + @doc("large object unlink (delete)") + def(lo_unlink(var1)) do + %Sonata.Expr.Call{name: "lo_unlink", arguments: [var1]} + end + @doc("base 10 logarithm") + def(log(var1)) do + %Sonata.Expr.Call{name: "log", arguments: [var1]} + end + @doc("large object read") + def(loread(var1, var2)) do + %Sonata.Expr.Call{name: "loread", arguments: [var1, var2]} + end + @doc("lowercase") + def(lower(var1)) do + %Sonata.Expr.Call{name: "lower", arguments: [var1]} + end + @doc("is the range's lower bound inclusive?") + def(lower_inc(var1)) do + %Sonata.Expr.Call{name: "lower_inc", arguments: [var1]} + end + @doc("is the range's lower bound infinite?") + def(lower_inf(var1)) do + %Sonata.Expr.Call{name: "lower_inf", arguments: [var1]} + end + @doc("large object write") + def(lowrite(var1, var2)) do + %Sonata.Expr.Call{name: "lowrite", arguments: [var1, var2]} + end + @doc("left-pad string to length") + def(lpad(var1, var2, var3)) do + %Sonata.Expr.Call{name: "lpad", arguments: [var1, var2, var3]} + end + @doc("diagonal of") + def(lseg(var1)) do + %Sonata.Expr.Call{name: "lseg", arguments: [var1]} + end + @doc("implementation of @@ operator") + def(lseg_center(var1)) do + %Sonata.Expr.Call{name: "lseg_center", arguments: [var1]} + end + @doc("implementation of <-> operator") + def(lseg_distance(var1, var2)) do + %Sonata.Expr.Call{name: "lseg_distance", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(lseg_eq(var1, var2)) do + %Sonata.Expr.Call{name: "lseg_eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(lseg_ge(var1, var2)) do + %Sonata.Expr.Call{name: "lseg_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(lseg_gt(var1, var2)) do + %Sonata.Expr.Call{name: "lseg_gt", arguments: [var1, var2]} + end + @doc("implementation of ?- operator") + def(lseg_horizontal(var1)) do + %Sonata.Expr.Call{name: "lseg_horizontal", arguments: [var1]} + end + @doc("I/O") + def(lseg_in(var1)) do + %Sonata.Expr.Call{name: "lseg_in", arguments: [var1]} + end + @doc("implementation of # operator") + def(lseg_interpt(var1, var2)) do + %Sonata.Expr.Call{name: "lseg_interpt", arguments: [var1, var2]} + end + @doc("implementation of ?# operator") + def(lseg_intersect(var1, var2)) do + %Sonata.Expr.Call{name: "lseg_intersect", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(lseg_le(var1, var2)) do + %Sonata.Expr.Call{name: "lseg_le", arguments: [var1, var2]} + end + @doc("implementation of @-@ operator") + def(lseg_length(var1)) do + %Sonata.Expr.Call{name: "lseg_length", arguments: [var1]} + end + @doc("implementation of < operator") + def(lseg_lt(var1, var2)) do + %Sonata.Expr.Call{name: "lseg_lt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(lseg_ne(var1, var2)) do + %Sonata.Expr.Call{name: "lseg_ne", arguments: [var1, var2]} + end + @doc("I/O") + def(lseg_out(var1)) do + %Sonata.Expr.Call{name: "lseg_out", arguments: [var1]} + end + @doc("implementation of ?|| operator") + def(lseg_parallel(var1, var2)) do + %Sonata.Expr.Call{name: "lseg_parallel", arguments: [var1, var2]} + end + @doc("implementation of ?-| operator") + def(lseg_perp(var1, var2)) do + %Sonata.Expr.Call{name: "lseg_perp", arguments: [var1, var2]} + end + @doc("I/O") + def(lseg_recv(var1)) do + %Sonata.Expr.Call{name: "lseg_recv", arguments: [var1]} + end + @doc("I/O") + def(lseg_send(var1)) do + %Sonata.Expr.Call{name: "lseg_send", arguments: [var1]} + end + @doc("implementation of ?| operator") + def(lseg_vertical(var1)) do + %Sonata.Expr.Call{name: "lseg_vertical", arguments: [var1]} + end + @doc("trim selected characters from left end of string") + def(ltrim(var1, var2)) do + %Sonata.Expr.Call{name: "ltrim", arguments: [var1, var2]} + end + @doc("implementation of & operator") + def(macaddr_and(var1, var2)) do + %Sonata.Expr.Call{name: "macaddr_and", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(macaddr_cmp(var1, var2)) do + %Sonata.Expr.Call{name: "macaddr_cmp", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(macaddr_eq(var1, var2)) do + %Sonata.Expr.Call{name: "macaddr_eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(macaddr_ge(var1, var2)) do + %Sonata.Expr.Call{name: "macaddr_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(macaddr_gt(var1, var2)) do + %Sonata.Expr.Call{name: "macaddr_gt", arguments: [var1, var2]} + end + @doc("I/O") + def(macaddr_in(var1)) do + %Sonata.Expr.Call{name: "macaddr_in", arguments: [var1]} + end + @doc("implementation of <= operator") + def(macaddr_le(var1, var2)) do + %Sonata.Expr.Call{name: "macaddr_le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(macaddr_lt(var1, var2)) do + %Sonata.Expr.Call{name: "macaddr_lt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(macaddr_ne(var1, var2)) do + %Sonata.Expr.Call{name: "macaddr_ne", arguments: [var1, var2]} + end + @doc("implementation of ~ operator") + def(macaddr_not(var1)) do + %Sonata.Expr.Call{name: "macaddr_not", arguments: [var1]} + end + @doc("implementation of | operator") + def(macaddr_or(var1, var2)) do + %Sonata.Expr.Call{name: "macaddr_or", arguments: [var1, var2]} + end + @doc("I/O") + def(macaddr_out(var1)) do + %Sonata.Expr.Call{name: "macaddr_out", arguments: [var1]} + end + @doc("I/O") + def(macaddr_recv(var1)) do + %Sonata.Expr.Call{name: "macaddr_recv", arguments: [var1]} + end + @doc("I/O") + def(macaddr_send(var1)) do + %Sonata.Expr.Call{name: "macaddr_send", arguments: [var1]} + end + @doc("construct date") + def(make_date(var1, var2, var3)) do + %Sonata.Expr.Call{name: "make_date", arguments: [var1, var2, var3]} + end + @doc("construct interval") + def(make_interval(var1, var2, var3, var4, var5, var6, var7)) do + %Sonata.Expr.Call{name: "make_interval", arguments: [var1, var2, var3, var4, var5, var6, var7]} + end + @doc("construct time") + def(make_time(var1, var2, var3)) do + %Sonata.Expr.Call{name: "make_time", arguments: [var1, var2, var3]} + end + @doc("construct timestamp") + def(make_timestamp(var1, var2, var3, var4, var5, var6)) do + %Sonata.Expr.Call{name: "make_timestamp", arguments: [var1, var2, var3, var4, var5, var6]} + end + @doc("construct timestamp with time zone") + def(make_timestamptz(var1, var2, var3, var4, var5, var6)) do + %Sonata.Expr.Call{name: "make_timestamptz", arguments: [var1, var2, var3, var4, var5, var6]} + end + @doc("make ACL item") + def(makeaclitem(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "makeaclitem", arguments: [var1, var2, var3, var4]} + end + @doc("netmask length") + def(masklen(var1)) do + %Sonata.Expr.Call{name: "masklen", arguments: [var1]} + end + @doc("maximum value of all money input values") + def(max(var1)) do + %Sonata.Expr.Call{name: "max", arguments: [var1]} + end + @doc("MD5 hash") + def(md5(var1)) do + %Sonata.Expr.Call{name: "md5", arguments: [var1]} + end + @doc("internal conversion function for MULE_INTERNAL to SQL_ASCII") + def(mic_to_ascii(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "mic_to_ascii", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for MULE_INTERNAL to BIG5") + def(mic_to_big5(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "mic_to_big5", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for MULE_INTERNAL to EUC_CN") + def(mic_to_euc_cn(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "mic_to_euc_cn", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for MULE_INTERNAL to EUC_JP") + def(mic_to_euc_jp(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "mic_to_euc_jp", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for MULE_INTERNAL to EUC_KR") + def(mic_to_euc_kr(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "mic_to_euc_kr", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for MULE_INTERNAL to EUC_TW") + def(mic_to_euc_tw(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "mic_to_euc_tw", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for MULE_INTERNAL to ISO-8859-5") + def(mic_to_iso(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "mic_to_iso", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for MULE_INTERNAL to KOI8R") + def(mic_to_koi8r(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "mic_to_koi8r", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for MULE_INTERNAL to LATIN1") + def(mic_to_latin1(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "mic_to_latin1", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for MULE_INTERNAL to LATIN2") + def(mic_to_latin2(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "mic_to_latin2", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for MULE_INTERNAL to LATIN3") + def(mic_to_latin3(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "mic_to_latin3", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for MULE_INTERNAL to LATIN4") + def(mic_to_latin4(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "mic_to_latin4", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for MULE_INTERNAL to SJIS") + def(mic_to_sjis(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "mic_to_sjis", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for MULE_INTERNAL to WIN1250") + def(mic_to_win1250(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "mic_to_win1250", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for MULE_INTERNAL to WIN1251") + def(mic_to_win1251(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "mic_to_win1251", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for MULE_INTERNAL to WIN866") + def(mic_to_win866(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "mic_to_win866", arguments: [var1, var2, var3, var4, var5]} + end + @doc("minimum value of all time with time zone input values") + def(min(var1)) do + %Sonata.Expr.Call{name: "min", arguments: [var1]} + end + @doc("implementation of <#> operator") + def(mktinterval(var1, var2)) do + %Sonata.Expr.Call{name: "mktinterval", arguments: [var1, var2]} + end + @doc("modulus") + def(mod(var1, var2)) do + %Sonata.Expr.Call{name: "mod", arguments: [var1, var2]} + end + @doc("most common value") + def(mode(var1)) do + %Sonata.Expr.Call{name: "mode", arguments: [var1]} + end + @doc("aggregate final function") + def(mode_final(var1, var2)) do + %Sonata.Expr.Call{name: "mode_final", arguments: [var1, var2]} + end + @doc("convert int8 to money") + def(money(var1)) do + %Sonata.Expr.Call{name: "money", arguments: [var1]} + end + @doc("implementation of * operator") + def(mul_d_interval(var1, var2)) do + %Sonata.Expr.Call{name: "mul_d_interval", arguments: [var1, var2]} + end + @doc("age of a multi-transaction ID, in multi-transactions before current multi-transaction") + def(mxid_age(var1)) do + %Sonata.Expr.Call{name: "mxid_age", arguments: [var1]} + end + @doc("convert char(n) to name") + def(name(var1)) do + %Sonata.Expr.Call{name: "name", arguments: [var1]} + end + @doc("implementation of = operator") + def(nameeq(var1, var2)) do + %Sonata.Expr.Call{name: "nameeq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(namege(var1, var2)) do + %Sonata.Expr.Call{name: "namege", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(namegt(var1, var2)) do + %Sonata.Expr.Call{name: "namegt", arguments: [var1, var2]} + end + @doc("implementation of ~~* operator") + def(nameiclike(var1, var2)) do + %Sonata.Expr.Call{name: "nameiclike", arguments: [var1, var2]} + end + @doc("implementation of !~~* operator") + def(nameicnlike(var1, var2)) do + %Sonata.Expr.Call{name: "nameicnlike", arguments: [var1, var2]} + end + @doc("implementation of ~* operator") + def(nameicregexeq(var1, var2)) do + %Sonata.Expr.Call{name: "nameicregexeq", arguments: [var1, var2]} + end + @doc("implementation of !~* operator") + def(nameicregexne(var1, var2)) do + %Sonata.Expr.Call{name: "nameicregexne", arguments: [var1, var2]} + end + @doc("I/O") + def(namein(var1)) do + %Sonata.Expr.Call{name: "namein", arguments: [var1]} + end + @doc("implementation of <= operator") + def(namele(var1, var2)) do + %Sonata.Expr.Call{name: "namele", arguments: [var1, var2]} + end + @doc("implementation of ~~ operator") + def(namelike(var1, var2)) do + %Sonata.Expr.Call{name: "namelike", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(namelt(var1, var2)) do + %Sonata.Expr.Call{name: "namelt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(namene(var1, var2)) do + %Sonata.Expr.Call{name: "namene", arguments: [var1, var2]} + end + @doc("implementation of !~~ operator") + def(namenlike(var1, var2)) do + %Sonata.Expr.Call{name: "namenlike", arguments: [var1, var2]} + end + @doc("I/O") + def(nameout(var1)) do + %Sonata.Expr.Call{name: "nameout", arguments: [var1]} + end + @doc("I/O") + def(namerecv(var1)) do + %Sonata.Expr.Call{name: "namerecv", arguments: [var1]} + end + @doc("implementation of ~ operator") + def(nameregexeq(var1, var2)) do + %Sonata.Expr.Call{name: "nameregexeq", arguments: [var1, var2]} + end + @doc("implementation of !~ operator") + def(nameregexne(var1, var2)) do + %Sonata.Expr.Call{name: "nameregexne", arguments: [var1, var2]} + end + @doc("I/O") + def(namesend(var1)) do + %Sonata.Expr.Call{name: "namesend", arguments: [var1]} + end + @doc("join selectivity of <> and related operators") + def(neqjoinsel(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "neqjoinsel", arguments: [var1, var2, var3, var4, var5]} + end + @doc("restriction selectivity of <> and related operators") + def(neqsel(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "neqsel", arguments: [var1, var2, var3, var4]} + end + @doc("netmask of address") + def(netmask(var1)) do + %Sonata.Expr.Call{name: "netmask", arguments: [var1]} + end + @doc("network part of address") + def(network(var1)) do + %Sonata.Expr.Call{name: "network", arguments: [var1]} + end + @doc("less-equal-greater") + def(network_cmp(var1, var2)) do + %Sonata.Expr.Call{name: "network_cmp", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(network_eq(var1, var2)) do + %Sonata.Expr.Call{name: "network_eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(network_ge(var1, var2)) do + %Sonata.Expr.Call{name: "network_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(network_gt(var1, var2)) do + %Sonata.Expr.Call{name: "network_gt", arguments: [var1, var2]} + end + @doc("larger of two") + def(network_larger(var1, var2)) do + %Sonata.Expr.Call{name: "network_larger", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(network_le(var1, var2)) do + %Sonata.Expr.Call{name: "network_le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(network_lt(var1, var2)) do + %Sonata.Expr.Call{name: "network_lt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(network_ne(var1, var2)) do + %Sonata.Expr.Call{name: "network_ne", arguments: [var1, var2]} + end + @doc("implementation of && operator") + def(network_overlap(var1, var2)) do + %Sonata.Expr.Call{name: "network_overlap", arguments: [var1, var2]} + end + @doc("smaller of two") + def(network_smaller(var1, var2)) do + %Sonata.Expr.Call{name: "network_smaller", arguments: [var1, var2]} + end + @doc("implementation of << operator") + def(network_sub(var1, var2)) do + %Sonata.Expr.Call{name: "network_sub", arguments: [var1, var2]} + end + @doc("implementation of <<= operator") + def(network_subeq(var1, var2)) do + %Sonata.Expr.Call{name: "network_subeq", arguments: [var1, var2]} + end + @doc("implementation of >> operator") + def(network_sup(var1, var2)) do + %Sonata.Expr.Call{name: "network_sup", arguments: [var1, var2]} + end + @doc("implementation of >>= operator") + def(network_supeq(var1, var2)) do + %Sonata.Expr.Call{name: "network_supeq", arguments: [var1, var2]} + end + @doc("join selectivity for network operators") + def(networkjoinsel(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "networkjoinsel", arguments: [var1, var2, var3, var4, var5]} + end + @doc("restriction selectivity for network operators") + def(networksel(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "networksel", arguments: [var1, var2, var3, var4]} + end + @doc("sequence next value") + def(nextval(var1)) do + %Sonata.Expr.Call{name: "nextval", arguments: [var1]} + end + @doc("join selectivity of NOT LIKE") + def(nlikejoinsel(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "nlikejoinsel", arguments: [var1, var2, var3, var4, var5]} + end + @doc("restriction selectivity of NOT LIKE") + def(nlikesel(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "nlikesel", arguments: [var1, var2, var3, var4]} + end + @doc("does not match LIKE expression") + def(notlike(var1, var2)) do + %Sonata.Expr.Call{name: "notlike", arguments: [var1, var2]} + end + @doc("current transaction time") + def(now()) do + %Sonata.Expr.Call{name: "now", arguments: []} + end + @doc("number of points") + def(npoints(var1)) do + %Sonata.Expr.Call{name: "npoints", arguments: [var1]} + end + @doc("fetch the Nth row value") + def(nth_value(var1, var2)) do + %Sonata.Expr.Call{name: "nth_value", arguments: [var1, var2]} + end + @doc("split rows into N groups") + def(ntile(var1)) do + %Sonata.Expr.Call{name: "ntile", arguments: [var1]} + end + @doc("convert int8 to numeric") + def(numeric(var1)) do + %Sonata.Expr.Call{name: "numeric", arguments: [var1]} + end + @doc("implementation of @ operator") + def(numeric_abs(var1)) do + %Sonata.Expr.Call{name: "numeric_abs", arguments: [var1]} + end + @doc("aggregate transition function") + def(numeric_accum(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_accum", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(numeric_accum_inv(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_accum_inv", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(numeric_add(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_add", arguments: [var1, var2]} + end + @doc("aggregate final function") + def(numeric_avg(var1)) do + %Sonata.Expr.Call{name: "numeric_avg", arguments: [var1]} + end + @doc("aggregate transition function") + def(numeric_avg_accum(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_avg_accum", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(numeric_cmp(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_cmp", arguments: [var1, var2]} + end + @doc("implementation of / operator") + def(numeric_div(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_div", arguments: [var1, var2]} + end + @doc("trunc(x/y)") + def(numeric_div_trunc(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_div_trunc", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(numeric_eq(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_eq", arguments: [var1, var2]} + end + @doc("natural exponential (e^x)") + def(numeric_exp(var1)) do + %Sonata.Expr.Call{name: "numeric_exp", arguments: [var1]} + end + @doc("implementation of ! operator") + def(numeric_fac(var1)) do + %Sonata.Expr.Call{name: "numeric_fac", arguments: [var1]} + end + @doc("implementation of >= operator") + def(numeric_ge(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(numeric_gt(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_gt", arguments: [var1, var2]} + end + @doc("I/O") + def(numeric_in(var1, var2, var3)) do + %Sonata.Expr.Call{name: "numeric_in", arguments: [var1, var2, var3]} + end + @doc("increment by one") + def(numeric_inc(var1)) do + %Sonata.Expr.Call{name: "numeric_inc", arguments: [var1]} + end + @doc("larger of two") + def(numeric_larger(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_larger", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(numeric_le(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_le", arguments: [var1, var2]} + end + @doc("natural logarithm") + def(numeric_ln(var1)) do + %Sonata.Expr.Call{name: "numeric_ln", arguments: [var1]} + end + @doc("logarithm base m of n") + def(numeric_log(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_log", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(numeric_lt(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_lt", arguments: [var1, var2]} + end + @doc("implementation of % operator") + def(numeric_mod(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_mod", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(numeric_mul(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_mul", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(numeric_ne(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_ne", arguments: [var1, var2]} + end + @doc("I/O") + def(numeric_out(var1)) do + %Sonata.Expr.Call{name: "numeric_out", arguments: [var1]} + end + @doc("aggregate final function") + def(numeric_poly_avg(var1)) do + %Sonata.Expr.Call{name: "numeric_poly_avg", arguments: [var1]} + end + @doc("aggregate final function") + def(numeric_poly_stddev_pop(var1)) do + %Sonata.Expr.Call{name: "numeric_poly_stddev_pop", arguments: [var1]} + end + @doc("aggregate final function") + def(numeric_poly_stddev_samp(var1)) do + %Sonata.Expr.Call{name: "numeric_poly_stddev_samp", arguments: [var1]} + end + @doc("aggregate final function") + def(numeric_poly_sum(var1)) do + %Sonata.Expr.Call{name: "numeric_poly_sum", arguments: [var1]} + end + @doc("aggregate final function") + def(numeric_poly_var_pop(var1)) do + %Sonata.Expr.Call{name: "numeric_poly_var_pop", arguments: [var1]} + end + @doc("aggregate final function") + def(numeric_poly_var_samp(var1)) do + %Sonata.Expr.Call{name: "numeric_poly_var_samp", arguments: [var1]} + end + @doc("implementation of ^ operator") + def(numeric_power(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_power", arguments: [var1, var2]} + end + @doc("I/O") + def(numeric_recv(var1, var2, var3)) do + %Sonata.Expr.Call{name: "numeric_recv", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(numeric_send(var1)) do + %Sonata.Expr.Call{name: "numeric_send", arguments: [var1]} + end + @doc("smaller of two") + def(numeric_smaller(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_smaller", arguments: [var1, var2]} + end + @doc("sort support") + def(numeric_sortsupport(var1)) do + %Sonata.Expr.Call{name: "numeric_sortsupport", arguments: [var1]} + end + @doc("square root") + def(numeric_sqrt(var1)) do + %Sonata.Expr.Call{name: "numeric_sqrt", arguments: [var1]} + end + @doc("aggregate final function") + def(numeric_stddev_pop(var1)) do + %Sonata.Expr.Call{name: "numeric_stddev_pop", arguments: [var1]} + end + @doc("aggregate final function") + def(numeric_stddev_samp(var1)) do + %Sonata.Expr.Call{name: "numeric_stddev_samp", arguments: [var1]} + end + @doc("implementation of - operator") + def(numeric_sub(var1, var2)) do + %Sonata.Expr.Call{name: "numeric_sub", arguments: [var1, var2]} + end + @doc("aggregate final function") + def(numeric_sum(var1)) do + %Sonata.Expr.Call{name: "numeric_sum", arguments: [var1]} + end + @doc("transform a numeric length coercion") + def(numeric_transform(var1)) do + %Sonata.Expr.Call{name: "numeric_transform", arguments: [var1]} + end + @doc("implementation of - operator") + def(numeric_uminus(var1)) do + %Sonata.Expr.Call{name: "numeric_uminus", arguments: [var1]} + end + @doc("implementation of + operator") + def(numeric_uplus(var1)) do + %Sonata.Expr.Call{name: "numeric_uplus", arguments: [var1]} + end + @doc("aggregate final function") + def(numeric_var_pop(var1)) do + %Sonata.Expr.Call{name: "numeric_var_pop", arguments: [var1]} + end + @doc("aggregate final function") + def(numeric_var_samp(var1)) do + %Sonata.Expr.Call{name: "numeric_var_samp", arguments: [var1]} + end + @doc("I/O typmod") + def(numerictypmodin(var1)) do + %Sonata.Expr.Call{name: "numerictypmodin", arguments: [var1]} + end + @doc("I/O typmod") + def(numerictypmodout(var1)) do + %Sonata.Expr.Call{name: "numerictypmodout", arguments: [var1]} + end + @doc("number of nodes") + def(numnode(var1)) do + %Sonata.Expr.Call{name: "numnode", arguments: [var1]} + end + @doc("numrange constructor") + def(numrange(var1, var2)) do + %Sonata.Expr.Call{name: "numrange", arguments: [var1, var2]} + end + @doc("float8 difference of two numeric values") + def(numrange_subdiff(var1, var2)) do + %Sonata.Expr.Call{name: "numrange_subdiff", arguments: [var1, var2]} + end + @doc("get description for object id and catalog name") + def(obj_description(var1, var2)) do + %Sonata.Expr.Call{name: "obj_description", arguments: [var1, var2]} + end + @doc("octet length") + def(octet_length(var1)) do + %Sonata.Expr.Call{name: "octet_length", arguments: [var1]} + end + @doc("convert int8 to oid") + def(oid(var1)) do + %Sonata.Expr.Call{name: "oid", arguments: [var1]} + end + @doc("implementation of = operator") + def(oideq(var1, var2)) do + %Sonata.Expr.Call{name: "oideq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(oidge(var1, var2)) do + %Sonata.Expr.Call{name: "oidge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(oidgt(var1, var2)) do + %Sonata.Expr.Call{name: "oidgt", arguments: [var1, var2]} + end + @doc("I/O") + def(oidin(var1)) do + %Sonata.Expr.Call{name: "oidin", arguments: [var1]} + end + @doc("larger of two") + def(oidlarger(var1, var2)) do + %Sonata.Expr.Call{name: "oidlarger", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(oidle(var1, var2)) do + %Sonata.Expr.Call{name: "oidle", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(oidlt(var1, var2)) do + %Sonata.Expr.Call{name: "oidlt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(oidne(var1, var2)) do + %Sonata.Expr.Call{name: "oidne", arguments: [var1, var2]} + end + @doc("I/O") + def(oidout(var1)) do + %Sonata.Expr.Call{name: "oidout", arguments: [var1]} + end + @doc("I/O") + def(oidrecv(var1)) do + %Sonata.Expr.Call{name: "oidrecv", arguments: [var1]} + end + @doc("I/O") + def(oidsend(var1)) do + %Sonata.Expr.Call{name: "oidsend", arguments: [var1]} + end + @doc("smaller of two") + def(oidsmaller(var1, var2)) do + %Sonata.Expr.Call{name: "oidsmaller", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(oidvectoreq(var1, var2)) do + %Sonata.Expr.Call{name: "oidvectoreq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(oidvectorge(var1, var2)) do + %Sonata.Expr.Call{name: "oidvectorge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(oidvectorgt(var1, var2)) do + %Sonata.Expr.Call{name: "oidvectorgt", arguments: [var1, var2]} + end + @doc("I/O") + def(oidvectorin(var1)) do + %Sonata.Expr.Call{name: "oidvectorin", arguments: [var1]} + end + @doc("implementation of <= operator") + def(oidvectorle(var1, var2)) do + %Sonata.Expr.Call{name: "oidvectorle", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(oidvectorlt(var1, var2)) do + %Sonata.Expr.Call{name: "oidvectorlt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(oidvectorne(var1, var2)) do + %Sonata.Expr.Call{name: "oidvectorne", arguments: [var1, var2]} + end + @doc("I/O") + def(oidvectorout(var1)) do + %Sonata.Expr.Call{name: "oidvectorout", arguments: [var1]} + end + @doc("I/O") + def(oidvectorrecv(var1)) do + %Sonata.Expr.Call{name: "oidvectorrecv", arguments: [var1]} + end + @doc("I/O") + def(oidvectorsend(var1)) do + %Sonata.Expr.Call{name: "oidvectorsend", arguments: [var1]} + end + @doc("print type names of oidvector field") + def(oidvectortypes(var1)) do + %Sonata.Expr.Call{name: "oidvectortypes", arguments: [var1]} + end + @doc("implementation of <@ operator") + def(on_pb(var1, var2)) do + %Sonata.Expr.Call{name: "on_pb", arguments: [var1, var2]} + end + @doc("implementation of <@ operator") + def(on_pl(var1, var2)) do + %Sonata.Expr.Call{name: "on_pl", arguments: [var1, var2]} + end + @doc("implementation of <@ operator") + def(on_ppath(var1, var2)) do + %Sonata.Expr.Call{name: "on_ppath", arguments: [var1, var2]} + end + @doc("implementation of <@ operator") + def(on_ps(var1, var2)) do + %Sonata.Expr.Call{name: "on_ps", arguments: [var1, var2]} + end + @doc("implementation of <@ operator") + def(on_sb(var1, var2)) do + %Sonata.Expr.Call{name: "on_sb", arguments: [var1, var2]} + end + @doc("implementation of <@ operator") + def(on_sl(var1, var2)) do + %Sonata.Expr.Call{name: "on_sl", arguments: [var1, var2]} + end + @doc("I/O") + def(opaque_in(var1)) do + %Sonata.Expr.Call{name: "opaque_in", arguments: [var1]} + end + @doc("I/O") + def(opaque_out(var1)) do + %Sonata.Expr.Call{name: "opaque_out", arguments: [var1]} + end + @doc("aggregate transition function") + def(ordered_set_transition(var1, var2)) do + %Sonata.Expr.Call{name: "ordered_set_transition", arguments: [var1, var2]} + end + @doc("aggregate transition function") + def(ordered_set_transition_multi(var1, var2)) do + %Sonata.Expr.Call{name: "ordered_set_transition_multi", arguments: [var1, var2]} + end + @doc("intervals overlap?") + def(overlaps(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "overlaps", arguments: [var1, var2, var3, var4]} + end + @doc("substitute portion of string") + def(overlay(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "overlay", arguments: [var1, var2, var3, var4]} + end + @doc("convert polygon to path") + def(path(var1)) do + %Sonata.Expr.Call{name: "path", arguments: [var1]} + end + @doc("implementation of + operator") + def(path_add(var1, var2)) do + %Sonata.Expr.Call{name: "path_add", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(path_add_pt(var1, var2)) do + %Sonata.Expr.Call{name: "path_add_pt", arguments: [var1, var2]} + end + @doc("implementation of @@ operator") + def(path_center(var1)) do + %Sonata.Expr.Call{name: "path_center", arguments: [var1]} + end + @doc("implementation of @> operator") + def(path_contain_pt(var1, var2)) do + %Sonata.Expr.Call{name: "path_contain_pt", arguments: [var1, var2]} + end + @doc("implementation of <-> operator") + def(path_distance(var1, var2)) do + %Sonata.Expr.Call{name: "path_distance", arguments: [var1, var2]} + end + @doc("implementation of / operator") + def(path_div_pt(var1, var2)) do + %Sonata.Expr.Call{name: "path_div_pt", arguments: [var1, var2]} + end + @doc("I/O") + def(path_in(var1)) do + %Sonata.Expr.Call{name: "path_in", arguments: [var1]} + end + @doc("implementation of ?# operator") + def(path_inter(var1, var2)) do + %Sonata.Expr.Call{name: "path_inter", arguments: [var1, var2]} + end + @doc("implementation of @-@ operator") + def(path_length(var1)) do + %Sonata.Expr.Call{name: "path_length", arguments: [var1]} + end + @doc("implementation of * operator") + def(path_mul_pt(var1, var2)) do + %Sonata.Expr.Call{name: "path_mul_pt", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(path_n_eq(var1, var2)) do + %Sonata.Expr.Call{name: "path_n_eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(path_n_ge(var1, var2)) do + %Sonata.Expr.Call{name: "path_n_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(path_n_gt(var1, var2)) do + %Sonata.Expr.Call{name: "path_n_gt", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(path_n_le(var1, var2)) do + %Sonata.Expr.Call{name: "path_n_le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(path_n_lt(var1, var2)) do + %Sonata.Expr.Call{name: "path_n_lt", arguments: [var1, var2]} + end + @doc("implementation of # operator") + def(path_npoints(var1)) do + %Sonata.Expr.Call{name: "path_npoints", arguments: [var1]} + end + @doc("I/O") + def(path_out(var1)) do + %Sonata.Expr.Call{name: "path_out", arguments: [var1]} + end + @doc("I/O") + def(path_recv(var1)) do + %Sonata.Expr.Call{name: "path_recv", arguments: [var1]} + end + @doc("I/O") + def(path_send(var1)) do + %Sonata.Expr.Call{name: "path_send", arguments: [var1]} + end + @doc("implementation of - operator") + def(path_sub_pt(var1, var2)) do + %Sonata.Expr.Call{name: "path_sub_pt", arguments: [var1, var2]} + end + @doc("close path") + def(pclose(var1)) do + %Sonata.Expr.Call{name: "pclose", arguments: [var1]} + end + @doc("fractional rank of hypothetical row") + def(percent_rank(var1)) do + %Sonata.Expr.Call{name: "percent_rank", arguments: [var1]} + end + @doc("aggregate final function") + def(percent_rank_final(var1, var2)) do + %Sonata.Expr.Call{name: "percent_rank_final", arguments: [var1, var2]} + end + @doc("multiple continuous percentiles") + def(percentile_cont(var1, var2)) do + %Sonata.Expr.Call{name: "percentile_cont", arguments: [var1, var2]} + end + @doc("aggregate final function") + def(percentile_cont_float8_final(var1, var2)) do + %Sonata.Expr.Call{name: "percentile_cont_float8_final", arguments: [var1, var2]} + end + @doc("aggregate final function") + def(percentile_cont_float8_multi_final(var1, var2)) do + %Sonata.Expr.Call{name: "percentile_cont_float8_multi_final", arguments: [var1, var2]} + end + @doc("aggregate final function") + def(percentile_cont_interval_final(var1, var2)) do + %Sonata.Expr.Call{name: "percentile_cont_interval_final", arguments: [var1, var2]} + end + @doc("aggregate final function") + def(percentile_cont_interval_multi_final(var1, var2)) do + %Sonata.Expr.Call{name: "percentile_cont_interval_multi_final", arguments: [var1, var2]} + end + @doc("discrete percentile") + def(percentile_disc(var1, var2)) do + %Sonata.Expr.Call{name: "percentile_disc", arguments: [var1, var2]} + end + @doc("aggregate final function") + def(percentile_disc_final(var1, var2, var3)) do + %Sonata.Expr.Call{name: "percentile_disc_final", arguments: [var1, var2, var3]} + end + @doc("aggregate final function") + def(percentile_disc_multi_final(var1, var2, var3)) do + %Sonata.Expr.Call{name: "percentile_disc_multi_final", arguments: [var1, var2, var3]} + end + @doc("obtain exclusive advisory lock") + def(pg_advisory_lock(var1)) do + %Sonata.Expr.Call{name: "pg_advisory_lock", arguments: [var1]} + end + @doc("obtain shared advisory lock") + def(pg_advisory_lock_shared(var1)) do + %Sonata.Expr.Call{name: "pg_advisory_lock_shared", arguments: [var1]} + end + @doc("release exclusive advisory lock") + def(pg_advisory_unlock(var1, var2)) do + %Sonata.Expr.Call{name: "pg_advisory_unlock", arguments: [var1, var2]} + end + @doc("release all advisory locks") + def(pg_advisory_unlock_all()) do + %Sonata.Expr.Call{name: "pg_advisory_unlock_all", arguments: []} + end + @doc("release shared advisory lock") + def(pg_advisory_unlock_shared(var1, var2)) do + %Sonata.Expr.Call{name: "pg_advisory_unlock_shared", arguments: [var1, var2]} + end + @doc("obtain exclusive advisory lock") + def(pg_advisory_xact_lock(var1)) do + %Sonata.Expr.Call{name: "pg_advisory_xact_lock", arguments: [var1]} + end + @doc("obtain shared advisory lock") + def(pg_advisory_xact_lock_shared(var1, var2)) do + %Sonata.Expr.Call{name: "pg_advisory_xact_lock_shared", arguments: [var1, var2]} + end + @doc("list available extension versions") + def(pg_available_extension_versions()) do + %Sonata.Expr.Call{name: "pg_available_extension_versions", arguments: []} + end + @doc("list available extensions") + def(pg_available_extensions()) do + %Sonata.Expr.Call{name: "pg_available_extensions", arguments: []} + end + @doc("statistics: current backend PID") + def(pg_backend_pid()) do + %Sonata.Expr.Call{name: "pg_backend_pid", arguments: []} + end + @doc("start time of an online backup") + def(pg_backup_start_time()) do + %Sonata.Expr.Call{name: "pg_backup_start_time", arguments: []} + end + @doc("cancel a server process' current query") + def(pg_cancel_backend(var1)) do + %Sonata.Expr.Call{name: "pg_cancel_backend", arguments: [var1]} + end + @doc("convert encoding name to encoding id") + def(pg_char_to_encoding(var1)) do + %Sonata.Expr.Call{name: "pg_char_to_encoding", arguments: [var1]} + end + @doc("encoding name of current database") + def(pg_client_encoding()) do + %Sonata.Expr.Call{name: "pg_client_encoding", arguments: []} + end + @doc("collation of the argument; implementation of the COLLATION FOR expression") + def(pg_collation_for(var1)) do + %Sonata.Expr.Call{name: "pg_collation_for", arguments: [var1]} + end + @doc("is collation visible in search path?") + def(pg_collation_is_visible(var1)) do + %Sonata.Expr.Call{name: "pg_collation_is_visible", arguments: [var1]} + end + @doc("is a column updatable") + def(pg_column_is_updatable(var1, var2, var3)) do + %Sonata.Expr.Call{name: "pg_column_is_updatable", arguments: [var1, var2, var3]} + end + @doc("bytes required to store the value, perhaps with compression") + def(pg_column_size(var1)) do + %Sonata.Expr.Call{name: "pg_column_size", arguments: [var1]} + end + @doc("configuration load time") + def(pg_conf_load_time()) do + %Sonata.Expr.Call{name: "pg_conf_load_time", arguments: []} + end + @doc("is conversion visible in search path?") + def(pg_conversion_is_visible(var1)) do + %Sonata.Expr.Call{name: "pg_conversion_is_visible", arguments: [var1]} + end + @doc("set up a logical replication slot") + def(pg_create_logical_replication_slot(var1, var2)) do + %Sonata.Expr.Call{name: "pg_create_logical_replication_slot", arguments: [var1, var2]} + end + @doc("create a physical replication slot") + def(pg_create_physical_replication_slot(var1)) do + %Sonata.Expr.Call{name: "pg_create_physical_replication_slot", arguments: [var1]} + end + @doc("create a named restore point") + def(pg_create_restore_point(var1)) do + %Sonata.Expr.Call{name: "pg_create_restore_point", arguments: [var1]} + end + @doc("current xlog insert location") + def(pg_current_xlog_insert_location()) do + %Sonata.Expr.Call{name: "pg_current_xlog_insert_location", arguments: []} + end + @doc("current xlog write location") + def(pg_current_xlog_location()) do + %Sonata.Expr.Call{name: "pg_current_xlog_location", arguments: []} + end + @doc("get the open cursors for this session") + def(pg_cursor()) do + %Sonata.Expr.Call{name: "pg_cursor", arguments: []} + end + @doc("total disk space usage for the specified database") + def(pg_database_size(var1)) do + %Sonata.Expr.Call{name: "pg_database_size", arguments: [var1]} + end + @doc("I/O") + def(pg_ddl_command_in(var1)) do + %Sonata.Expr.Call{name: "pg_ddl_command_in", arguments: [var1]} + end + @doc("I/O") + def(pg_ddl_command_out(var1)) do + %Sonata.Expr.Call{name: "pg_ddl_command_out", arguments: [var1]} + end + @doc("I/O") + def(pg_ddl_command_recv(var1)) do + %Sonata.Expr.Call{name: "pg_ddl_command_recv", arguments: [var1]} + end + @doc("I/O") + def(pg_ddl_command_send(var1)) do + %Sonata.Expr.Call{name: "pg_ddl_command_send", arguments: [var1]} + end + @doc("get identification of SQL object") + def(pg_describe_object(var1, var2, var3)) do + %Sonata.Expr.Call{name: "pg_describe_object", arguments: [var1, var2, var3]} + end + @doc("drop a replication slot") + def(pg_drop_replication_slot(var1)) do + %Sonata.Expr.Call{name: "pg_drop_replication_slot", arguments: [var1]} + end + @doc("maximum octet length of a character in given encoding") + def(pg_encoding_max_length(var1)) do + %Sonata.Expr.Call{name: "pg_encoding_max_length", arguments: [var1]} + end + @doc("convert encoding id to encoding name") + def(pg_encoding_to_char(var1)) do + %Sonata.Expr.Call{name: "pg_encoding_to_char", arguments: [var1]} + end + @doc("list DDL actions being executed by the current command") + def(pg_event_trigger_ddl_commands()) do + %Sonata.Expr.Call{name: "pg_event_trigger_ddl_commands", arguments: []} + end + @doc("list objects dropped by the current command") + def(pg_event_trigger_dropped_objects()) do + %Sonata.Expr.Call{name: "pg_event_trigger_dropped_objects", arguments: []} + end + @doc("return Oid of the table getting rewritten") + def(pg_event_trigger_table_rewrite_oid()) do + %Sonata.Expr.Call{name: "pg_event_trigger_table_rewrite_oid", arguments: []} + end + @doc("return reason code for table getting rewritten") + def(pg_event_trigger_table_rewrite_reason()) do + %Sonata.Expr.Call{name: "pg_event_trigger_table_rewrite_reason", arguments: []} + end + @doc("export a snapshot") + def(pg_export_snapshot()) do + %Sonata.Expr.Call{name: "pg_export_snapshot", arguments: []} + end + @doc("flag an extension's table contents to be emitted by pg_dump") + def(pg_extension_config_dump(var1, var2)) do + %Sonata.Expr.Call{name: "pg_extension_config_dump", arguments: [var1, var2]} + end + @doc("list an extension's version update paths") + def(pg_extension_update_paths(var1)) do + %Sonata.Expr.Call{name: "pg_extension_update_paths", arguments: [var1]} + end + @doc("relation OID for filenode and tablespace") + def(pg_filenode_relation(var1, var2)) do + %Sonata.Expr.Call{name: "pg_filenode_relation", arguments: [var1, var2]} + end + @doc("is function visible in search path?") + def(pg_function_is_visible(var1)) do + %Sonata.Expr.Call{name: "pg_function_is_visible", arguments: [var1]} + end + @doc("constraint description") + def(pg_get_constraintdef(var1)) do + %Sonata.Expr.Call{name: "pg_get_constraintdef", arguments: [var1]} + end + @doc("deparse an encoded expression with pretty-print option") + def(pg_get_expr(var1, var2, var3)) do + %Sonata.Expr.Call{name: "pg_get_expr", arguments: [var1, var2, var3]} + end + @doc("function argument default") + def(pg_get_function_arg_default(var1, var2)) do + %Sonata.Expr.Call{name: "pg_get_function_arg_default", arguments: [var1, var2]} + end + @doc("argument list of a function") + def(pg_get_function_arguments(var1)) do + %Sonata.Expr.Call{name: "pg_get_function_arguments", arguments: [var1]} + end + @doc("identity argument list of a function") + def(pg_get_function_identity_arguments(var1)) do + %Sonata.Expr.Call{name: "pg_get_function_identity_arguments", arguments: [var1]} + end + @doc("result type of a function") + def(pg_get_function_result(var1)) do + %Sonata.Expr.Call{name: "pg_get_function_result", arguments: [var1]} + end + @doc("definition of a function") + def(pg_get_functiondef(var1)) do + %Sonata.Expr.Call{name: "pg_get_functiondef", arguments: [var1]} + end + @doc("index description") + def(pg_get_indexdef(var1)) do + %Sonata.Expr.Call{name: "pg_get_indexdef", arguments: [var1]} + end + @doc("list of SQL keywords") + def(pg_get_keywords()) do + %Sonata.Expr.Call{name: "pg_get_keywords", arguments: []} + end + @doc("view members of a multixactid") + def(pg_get_multixact_members(var1)) do + %Sonata.Expr.Call{name: "pg_get_multixact_members", arguments: [var1]} + end + @doc("get OID-based object address from name/args arrays") + def(pg_get_object_address(var1, var2, var3)) do + %Sonata.Expr.Call{name: "pg_get_object_address", arguments: [var1, var2, var3]} + end + @doc("information about replication slots currently in use") + def(pg_get_replication_slots()) do + %Sonata.Expr.Call{name: "pg_get_replication_slots", arguments: []} + end + @doc("source text of a rule with pretty-print option") + def(pg_get_ruledef(var1, var2)) do + %Sonata.Expr.Call{name: "pg_get_ruledef", arguments: [var1, var2]} + end + @doc("name of sequence for a serial column") + def(pg_get_serial_sequence(var1, var2)) do + %Sonata.Expr.Call{name: "pg_get_serial_sequence", arguments: [var1, var2]} + end + @doc("trigger description") + def(pg_get_triggerdef(var1)) do + %Sonata.Expr.Call{name: "pg_get_triggerdef", arguments: [var1]} + end + @doc("role name by OID (with fallback)") + def(pg_get_userbyid(var1)) do + %Sonata.Expr.Call{name: "pg_get_userbyid", arguments: [var1]} + end + @doc("select statement of a view") + def(pg_get_viewdef(var1)) do + %Sonata.Expr.Call{name: "pg_get_viewdef", arguments: [var1]} + end + @doc("current user privilege on role by role oid") + def(pg_has_role(var1, var2)) do + %Sonata.Expr.Call{name: "pg_has_role", arguments: [var1, var2]} + end + @doc("get machine-parseable identification of SQL object") + def(pg_identify_object(var1, var2, var3)) do + %Sonata.Expr.Call{name: "pg_identify_object", arguments: [var1, var2, var3]} + end + @doc("get identification of SQL object for pg_get_object_address()") + def(pg_identify_object_as_address(var1, var2, var3)) do + %Sonata.Expr.Call{name: "pg_identify_object_as_address", arguments: [var1, var2, var3]} + end + @doc("disk space usage for all indexes attached to the specified table") + def(pg_indexes_size(var1)) do + %Sonata.Expr.Call{name: "pg_indexes_size", arguments: [var1]} + end + @doc("true if server is in online backup") + def(pg_is_in_backup()) do + %Sonata.Expr.Call{name: "pg_is_in_backup", arguments: []} + end + @doc("true if server is in recovery") + def(pg_is_in_recovery()) do + %Sonata.Expr.Call{name: "pg_is_in_recovery", arguments: []} + end + @doc("is schema another session's temp schema?") + def(pg_is_other_temp_schema(var1)) do + %Sonata.Expr.Call{name: "pg_is_other_temp_schema", arguments: [var1]} + end + @doc("true if xlog replay is paused") + def(pg_is_xlog_replay_paused()) do + %Sonata.Expr.Call{name: "pg_is_xlog_replay_paused", arguments: []} + end + @doc("get transaction Id and commit timestamp of latest transaction commit") + def(pg_last_committed_xact()) do + %Sonata.Expr.Call{name: "pg_last_committed_xact", arguments: []} + end + @doc("timestamp of last replay xact") + def(pg_last_xact_replay_timestamp()) do + %Sonata.Expr.Call{name: "pg_last_xact_replay_timestamp", arguments: []} + end + @doc("current xlog flush location") + def(pg_last_xlog_receive_location()) do + %Sonata.Expr.Call{name: "pg_last_xlog_receive_location", arguments: []} + end + @doc("last xlog replay location") + def(pg_last_xlog_replay_location()) do + %Sonata.Expr.Call{name: "pg_last_xlog_replay_location", arguments: []} + end + @doc("get the channels that the current backend listens to") + def(pg_listening_channels()) do + %Sonata.Expr.Call{name: "pg_listening_channels", arguments: []} + end + @doc("view system lock information") + def(pg_lock_status()) do + %Sonata.Expr.Call{name: "pg_lock_status", arguments: []} + end + @doc("get binary changes from replication slot") + def(pg_logical_slot_get_binary_changes(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "pg_logical_slot_get_binary_changes", arguments: [var1, var2, var3, var4]} + end + @doc("get changes from replication slot") + def(pg_logical_slot_get_changes(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "pg_logical_slot_get_changes", arguments: [var1, var2, var3, var4]} + end + @doc("peek at binary changes from replication slot") + def(pg_logical_slot_peek_binary_changes(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "pg_logical_slot_peek_binary_changes", arguments: [var1, var2, var3, var4]} + end + @doc("peek at changes from replication slot") + def(pg_logical_slot_peek_changes(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "pg_logical_slot_peek_changes", arguments: [var1, var2, var3, var4]} + end + @doc("list all files in a directory") + def(pg_ls_dir(var1, var2, var3)) do + %Sonata.Expr.Call{name: "pg_ls_dir", arguments: [var1, var2, var3]} + end + @doc("less-equal-greater") + def(pg_lsn_cmp(var1, var2)) do + %Sonata.Expr.Call{name: "pg_lsn_cmp", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(pg_lsn_eq(var1, var2)) do + %Sonata.Expr.Call{name: "pg_lsn_eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(pg_lsn_ge(var1, var2)) do + %Sonata.Expr.Call{name: "pg_lsn_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(pg_lsn_gt(var1, var2)) do + %Sonata.Expr.Call{name: "pg_lsn_gt", arguments: [var1, var2]} + end + @doc("hash") + def(pg_lsn_hash(var1)) do + %Sonata.Expr.Call{name: "pg_lsn_hash", arguments: [var1]} + end + @doc("I/O") + def(pg_lsn_in(var1)) do + %Sonata.Expr.Call{name: "pg_lsn_in", arguments: [var1]} + end + @doc("implementation of <= operator") + def(pg_lsn_le(var1, var2)) do + %Sonata.Expr.Call{name: "pg_lsn_le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(pg_lsn_lt(var1, var2)) do + %Sonata.Expr.Call{name: "pg_lsn_lt", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(pg_lsn_mi(var1, var2)) do + %Sonata.Expr.Call{name: "pg_lsn_mi", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(pg_lsn_ne(var1, var2)) do + %Sonata.Expr.Call{name: "pg_lsn_ne", arguments: [var1, var2]} + end + @doc("I/O") + def(pg_lsn_out(var1)) do + %Sonata.Expr.Call{name: "pg_lsn_out", arguments: [var1]} + end + @doc("I/O") + def(pg_lsn_recv(var1)) do + %Sonata.Expr.Call{name: "pg_lsn_recv", arguments: [var1]} + end + @doc("I/O") + def(pg_lsn_send(var1)) do + %Sonata.Expr.Call{name: "pg_lsn_send", arguments: [var1]} + end + @doc("get OID of current session's temp schema, if any") + def(pg_my_temp_schema()) do + %Sonata.Expr.Call{name: "pg_my_temp_schema", arguments: []} + end + @doc("I/O") + def(pg_node_tree_in(var1)) do + %Sonata.Expr.Call{name: "pg_node_tree_in", arguments: [var1]} + end + @doc("I/O") + def(pg_node_tree_out(var1)) do + %Sonata.Expr.Call{name: "pg_node_tree_out", arguments: [var1]} + end + @doc("I/O") + def(pg_node_tree_recv(var1)) do + %Sonata.Expr.Call{name: "pg_node_tree_recv", arguments: [var1]} + end + @doc("I/O") + def(pg_node_tree_send(var1)) do + %Sonata.Expr.Call{name: "pg_node_tree_send", arguments: [var1]} + end + @doc("send a notification event") + def(pg_notify(var1, var2)) do + %Sonata.Expr.Call{name: "pg_notify", arguments: [var1, var2]} + end + @doc("is opclass visible in search path?") + def(pg_opclass_is_visible(var1)) do + %Sonata.Expr.Call{name: "pg_opclass_is_visible", arguments: [var1]} + end + @doc("is operator visible in search path?") + def(pg_operator_is_visible(var1)) do + %Sonata.Expr.Call{name: "pg_operator_is_visible", arguments: [var1]} + end + @doc("is opfamily visible in search path?") + def(pg_opfamily_is_visible(var1)) do + %Sonata.Expr.Call{name: "pg_opfamily_is_visible", arguments: [var1]} + end + @doc("convert generic options array to name/value table") + def(pg_options_to_table(var1)) do + %Sonata.Expr.Call{name: "pg_options_to_table", arguments: [var1]} + end + @doc("postmaster start time") + def(pg_postmaster_start_time()) do + %Sonata.Expr.Call{name: "pg_postmaster_start_time", arguments: []} + end + @doc("get the prepared statements for this session") + def(pg_prepared_statement()) do + %Sonata.Expr.Call{name: "pg_prepared_statement", arguments: []} + end + @doc("view two-phase transactions") + def(pg_prepared_xact()) do + %Sonata.Expr.Call{name: "pg_prepared_xact", arguments: []} + end + @doc("read bytea from a file") + def(pg_read_binary_file(var1)) do + %Sonata.Expr.Call{name: "pg_read_binary_file", arguments: [var1]} + end + @doc("read text from a file") + def(pg_read_file(var1, var2, var3)) do + %Sonata.Expr.Call{name: "pg_read_file", arguments: [var1, var2, var3]} + end + @doc("filenode identifier of relation") + def(pg_relation_filenode(var1)) do + %Sonata.Expr.Call{name: "pg_relation_filenode", arguments: [var1]} + end + @doc("file path of relation") + def(pg_relation_filepath(var1)) do + %Sonata.Expr.Call{name: "pg_relation_filepath", arguments: [var1]} + end + @doc("is a relation insertable/updatable/deletable") + def(pg_relation_is_updatable(var1, var2)) do + %Sonata.Expr.Call{name: "pg_relation_is_updatable", arguments: [var1, var2]} + end + @doc("disk space usage for the main fork of the specified table or index") + def(pg_relation_size(var1)) do + %Sonata.Expr.Call{name: "pg_relation_size", arguments: [var1]} + end + @doc("reload configuration files") + def(pg_reload_conf()) do + %Sonata.Expr.Call{name: "pg_reload_conf", arguments: []} + end + @doc("advance replication itentifier to specific location") + def(pg_replication_origin_advance(var1, var2)) do + %Sonata.Expr.Call{name: "pg_replication_origin_advance", arguments: [var1, var2]} + end + @doc("create a replication origin") + def(pg_replication_origin_create(var1)) do + %Sonata.Expr.Call{name: "pg_replication_origin_create", arguments: [var1]} + end + @doc("drop replication origin identified by its name") + def(pg_replication_origin_drop(var1)) do + %Sonata.Expr.Call{name: "pg_replication_origin_drop", arguments: [var1]} + end + @doc("translate the replication origin's name to its id") + def(pg_replication_origin_oid(var1)) do + %Sonata.Expr.Call{name: "pg_replication_origin_oid", arguments: [var1]} + end + @doc("get an individual replication origin's replication progress") + def(pg_replication_origin_progress(var1, var2)) do + %Sonata.Expr.Call{name: "pg_replication_origin_progress", arguments: [var1, var2]} + end + @doc("is a replication origin configured in this session") + def(pg_replication_origin_session_is_setup()) do + %Sonata.Expr.Call{name: "pg_replication_origin_session_is_setup", arguments: []} + end + @doc("get the replication progress of the current session") + def(pg_replication_origin_session_progress(var1)) do + %Sonata.Expr.Call{name: "pg_replication_origin_session_progress", arguments: [var1]} + end + @doc("teardown configured replication progress tracking") + def(pg_replication_origin_session_reset()) do + %Sonata.Expr.Call{name: "pg_replication_origin_session_reset", arguments: []} + end + @doc("configure session to maintain replication progress tracking for the passed in origin") + def(pg_replication_origin_session_setup(var1)) do + %Sonata.Expr.Call{name: "pg_replication_origin_session_setup", arguments: [var1]} + end + @doc("reset the transaction's origin lsn and timestamp") + def(pg_replication_origin_xact_reset(var1, var2)) do + %Sonata.Expr.Call{name: "pg_replication_origin_xact_reset", arguments: [var1, var2]} + end + @doc("setup the transaction's origin lsn and timestamp") + def(pg_replication_origin_xact_setup(var1, var2)) do + %Sonata.Expr.Call{name: "pg_replication_origin_xact_setup", arguments: [var1, var2]} + end + @doc("rotate log file") + def(pg_rotate_logfile()) do + %Sonata.Expr.Call{name: "pg_rotate_logfile", arguments: []} + end + @doc("sequence parameters, for use by information schema") + def(pg_sequence_parameters(var1)) do + %Sonata.Expr.Call{name: "pg_sequence_parameters", arguments: [var1]} + end + @doc("show config file settings") + def(pg_show_all_file_settings()) do + %Sonata.Expr.Call{name: "pg_show_all_file_settings", arguments: []} + end + @doc("SHOW ALL as a function") + def(pg_show_all_settings()) do + %Sonata.Expr.Call{name: "pg_show_all_settings", arguments: []} + end + @doc("get progress for all replication origins") + def(pg_show_replication_origin_status()) do + %Sonata.Expr.Call{name: "pg_show_replication_origin_status", arguments: []} + end + @doc("convert a numeric to a human readable text using size units") + def(pg_size_pretty(var1)) do + %Sonata.Expr.Call{name: "pg_size_pretty", arguments: [var1]} + end + @doc("sleep for the specified time in seconds") + def(pg_sleep(var1)) do + %Sonata.Expr.Call{name: "pg_sleep", arguments: [var1]} + end + @doc("sleep for the specified interval") + def(pg_sleep_for(var1)) do + %Sonata.Expr.Call{name: "pg_sleep_for", arguments: [var1]} + end + @doc("sleep until the specified time") + def(pg_sleep_until(var1)) do + %Sonata.Expr.Call{name: "pg_sleep_until", arguments: [var1]} + end + @doc("prepare for taking an online backup") + def(pg_start_backup(var1, var2)) do + %Sonata.Expr.Call{name: "pg_start_backup", arguments: [var1, var2]} + end + @doc("statistics: discard current transaction's statistics snapshot") + def(pg_stat_clear_snapshot()) do + %Sonata.Expr.Call{name: "pg_stat_clear_snapshot", arguments: []} + end + @doc("get information about file") + def(pg_stat_file(var1, var2)) do + %Sonata.Expr.Call{name: "pg_stat_file", arguments: [var1, var2]} + end + @doc("statistics: information about currently active backends") + def(pg_stat_get_activity(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_activity", arguments: [var1]} + end + @doc("statistics: number of manual analyzes for a table") + def(pg_stat_get_analyze_count(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_analyze_count", arguments: [var1]} + end + @doc("statistics: information about WAL archiver") + def(pg_stat_get_archiver()) do + %Sonata.Expr.Call{name: "pg_stat_get_archiver", arguments: []} + end + @doc("statistics: number of auto analyzes for a table") + def(pg_stat_get_autoanalyze_count(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_autoanalyze_count", arguments: [var1]} + end + @doc("statistics: number of auto vacuums for a table") + def(pg_stat_get_autovacuum_count(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_autovacuum_count", arguments: [var1]} + end + @doc("statistics: current query of backend") + def(pg_stat_get_backend_activity(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_backend_activity", arguments: [var1]} + end + @doc("statistics: start time for current query of backend") + def(pg_stat_get_backend_activity_start(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_backend_activity_start", arguments: [var1]} + end + @doc("statistics: address of client connected to backend") + def(pg_stat_get_backend_client_addr(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_backend_client_addr", arguments: [var1]} + end + @doc("statistics: port number of client connected to backend") + def(pg_stat_get_backend_client_port(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_backend_client_port", arguments: [var1]} + end + @doc("statistics: database ID of backend") + def(pg_stat_get_backend_dbid(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_backend_dbid", arguments: [var1]} + end + @doc("statistics: currently active backend IDs") + def(pg_stat_get_backend_idset()) do + %Sonata.Expr.Call{name: "pg_stat_get_backend_idset", arguments: []} + end + @doc("statistics: PID of backend") + def(pg_stat_get_backend_pid(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_backend_pid", arguments: [var1]} + end + @doc("statistics: start time for current backend session") + def(pg_stat_get_backend_start(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_backend_start", arguments: [var1]} + end + @doc("statistics: user ID of backend") + def(pg_stat_get_backend_userid(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_backend_userid", arguments: [var1]} + end + @doc("statistics: is backend currently waiting for a lock") + def(pg_stat_get_backend_waiting(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_backend_waiting", arguments: [var1]} + end + @doc("statistics: start time for backend's current transaction") + def(pg_stat_get_backend_xact_start(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_backend_xact_start", arguments: [var1]} + end + @doc("statistics: number of buffers written by the bgwriter during checkpoints") + def(pg_stat_get_bgwriter_buf_written_checkpoints()) do + %Sonata.Expr.Call{name: "pg_stat_get_bgwriter_buf_written_checkpoints", arguments: []} + end + @doc("statistics: number of buffers written by the bgwriter for cleaning dirty buffers") + def(pg_stat_get_bgwriter_buf_written_clean()) do + %Sonata.Expr.Call{name: "pg_stat_get_bgwriter_buf_written_clean", arguments: []} + end + @doc("statistics: number of times the bgwriter stopped processing when it had written too many buffers while cleaning") + def(pg_stat_get_bgwriter_maxwritten_clean()) do + %Sonata.Expr.Call{name: "pg_stat_get_bgwriter_maxwritten_clean", arguments: []} + end + @doc("statistics: number of backend requested checkpoints started by the bgwriter") + def(pg_stat_get_bgwriter_requested_checkpoints()) do + %Sonata.Expr.Call{name: "pg_stat_get_bgwriter_requested_checkpoints", arguments: []} + end + @doc("statistics: last reset for the bgwriter") + def(pg_stat_get_bgwriter_stat_reset_time()) do + %Sonata.Expr.Call{name: "pg_stat_get_bgwriter_stat_reset_time", arguments: []} + end + @doc("statistics: number of timed checkpoints started by the bgwriter") + def(pg_stat_get_bgwriter_timed_checkpoints()) do + %Sonata.Expr.Call{name: "pg_stat_get_bgwriter_timed_checkpoints", arguments: []} + end + @doc("statistics: number of blocks fetched") + def(pg_stat_get_blocks_fetched(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_blocks_fetched", arguments: [var1]} + end + @doc("statistics: number of blocks found in cache") + def(pg_stat_get_blocks_hit(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_blocks_hit", arguments: [var1]} + end + @doc("statistics: number of buffer allocations") + def(pg_stat_get_buf_alloc()) do + %Sonata.Expr.Call{name: "pg_stat_get_buf_alloc", arguments: []} + end + @doc("statistics: number of backend buffer writes that did their own fsync") + def(pg_stat_get_buf_fsync_backend()) do + %Sonata.Expr.Call{name: "pg_stat_get_buf_fsync_backend", arguments: []} + end + @doc("statistics: number of buffers written by backends") + def(pg_stat_get_buf_written_backend()) do + %Sonata.Expr.Call{name: "pg_stat_get_buf_written_backend", arguments: []} + end + @doc("statistics: checkpoint time spent synchronizing buffers to disk, in msec") + def(pg_stat_get_checkpoint_sync_time()) do + %Sonata.Expr.Call{name: "pg_stat_get_checkpoint_sync_time", arguments: []} + end + @doc("statistics: checkpoint time spent writing buffers to disk, in msec") + def(pg_stat_get_checkpoint_write_time()) do + %Sonata.Expr.Call{name: "pg_stat_get_checkpoint_write_time", arguments: []} + end + @doc("statistics: block read time, in msec") + def(pg_stat_get_db_blk_read_time(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_blk_read_time", arguments: [var1]} + end + @doc("statistics: block write time, in msec") + def(pg_stat_get_db_blk_write_time(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_blk_write_time", arguments: [var1]} + end + @doc("statistics: blocks fetched for database") + def(pg_stat_get_db_blocks_fetched(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_blocks_fetched", arguments: [var1]} + end + @doc("statistics: blocks found in cache for database") + def(pg_stat_get_db_blocks_hit(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_blocks_hit", arguments: [var1]} + end + @doc("statistics: recovery conflicts in database") + def(pg_stat_get_db_conflict_all(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_conflict_all", arguments: [var1]} + end + @doc("statistics: recovery conflicts in database caused by shared buffer pin") + def(pg_stat_get_db_conflict_bufferpin(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_conflict_bufferpin", arguments: [var1]} + end + @doc("statistics: recovery conflicts in database caused by relation lock") + def(pg_stat_get_db_conflict_lock(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_conflict_lock", arguments: [var1]} + end + @doc("statistics: recovery conflicts in database caused by snapshot expiry") + def(pg_stat_get_db_conflict_snapshot(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_conflict_snapshot", arguments: [var1]} + end + @doc("statistics: recovery conflicts in database caused by buffer deadlock") + def(pg_stat_get_db_conflict_startup_deadlock(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_conflict_startup_deadlock", arguments: [var1]} + end + @doc("statistics: recovery conflicts in database caused by drop tablespace") + def(pg_stat_get_db_conflict_tablespace(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_conflict_tablespace", arguments: [var1]} + end + @doc("statistics: deadlocks detected in database") + def(pg_stat_get_db_deadlocks(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_deadlocks", arguments: [var1]} + end + @doc("statistics: number of backends in database") + def(pg_stat_get_db_numbackends(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_numbackends", arguments: [var1]} + end + @doc("statistics: last reset for a database") + def(pg_stat_get_db_stat_reset_time(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_stat_reset_time", arguments: [var1]} + end + @doc("statistics: number of bytes in temporary files written") + def(pg_stat_get_db_temp_bytes(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_temp_bytes", arguments: [var1]} + end + @doc("statistics: number of temporary files written") + def(pg_stat_get_db_temp_files(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_temp_files", arguments: [var1]} + end + @doc("statistics: tuples deleted in database") + def(pg_stat_get_db_tuples_deleted(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_tuples_deleted", arguments: [var1]} + end + @doc("statistics: tuples fetched for database") + def(pg_stat_get_db_tuples_fetched(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_tuples_fetched", arguments: [var1]} + end + @doc("statistics: tuples inserted in database") + def(pg_stat_get_db_tuples_inserted(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_tuples_inserted", arguments: [var1]} + end + @doc("statistics: tuples returned for database") + def(pg_stat_get_db_tuples_returned(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_tuples_returned", arguments: [var1]} + end + @doc("statistics: tuples updated in database") + def(pg_stat_get_db_tuples_updated(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_tuples_updated", arguments: [var1]} + end + @doc("statistics: transactions committed") + def(pg_stat_get_db_xact_commit(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_xact_commit", arguments: [var1]} + end + @doc("statistics: transactions rolled back") + def(pg_stat_get_db_xact_rollback(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_db_xact_rollback", arguments: [var1]} + end + @doc("statistics: number of dead tuples") + def(pg_stat_get_dead_tuples(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_dead_tuples", arguments: [var1]} + end + @doc("statistics: number of function calls") + def(pg_stat_get_function_calls(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_function_calls", arguments: [var1]} + end + @doc("statistics: self execution time of function, in msec") + def(pg_stat_get_function_self_time(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_function_self_time", arguments: [var1]} + end + @doc("statistics: total execution time of function, in msec") + def(pg_stat_get_function_total_time(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_function_total_time", arguments: [var1]} + end + @doc("statistics: last manual analyze time for a table") + def(pg_stat_get_last_analyze_time(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_last_analyze_time", arguments: [var1]} + end + @doc("statistics: last auto analyze time for a table") + def(pg_stat_get_last_autoanalyze_time(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_last_autoanalyze_time", arguments: [var1]} + end + @doc("statistics: last auto vacuum time for a table") + def(pg_stat_get_last_autovacuum_time(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_last_autovacuum_time", arguments: [var1]} + end + @doc("statistics: last manual vacuum time for a table") + def(pg_stat_get_last_vacuum_time(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_last_vacuum_time", arguments: [var1]} + end + @doc("statistics: number of live tuples") + def(pg_stat_get_live_tuples(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_live_tuples", arguments: [var1]} + end + @doc("statistics: number of tuples changed since last analyze") + def(pg_stat_get_mod_since_analyze(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_mod_since_analyze", arguments: [var1]} + end + @doc("statistics: number of scans done for table/index") + def(pg_stat_get_numscans(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_numscans", arguments: [var1]} + end + @doc("statistics: timestamp of the current statistics snapshot") + def(pg_stat_get_snapshot_timestamp()) do + %Sonata.Expr.Call{name: "pg_stat_get_snapshot_timestamp", arguments: []} + end + @doc("statistics: number of tuples deleted") + def(pg_stat_get_tuples_deleted(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_tuples_deleted", arguments: [var1]} + end + @doc("statistics: number of tuples fetched by idxscan") + def(pg_stat_get_tuples_fetched(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_tuples_fetched", arguments: [var1]} + end + @doc("statistics: number of tuples hot updated") + def(pg_stat_get_tuples_hot_updated(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_tuples_hot_updated", arguments: [var1]} + end + @doc("statistics: number of tuples inserted") + def(pg_stat_get_tuples_inserted(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_tuples_inserted", arguments: [var1]} + end + @doc("statistics: number of tuples read by seqscan") + def(pg_stat_get_tuples_returned(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_tuples_returned", arguments: [var1]} + end + @doc("statistics: number of tuples updated") + def(pg_stat_get_tuples_updated(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_tuples_updated", arguments: [var1]} + end + @doc("statistics: number of manual vacuums for a table") + def(pg_stat_get_vacuum_count(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_vacuum_count", arguments: [var1]} + end + @doc("statistics: information about currently active replication") + def(pg_stat_get_wal_senders()) do + %Sonata.Expr.Call{name: "pg_stat_get_wal_senders", arguments: []} + end + @doc("statistics: number of blocks fetched in current transaction") + def(pg_stat_get_xact_blocks_fetched(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_xact_blocks_fetched", arguments: [var1]} + end + @doc("statistics: number of blocks found in cache in current transaction") + def(pg_stat_get_xact_blocks_hit(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_xact_blocks_hit", arguments: [var1]} + end + @doc("statistics: number of function calls in current transaction") + def(pg_stat_get_xact_function_calls(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_xact_function_calls", arguments: [var1]} + end + @doc("statistics: self execution time of function in current transaction, in msec") + def(pg_stat_get_xact_function_self_time(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_xact_function_self_time", arguments: [var1]} + end + @doc("statistics: total execution time of function in current transaction, in msec") + def(pg_stat_get_xact_function_total_time(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_xact_function_total_time", arguments: [var1]} + end + @doc("statistics: number of scans done for table/index in current transaction") + def(pg_stat_get_xact_numscans(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_xact_numscans", arguments: [var1]} + end + @doc("statistics: number of tuples deleted in current transaction") + def(pg_stat_get_xact_tuples_deleted(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_xact_tuples_deleted", arguments: [var1]} + end + @doc("statistics: number of tuples fetched by idxscan in current transaction") + def(pg_stat_get_xact_tuples_fetched(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_xact_tuples_fetched", arguments: [var1]} + end + @doc("statistics: number of tuples hot updated in current transaction") + def(pg_stat_get_xact_tuples_hot_updated(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_xact_tuples_hot_updated", arguments: [var1]} + end + @doc("statistics: number of tuples inserted in current transaction") + def(pg_stat_get_xact_tuples_inserted(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_xact_tuples_inserted", arguments: [var1]} + end + @doc("statistics: number of tuples read by seqscan in current transaction") + def(pg_stat_get_xact_tuples_returned(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_xact_tuples_returned", arguments: [var1]} + end + @doc("statistics: number of tuples updated in current transaction") + def(pg_stat_get_xact_tuples_updated(var1)) do + %Sonata.Expr.Call{name: "pg_stat_get_xact_tuples_updated", arguments: [var1]} + end + @doc("statistics: reset collected statistics for current database") + def(pg_stat_reset()) do + %Sonata.Expr.Call{name: "pg_stat_reset", arguments: []} + end + @doc("statistics: reset collected statistics shared across the cluster") + def(pg_stat_reset_shared(var1)) do + %Sonata.Expr.Call{name: "pg_stat_reset_shared", arguments: [var1]} + end + @doc("statistics: reset collected statistics for a single function in the current database") + def(pg_stat_reset_single_function_counters(var1)) do + %Sonata.Expr.Call{name: "pg_stat_reset_single_function_counters", arguments: [var1]} + end + @doc("statistics: reset collected statistics for a single table or index in the current database") + def(pg_stat_reset_single_table_counters(var1)) do + %Sonata.Expr.Call{name: "pg_stat_reset_single_table_counters", arguments: [var1]} + end + @doc("finish taking an online backup") + def(pg_stop_backup()) do + %Sonata.Expr.Call{name: "pg_stop_backup", arguments: []} + end + @doc("switch to new xlog file") + def(pg_switch_xlog()) do + %Sonata.Expr.Call{name: "pg_switch_xlog", arguments: []} + end + @doc("is table visible in search path?") + def(pg_table_is_visible(var1)) do + %Sonata.Expr.Call{name: "pg_table_is_visible", arguments: [var1]} + end + @doc("disk space usage for the specified table, including TOAST, free space and visibility map") + def(pg_table_size(var1)) do + %Sonata.Expr.Call{name: "pg_table_size", arguments: [var1]} + end + @doc("get OIDs of databases in a tablespace") + def(pg_tablespace_databases(var1)) do + %Sonata.Expr.Call{name: "pg_tablespace_databases", arguments: [var1]} + end + @doc("tablespace location") + def(pg_tablespace_location(var1)) do + %Sonata.Expr.Call{name: "pg_tablespace_location", arguments: [var1]} + end + @doc("total disk space usage for the specified tablespace") + def(pg_tablespace_size(var1)) do + %Sonata.Expr.Call{name: "pg_tablespace_size", arguments: [var1]} + end + @doc("terminate a server process") + def(pg_terminate_backend(var1)) do + %Sonata.Expr.Call{name: "pg_terminate_backend", arguments: [var1]} + end + @doc("get the available time zone abbreviations") + def(pg_timezone_abbrevs()) do + %Sonata.Expr.Call{name: "pg_timezone_abbrevs", arguments: []} + end + @doc("get the available time zone names") + def(pg_timezone_names()) do + %Sonata.Expr.Call{name: "pg_timezone_names", arguments: []} + end + @doc("total disk space usage for the specified table and associated indexes") + def(pg_total_relation_size(var1)) do + %Sonata.Expr.Call{name: "pg_total_relation_size", arguments: [var1]} + end + @doc("current trigger depth") + def(pg_trigger_depth()) do + %Sonata.Expr.Call{name: "pg_trigger_depth", arguments: []} + end + @doc("obtain exclusive advisory lock if available") + def(pg_try_advisory_lock(var1)) do + %Sonata.Expr.Call{name: "pg_try_advisory_lock", arguments: [var1]} + end + @doc("obtain shared advisory lock if available") + def(pg_try_advisory_lock_shared(var1)) do + %Sonata.Expr.Call{name: "pg_try_advisory_lock_shared", arguments: [var1]} + end + @doc("obtain exclusive advisory lock if available") + def(pg_try_advisory_xact_lock(var1, var2)) do + %Sonata.Expr.Call{name: "pg_try_advisory_xact_lock", arguments: [var1, var2]} + end + @doc("obtain shared advisory lock if available") + def(pg_try_advisory_xact_lock_shared(var1)) do + %Sonata.Expr.Call{name: "pg_try_advisory_xact_lock_shared", arguments: [var1]} + end + @doc("is text search configuration visible in search path?") + def(pg_ts_config_is_visible(var1)) do + %Sonata.Expr.Call{name: "pg_ts_config_is_visible", arguments: [var1]} + end + @doc("is text search dictionary visible in search path?") + def(pg_ts_dict_is_visible(var1)) do + %Sonata.Expr.Call{name: "pg_ts_dict_is_visible", arguments: [var1]} + end + @doc("is text search parser visible in search path?") + def(pg_ts_parser_is_visible(var1)) do + %Sonata.Expr.Call{name: "pg_ts_parser_is_visible", arguments: [var1]} + end + @doc("is text search template visible in search path?") + def(pg_ts_template_is_visible(var1)) do + %Sonata.Expr.Call{name: "pg_ts_template_is_visible", arguments: [var1]} + end + @doc("is type visible in search path?") + def(pg_type_is_visible(var1)) do + %Sonata.Expr.Call{name: "pg_type_is_visible", arguments: [var1]} + end + @doc("type of the argument") + def(pg_typeof(var1)) do + %Sonata.Expr.Call{name: "pg_typeof", arguments: [var1]} + end + @doc("get commit timestamp of a transaction") + def(pg_xact_commit_timestamp(var1)) do + %Sonata.Expr.Call{name: "pg_xact_commit_timestamp", arguments: [var1]} + end + @doc("difference in bytes, given two xlog locations") + def(pg_xlog_location_diff(var1, var2)) do + %Sonata.Expr.Call{name: "pg_xlog_location_diff", arguments: [var1, var2]} + end + @doc("pause xlog replay") + def(pg_xlog_replay_pause()) do + %Sonata.Expr.Call{name: "pg_xlog_replay_pause", arguments: []} + end + @doc("resume xlog replay, if it was paused") + def(pg_xlog_replay_resume()) do + %Sonata.Expr.Call{name: "pg_xlog_replay_resume", arguments: []} + end + @doc("xlog filename, given an xlog location") + def(pg_xlogfile_name(var1)) do + %Sonata.Expr.Call{name: "pg_xlogfile_name", arguments: [var1]} + end + @doc("xlog filename and byte offset, given an xlog location") + def(pg_xlogfile_name_offset(var1)) do + %Sonata.Expr.Call{name: "pg_xlogfile_name_offset", arguments: [var1]} + end + @doc("PI") + def(pi()) do + %Sonata.Expr.Call{name: "pi", arguments: []} + end + @doc("transform to tsquery") + def(plainto_tsquery(var1)) do + %Sonata.Expr.Call{name: "plainto_tsquery", arguments: [var1]} + end + @doc("center of") + def(point(var1)) do + %Sonata.Expr.Call{name: "point", arguments: [var1]} + end + @doc("implementation of >^ operator") + def(point_above(var1, var2)) do + %Sonata.Expr.Call{name: "point_above", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(point_add(var1, var2)) do + %Sonata.Expr.Call{name: "point_add", arguments: [var1, var2]} + end + @doc("implementation of <^ operator") + def(point_below(var1, var2)) do + %Sonata.Expr.Call{name: "point_below", arguments: [var1, var2]} + end + @doc("implementation of <-> operator") + def(point_distance(var1, var2)) do + %Sonata.Expr.Call{name: "point_distance", arguments: [var1, var2]} + end + @doc("implementation of / operator") + def(point_div(var1, var2)) do + %Sonata.Expr.Call{name: "point_div", arguments: [var1, var2]} + end + @doc("implementation of ~= operator") + def(point_eq(var1, var2)) do + %Sonata.Expr.Call{name: "point_eq", arguments: [var1, var2]} + end + @doc("implementation of ?- operator") + def(point_horiz(var1, var2)) do + %Sonata.Expr.Call{name: "point_horiz", arguments: [var1, var2]} + end + @doc("I/O") + def(point_in(var1)) do + %Sonata.Expr.Call{name: "point_in", arguments: [var1]} + end + @doc("implementation of << operator") + def(point_left(var1, var2)) do + %Sonata.Expr.Call{name: "point_left", arguments: [var1, var2]} + end + @doc("implementation of * operator") + def(point_mul(var1, var2)) do + %Sonata.Expr.Call{name: "point_mul", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(point_ne(var1, var2)) do + %Sonata.Expr.Call{name: "point_ne", arguments: [var1, var2]} + end + @doc("I/O") + def(point_out(var1)) do + %Sonata.Expr.Call{name: "point_out", arguments: [var1]} + end + @doc("I/O") + def(point_recv(var1)) do + %Sonata.Expr.Call{name: "point_recv", arguments: [var1]} + end + @doc("implementation of >> operator") + def(point_right(var1, var2)) do + %Sonata.Expr.Call{name: "point_right", arguments: [var1, var2]} + end + @doc("I/O") + def(point_send(var1)) do + %Sonata.Expr.Call{name: "point_send", arguments: [var1]} + end + @doc("implementation of - operator") + def(point_sub(var1, var2)) do + %Sonata.Expr.Call{name: "point_sub", arguments: [var1, var2]} + end + @doc("implementation of ?| operator") + def(point_vert(var1, var2)) do + %Sonata.Expr.Call{name: "point_vert", arguments: [var1, var2]} + end + @doc("implementation of |>> operator") + def(poly_above(var1, var2)) do + %Sonata.Expr.Call{name: "poly_above", arguments: [var1, var2]} + end + @doc("implementation of <<| operator") + def(poly_below(var1, var2)) do + %Sonata.Expr.Call{name: "poly_below", arguments: [var1, var2]} + end + @doc("implementation of @@ operator") + def(poly_center(var1)) do + %Sonata.Expr.Call{name: "poly_center", arguments: [var1]} + end + @doc("implementation of @> operator") + def(poly_contain(var1, var2)) do + %Sonata.Expr.Call{name: "poly_contain", arguments: [var1, var2]} + end + @doc("implementation of @> operator") + def(poly_contain_pt(var1, var2)) do + %Sonata.Expr.Call{name: "poly_contain_pt", arguments: [var1, var2]} + end + @doc("implementation of <@ operator") + def(poly_contained(var1, var2)) do + %Sonata.Expr.Call{name: "poly_contained", arguments: [var1, var2]} + end + @doc("implementation of <-> operator") + def(poly_distance(var1, var2)) do + %Sonata.Expr.Call{name: "poly_distance", arguments: [var1, var2]} + end + @doc("I/O") + def(poly_in(var1)) do + %Sonata.Expr.Call{name: "poly_in", arguments: [var1]} + end + @doc("implementation of << operator") + def(poly_left(var1, var2)) do + %Sonata.Expr.Call{name: "poly_left", arguments: [var1, var2]} + end + @doc("implementation of # operator") + def(poly_npoints(var1)) do + %Sonata.Expr.Call{name: "poly_npoints", arguments: [var1]} + end + @doc("I/O") + def(poly_out(var1)) do + %Sonata.Expr.Call{name: "poly_out", arguments: [var1]} + end + @doc("implementation of |&> operator") + def(poly_overabove(var1, var2)) do + %Sonata.Expr.Call{name: "poly_overabove", arguments: [var1, var2]} + end + @doc("implementation of &<| operator") + def(poly_overbelow(var1, var2)) do + %Sonata.Expr.Call{name: "poly_overbelow", arguments: [var1, var2]} + end + @doc("implementation of && operator") + def(poly_overlap(var1, var2)) do + %Sonata.Expr.Call{name: "poly_overlap", arguments: [var1, var2]} + end + @doc("implementation of &< operator") + def(poly_overleft(var1, var2)) do + %Sonata.Expr.Call{name: "poly_overleft", arguments: [var1, var2]} + end + @doc("implementation of &> operator") + def(poly_overright(var1, var2)) do + %Sonata.Expr.Call{name: "poly_overright", arguments: [var1, var2]} + end + @doc("I/O") + def(poly_recv(var1)) do + %Sonata.Expr.Call{name: "poly_recv", arguments: [var1]} + end + @doc("implementation of >> operator") + def(poly_right(var1, var2)) do + %Sonata.Expr.Call{name: "poly_right", arguments: [var1, var2]} + end + @doc("implementation of ~= operator") + def(poly_same(var1, var2)) do + %Sonata.Expr.Call{name: "poly_same", arguments: [var1, var2]} + end + @doc("I/O") + def(poly_send(var1)) do + %Sonata.Expr.Call{name: "poly_send", arguments: [var1]} + end + @doc("convert path to polygon") + def(polygon(var1)) do + %Sonata.Expr.Call{name: "polygon", arguments: [var1]} + end + @doc("open path") + def(popen(var1)) do + %Sonata.Expr.Call{name: "popen", arguments: [var1]} + end + @doc("position of sub-bitstring") + def(position(var1, var2)) do + %Sonata.Expr.Call{name: "position", arguments: [var1, var2]} + end + @doc("join selectivity for position-comparison operators") + def(positionjoinsel(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "positionjoinsel", arguments: [var1, var2, var3, var4, var5]} + end + @doc("restriction selectivity for position-comparison operators") + def(positionsel(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "positionsel", arguments: [var1, var2, var3, var4]} + end + @doc("(internal)") + def(postgresql_fdw_validator(var1, var2)) do + %Sonata.Expr.Call{name: "postgresql_fdw_validator", arguments: [var1, var2]} + end + @doc("exponentiation") + def(pow(var1, var2)) do + %Sonata.Expr.Call{name: "pow", arguments: [var1, var2]} + end + @doc("exponentiation") + def(power(var1, var2)) do + %Sonata.Expr.Call{name: "power", arguments: [var1, var2]} + end + @doc("(internal)") + def(prsd_end(var1)) do + %Sonata.Expr.Call{name: "prsd_end", arguments: [var1]} + end + @doc("(internal)") + def(prsd_headline(var1, var2, var3)) do + %Sonata.Expr.Call{name: "prsd_headline", arguments: [var1, var2, var3]} + end + @doc("(internal)") + def(prsd_lextype(var1)) do + %Sonata.Expr.Call{name: "prsd_lextype", arguments: [var1]} + end + @doc("(internal)") + def(prsd_nexttoken(var1, var2, var3)) do + %Sonata.Expr.Call{name: "prsd_nexttoken", arguments: [var1, var2, var3]} + end + @doc("(internal)") + def(prsd_start(var1, var2)) do + %Sonata.Expr.Call{name: "prsd_start", arguments: [var1, var2]} + end + @doc("implementation of <@ operator") + def(pt_contained_circle(var1, var2)) do + %Sonata.Expr.Call{name: "pt_contained_circle", arguments: [var1, var2]} + end + @doc("implementation of <@ operator") + def(pt_contained_poly(var1, var2)) do + %Sonata.Expr.Call{name: "pt_contained_poly", arguments: [var1, var2]} + end + @doc("map query result to XML") + def(query_to_xml(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "query_to_xml", arguments: [var1, var2, var3, var4]} + end + @doc("map query result and structure to XML and XML Schema") + def(query_to_xml_and_xmlschema(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "query_to_xml_and_xmlschema", arguments: [var1, var2, var3, var4]} + end + @doc("map query result structure to XML Schema") + def(query_to_xmlschema(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "query_to_xmlschema", arguments: [var1, var2, var3, var4]} + end + @doc("show real useful query for GiST index") + def(querytree(var1)) do + %Sonata.Expr.Call{name: "querytree", arguments: [var1]} + end + @doc("quote an identifier for usage in a querystring") + def(quote_ident(var1)) do + %Sonata.Expr.Call{name: "quote_ident", arguments: [var1]} + end + @doc("quote a literal for usage in a querystring") + def(quote_literal(var1)) do + %Sonata.Expr.Call{name: "quote_literal", arguments: [var1]} + end + @doc("quote a possibly-null literal for usage in a querystring") + def(quote_nullable(var1)) do + %Sonata.Expr.Call{name: "quote_nullable", arguments: [var1]} + end + @doc("degrees to radians") + def(radians(var1)) do + %Sonata.Expr.Call{name: "radians", arguments: [var1]} + end + @doc("radius of circle") + def(radius(var1)) do + %Sonata.Expr.Call{name: "radius", arguments: [var1]} + end + @doc("random value") + def(random()) do + %Sonata.Expr.Call{name: "random", arguments: []} + end + @doc("implementation of -|- operator") + def(range_adjacent(var1, var2)) do + %Sonata.Expr.Call{name: "range_adjacent", arguments: [var1, var2]} + end + @doc("implementation of >> operator") + def(range_after(var1, var2)) do + %Sonata.Expr.Call{name: "range_after", arguments: [var1, var2]} + end + @doc("implementation of << operator") + def(range_before(var1, var2)) do + %Sonata.Expr.Call{name: "range_before", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(range_cmp(var1, var2)) do + %Sonata.Expr.Call{name: "range_cmp", arguments: [var1, var2]} + end + @doc("implementation of <@ operator") + def(range_contained_by(var1, var2)) do + %Sonata.Expr.Call{name: "range_contained_by", arguments: [var1, var2]} + end + @doc("implementation of @> operator") + def(range_contains(var1, var2)) do + %Sonata.Expr.Call{name: "range_contains", arguments: [var1, var2]} + end + @doc("implementation of @> operator") + def(range_contains_elem(var1, var2)) do + %Sonata.Expr.Call{name: "range_contains_elem", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(range_eq(var1, var2)) do + %Sonata.Expr.Call{name: "range_eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(range_ge(var1, var2)) do + %Sonata.Expr.Call{name: "range_ge", arguments: [var1, var2]} + end + @doc("GiST support") + def(range_gist_compress(var1)) do + %Sonata.Expr.Call{name: "range_gist_compress", arguments: [var1]} + end + @doc("GiST support") + def(range_gist_consistent(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "range_gist_consistent", arguments: [var1, var2, var3, var4, var5]} + end + @doc("GiST support") + def(range_gist_decompress(var1)) do + %Sonata.Expr.Call{name: "range_gist_decompress", arguments: [var1]} + end + @doc("GiST support") + def(range_gist_fetch(var1)) do + %Sonata.Expr.Call{name: "range_gist_fetch", arguments: [var1]} + end + @doc("GiST support") + def(range_gist_penalty(var1, var2, var3)) do + %Sonata.Expr.Call{name: "range_gist_penalty", arguments: [var1, var2, var3]} + end + @doc("GiST support") + def(range_gist_picksplit(var1, var2)) do + %Sonata.Expr.Call{name: "range_gist_picksplit", arguments: [var1, var2]} + end + @doc("GiST support") + def(range_gist_same(var1, var2, var3)) do + %Sonata.Expr.Call{name: "range_gist_same", arguments: [var1, var2, var3]} + end + @doc("GiST support") + def(range_gist_union(var1, var2)) do + %Sonata.Expr.Call{name: "range_gist_union", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(range_gt(var1, var2)) do + %Sonata.Expr.Call{name: "range_gt", arguments: [var1, var2]} + end + @doc("I/O") + def(range_in(var1, var2, var3)) do + %Sonata.Expr.Call{name: "range_in", arguments: [var1, var2, var3]} + end + @doc("implementation of * operator") + def(range_intersect(var1, var2)) do + %Sonata.Expr.Call{name: "range_intersect", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(range_le(var1, var2)) do + %Sonata.Expr.Call{name: "range_le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(range_lt(var1, var2)) do + %Sonata.Expr.Call{name: "range_lt", arguments: [var1, var2]} + end + @doc("the smallest range which includes both of the given ranges") + def(range_merge(var1, var2)) do + %Sonata.Expr.Call{name: "range_merge", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(range_minus(var1, var2)) do + %Sonata.Expr.Call{name: "range_minus", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(range_ne(var1, var2)) do + %Sonata.Expr.Call{name: "range_ne", arguments: [var1, var2]} + end + @doc("I/O") + def(range_out(var1)) do + %Sonata.Expr.Call{name: "range_out", arguments: [var1]} + end + @doc("implementation of && operator") + def(range_overlaps(var1, var2)) do + %Sonata.Expr.Call{name: "range_overlaps", arguments: [var1, var2]} + end + @doc("implementation of &< operator") + def(range_overleft(var1, var2)) do + %Sonata.Expr.Call{name: "range_overleft", arguments: [var1, var2]} + end + @doc("implementation of &> operator") + def(range_overright(var1, var2)) do + %Sonata.Expr.Call{name: "range_overright", arguments: [var1, var2]} + end + @doc("I/O") + def(range_recv(var1, var2, var3)) do + %Sonata.Expr.Call{name: "range_recv", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(range_send(var1)) do + %Sonata.Expr.Call{name: "range_send", arguments: [var1]} + end + @doc("range typanalyze") + def(range_typanalyze(var1)) do + %Sonata.Expr.Call{name: "range_typanalyze", arguments: [var1]} + end + @doc("implementation of + operator") + def(range_union(var1, var2)) do + %Sonata.Expr.Call{name: "range_union", arguments: [var1, var2]} + end + @doc("restriction selectivity for range operators") + def(rangesel(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "rangesel", arguments: [var1, var2, var3, var4]} + end + @doc("integer rank with gaps") + def(rank()) do + %Sonata.Expr.Call{name: "rank", arguments: []} + end + @doc("aggregate final function") + def(rank_final(var1, var2)) do + %Sonata.Expr.Call{name: "rank_final", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(record_eq(var1, var2)) do + %Sonata.Expr.Call{name: "record_eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(record_ge(var1, var2)) do + %Sonata.Expr.Call{name: "record_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(record_gt(var1, var2)) do + %Sonata.Expr.Call{name: "record_gt", arguments: [var1, var2]} + end + @doc("implementation of *= operator") + def(record_image_eq(var1, var2)) do + %Sonata.Expr.Call{name: "record_image_eq", arguments: [var1, var2]} + end + @doc("implementation of *>= operator") + def(record_image_ge(var1, var2)) do + %Sonata.Expr.Call{name: "record_image_ge", arguments: [var1, var2]} + end + @doc("implementation of *> operator") + def(record_image_gt(var1, var2)) do + %Sonata.Expr.Call{name: "record_image_gt", arguments: [var1, var2]} + end + @doc("implementation of *<= operator") + def(record_image_le(var1, var2)) do + %Sonata.Expr.Call{name: "record_image_le", arguments: [var1, var2]} + end + @doc("implementation of *< operator") + def(record_image_lt(var1, var2)) do + %Sonata.Expr.Call{name: "record_image_lt", arguments: [var1, var2]} + end + @doc("implementation of *<> operator") + def(record_image_ne(var1, var2)) do + %Sonata.Expr.Call{name: "record_image_ne", arguments: [var1, var2]} + end + @doc("I/O") + def(record_in(var1, var2, var3)) do + %Sonata.Expr.Call{name: "record_in", arguments: [var1, var2, var3]} + end + @doc("implementation of <= operator") + def(record_le(var1, var2)) do + %Sonata.Expr.Call{name: "record_le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(record_lt(var1, var2)) do + %Sonata.Expr.Call{name: "record_lt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(record_ne(var1, var2)) do + %Sonata.Expr.Call{name: "record_ne", arguments: [var1, var2]} + end + @doc("I/O") + def(record_out(var1)) do + %Sonata.Expr.Call{name: "record_out", arguments: [var1]} + end + @doc("I/O") + def(record_recv(var1, var2, var3)) do + %Sonata.Expr.Call{name: "record_recv", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(record_send(var1)) do + %Sonata.Expr.Call{name: "record_send", arguments: [var1]} + end + @doc("convert text to regclass") + def(regclass(var1)) do + %Sonata.Expr.Call{name: "regclass", arguments: [var1]} + end + @doc("I/O") + def(regclassin(var1)) do + %Sonata.Expr.Call{name: "regclassin", arguments: [var1]} + end + @doc("I/O") + def(regclassout(var1)) do + %Sonata.Expr.Call{name: "regclassout", arguments: [var1]} + end + @doc("I/O") + def(regclassrecv(var1)) do + %Sonata.Expr.Call{name: "regclassrecv", arguments: [var1]} + end + @doc("I/O") + def(regclasssend(var1)) do + %Sonata.Expr.Call{name: "regclasssend", arguments: [var1]} + end + @doc("I/O") + def(regconfigin(var1)) do + %Sonata.Expr.Call{name: "regconfigin", arguments: [var1]} + end + @doc("I/O") + def(regconfigout(var1)) do + %Sonata.Expr.Call{name: "regconfigout", arguments: [var1]} + end + @doc("I/O") + def(regconfigrecv(var1)) do + %Sonata.Expr.Call{name: "regconfigrecv", arguments: [var1]} + end + @doc("I/O") + def(regconfigsend(var1)) do + %Sonata.Expr.Call{name: "regconfigsend", arguments: [var1]} + end + @doc("I/O") + def(regdictionaryin(var1)) do + %Sonata.Expr.Call{name: "regdictionaryin", arguments: [var1]} + end + @doc("I/O") + def(regdictionaryout(var1)) do + %Sonata.Expr.Call{name: "regdictionaryout", arguments: [var1]} + end + @doc("I/O") + def(regdictionaryrecv(var1)) do + %Sonata.Expr.Call{name: "regdictionaryrecv", arguments: [var1]} + end + @doc("I/O") + def(regdictionarysend(var1)) do + %Sonata.Expr.Call{name: "regdictionarysend", arguments: [var1]} + end + @doc("join selectivity of regex match") + def(regexeqjoinsel(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "regexeqjoinsel", arguments: [var1, var2, var3, var4, var5]} + end + @doc("restriction selectivity of regex match") + def(regexeqsel(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "regexeqsel", arguments: [var1, var2, var3, var4]} + end + @doc("join selectivity of regex non-match") + def(regexnejoinsel(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "regexnejoinsel", arguments: [var1, var2, var3, var4, var5]} + end + @doc("restriction selectivity of regex non-match") + def(regexnesel(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "regexnesel", arguments: [var1, var2, var3, var4]} + end + @doc("find all match groups for regexp") + def(regexp_matches(var1, var2, var3)) do + %Sonata.Expr.Call{name: "regexp_matches", arguments: [var1, var2, var3]} + end + @doc("replace text using regexp") + def(regexp_replace(var1, var2, var3)) do + %Sonata.Expr.Call{name: "regexp_replace", arguments: [var1, var2, var3]} + end + @doc("split string by pattern") + def(regexp_split_to_array(var1, var2, var3)) do + %Sonata.Expr.Call{name: "regexp_split_to_array", arguments: [var1, var2, var3]} + end + @doc("split string by pattern") + def(regexp_split_to_table(var1, var2)) do + %Sonata.Expr.Call{name: "regexp_split_to_table", arguments: [var1, var2]} + end + @doc("I/O") + def(regnamespacein(var1)) do + %Sonata.Expr.Call{name: "regnamespacein", arguments: [var1]} + end + @doc("I/O") + def(regnamespaceout(var1)) do + %Sonata.Expr.Call{name: "regnamespaceout", arguments: [var1]} + end + @doc("I/O") + def(regnamespacerecv(var1)) do + %Sonata.Expr.Call{name: "regnamespacerecv", arguments: [var1]} + end + @doc("I/O") + def(regnamespacesend(var1)) do + %Sonata.Expr.Call{name: "regnamespacesend", arguments: [var1]} + end + @doc("I/O") + def(regoperatorin(var1)) do + %Sonata.Expr.Call{name: "regoperatorin", arguments: [var1]} + end + @doc("I/O") + def(regoperatorout(var1)) do + %Sonata.Expr.Call{name: "regoperatorout", arguments: [var1]} + end + @doc("I/O") + def(regoperatorrecv(var1)) do + %Sonata.Expr.Call{name: "regoperatorrecv", arguments: [var1]} + end + @doc("I/O") + def(regoperatorsend(var1)) do + %Sonata.Expr.Call{name: "regoperatorsend", arguments: [var1]} + end + @doc("I/O") + def(regoperin(var1)) do + %Sonata.Expr.Call{name: "regoperin", arguments: [var1]} + end + @doc("I/O") + def(regoperout(var1)) do + %Sonata.Expr.Call{name: "regoperout", arguments: [var1]} + end + @doc("I/O") + def(regoperrecv(var1)) do + %Sonata.Expr.Call{name: "regoperrecv", arguments: [var1]} + end + @doc("I/O") + def(regopersend(var1)) do + %Sonata.Expr.Call{name: "regopersend", arguments: [var1]} + end + @doc("I/O") + def(regprocedurein(var1)) do + %Sonata.Expr.Call{name: "regprocedurein", arguments: [var1]} + end + @doc("I/O") + def(regprocedureout(var1)) do + %Sonata.Expr.Call{name: "regprocedureout", arguments: [var1]} + end + @doc("I/O") + def(regprocedurerecv(var1)) do + %Sonata.Expr.Call{name: "regprocedurerecv", arguments: [var1]} + end + @doc("I/O") + def(regproceduresend(var1)) do + %Sonata.Expr.Call{name: "regproceduresend", arguments: [var1]} + end + @doc("I/O") + def(regprocin(var1)) do + %Sonata.Expr.Call{name: "regprocin", arguments: [var1]} + end + @doc("I/O") + def(regprocout(var1)) do + %Sonata.Expr.Call{name: "regprocout", arguments: [var1]} + end + @doc("I/O") + def(regprocrecv(var1)) do + %Sonata.Expr.Call{name: "regprocrecv", arguments: [var1]} + end + @doc("I/O") + def(regprocsend(var1)) do + %Sonata.Expr.Call{name: "regprocsend", arguments: [var1]} + end + @doc("average of the independent variable (sum(X)/N)") + def(regr_avgx(var1, var2)) do + %Sonata.Expr.Call{name: "regr_avgx", arguments: [var1, var2]} + end + @doc("average of the dependent variable (sum(Y)/N)") + def(regr_avgy(var1, var2)) do + %Sonata.Expr.Call{name: "regr_avgy", arguments: [var1, var2]} + end + @doc("number of input rows in which both expressions are not null") + def(regr_count(var1, var2)) do + %Sonata.Expr.Call{name: "regr_count", arguments: [var1, var2]} + end + @doc("y-intercept of the least-squares-fit linear equation determined by the (X, Y) pairs") + def(regr_intercept(var1, var2)) do + %Sonata.Expr.Call{name: "regr_intercept", arguments: [var1, var2]} + end + @doc("square of the correlation coefficient") + def(regr_r2(var1, var2)) do + %Sonata.Expr.Call{name: "regr_r2", arguments: [var1, var2]} + end + @doc("slope of the least-squares-fit linear equation determined by the (X, Y) pairs") + def(regr_slope(var1, var2)) do + %Sonata.Expr.Call{name: "regr_slope", arguments: [var1, var2]} + end + @doc("sum of squares of the independent variable (sum(X^2) - sum(X)^2/N)") + def(regr_sxx(var1, var2)) do + %Sonata.Expr.Call{name: "regr_sxx", arguments: [var1, var2]} + end + @doc("sum of products of independent times dependent variable (sum(X*Y) - sum(X) * sum(Y)/N)") + def(regr_sxy(var1, var2)) do + %Sonata.Expr.Call{name: "regr_sxy", arguments: [var1, var2]} + end + @doc("sum of squares of the dependent variable (sum(Y^2) - sum(Y)^2/N)") + def(regr_syy(var1, var2)) do + %Sonata.Expr.Call{name: "regr_syy", arguments: [var1, var2]} + end + @doc("I/O") + def(regrolein(var1)) do + %Sonata.Expr.Call{name: "regrolein", arguments: [var1]} + end + @doc("I/O") + def(regroleout(var1)) do + %Sonata.Expr.Call{name: "regroleout", arguments: [var1]} + end + @doc("I/O") + def(regrolerecv(var1)) do + %Sonata.Expr.Call{name: "regrolerecv", arguments: [var1]} + end + @doc("I/O") + def(regrolesend(var1)) do + %Sonata.Expr.Call{name: "regrolesend", arguments: [var1]} + end + @doc("I/O") + def(regtypein(var1)) do + %Sonata.Expr.Call{name: "regtypein", arguments: [var1]} + end + @doc("I/O") + def(regtypeout(var1)) do + %Sonata.Expr.Call{name: "regtypeout", arguments: [var1]} + end + @doc("I/O") + def(regtyperecv(var1)) do + %Sonata.Expr.Call{name: "regtyperecv", arguments: [var1]} + end + @doc("I/O") + def(regtypesend(var1)) do + %Sonata.Expr.Call{name: "regtypesend", arguments: [var1]} + end + @doc("convert interval to reltime") + def(reltime(var1)) do + %Sonata.Expr.Call{name: "reltime", arguments: [var1]} + end + @doc("implementation of = operator") + def(reltimeeq(var1, var2)) do + %Sonata.Expr.Call{name: "reltimeeq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(reltimege(var1, var2)) do + %Sonata.Expr.Call{name: "reltimege", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(reltimegt(var1, var2)) do + %Sonata.Expr.Call{name: "reltimegt", arguments: [var1, var2]} + end + @doc("I/O") + def(reltimein(var1)) do + %Sonata.Expr.Call{name: "reltimein", arguments: [var1]} + end + @doc("implementation of <= operator") + def(reltimele(var1, var2)) do + %Sonata.Expr.Call{name: "reltimele", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(reltimelt(var1, var2)) do + %Sonata.Expr.Call{name: "reltimelt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(reltimene(var1, var2)) do + %Sonata.Expr.Call{name: "reltimene", arguments: [var1, var2]} + end + @doc("I/O") + def(reltimeout(var1)) do + %Sonata.Expr.Call{name: "reltimeout", arguments: [var1]} + end + @doc("I/O") + def(reltimerecv(var1)) do + %Sonata.Expr.Call{name: "reltimerecv", arguments: [var1]} + end + @doc("I/O") + def(reltimesend(var1)) do + %Sonata.Expr.Call{name: "reltimesend", arguments: [var1]} + end + @doc("replicate string n times") + def(repeat(var1, var2)) do + %Sonata.Expr.Call{name: "repeat", arguments: [var1, var2]} + end + @doc("replace all occurrences in string of old_substr with new_substr") + def(replace(var1, var2, var3)) do + %Sonata.Expr.Call{name: "replace", arguments: [var1, var2, var3]} + end + @doc("reverse text") + def(reverse(var1)) do + %Sonata.Expr.Call{name: "reverse", arguments: [var1]} + end + @doc("extract the last n characters") + def(right(var1, var2)) do + %Sonata.Expr.Call{name: "right", arguments: [var1, var2]} + end + @doc("value rounded to 'scale' of zero") + def(round(var1)) do + %Sonata.Expr.Call{name: "round", arguments: [var1]} + end + @doc("row number within partition") + def(row_number()) do + %Sonata.Expr.Call{name: "row_number", arguments: []} + end + @doc("row security for current context active on table by table name") + def(row_security_active(var1)) do + %Sonata.Expr.Call{name: "row_security_active", arguments: [var1]} + end + @doc("map row to json") + def(row_to_json(var1)) do + %Sonata.Expr.Call{name: "row_to_json", arguments: [var1]} + end + @doc("right-pad string to length") + def(rpad(var1, var2, var3)) do + %Sonata.Expr.Call{name: "rpad", arguments: [var1, var2, var3]} + end + @doc("trim selected characters from right end of string") + def(rtrim(var1, var2)) do + %Sonata.Expr.Call{name: "rtrim", arguments: [var1, var2]} + end + @doc("join selectivity of > and related operators on scalar datatypes") + def(scalargtjoinsel(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "scalargtjoinsel", arguments: [var1, var2, var3, var4, var5]} + end + @doc("restriction selectivity of > and related operators on scalar datatypes") + def(scalargtsel(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "scalargtsel", arguments: [var1, var2, var3, var4]} + end + @doc("join selectivity of < and related operators on scalar datatypes") + def(scalarltjoinsel(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "scalarltjoinsel", arguments: [var1, var2, var3, var4, var5]} + end + @doc("restriction selectivity of < and related operators on scalar datatypes") + def(scalarltsel(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "scalarltsel", arguments: [var1, var2, var3, var4]} + end + @doc("map schema contents to XML") + def(schema_to_xml(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "schema_to_xml", arguments: [var1, var2, var3, var4]} + end + @doc("map schema contents and structure to XML and XML Schema") + def(schema_to_xml_and_xmlschema(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "schema_to_xml_and_xmlschema", arguments: [var1, var2, var3, var4]} + end + @doc("map schema structure to XML Schema") + def(schema_to_xmlschema(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "schema_to_xmlschema", arguments: [var1, var2, var3, var4]} + end + @doc("session user name") + def(session_user()) do + %Sonata.Expr.Call{name: "session_user", arguments: []} + end + @doc("set bit") + def(set_bit(var1, var2, var3)) do + %Sonata.Expr.Call{name: "set_bit", arguments: [var1, var2, var3]} + end + @doc("set byte") + def(set_byte(var1, var2, var3)) do + %Sonata.Expr.Call{name: "set_byte", arguments: [var1, var2, var3]} + end + @doc("SET X as a function") + def(set_config(var1, var2, var3)) do + %Sonata.Expr.Call{name: "set_config", arguments: [var1, var2, var3]} + end + @doc("change netmask of cidr") + def(set_masklen(var1, var2)) do + %Sonata.Expr.Call{name: "set_masklen", arguments: [var1, var2]} + end + @doc("set random seed") + def(setseed(var1)) do + %Sonata.Expr.Call{name: "setseed", arguments: [var1]} + end + @doc("set sequence value and is_called status") + def(setval(var1, var2, var3)) do + %Sonata.Expr.Call{name: "setval", arguments: [var1, var2, var3]} + end + @doc("set weight of lexeme's entries") + def(setweight(var1, var2)) do + %Sonata.Expr.Call{name: "setweight", arguments: [var1, var2]} + end + @doc("I/O") + def(shell_in(var1)) do + %Sonata.Expr.Call{name: "shell_in", arguments: [var1]} + end + @doc("I/O") + def(shell_out(var1)) do + %Sonata.Expr.Call{name: "shell_out", arguments: [var1]} + end + @doc("internal conversion function for SHIFT_JIS_2004 to EUC_JIS_2004") + def(shift_jis_2004_to_euc_jis_2004(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "shift_jis_2004_to_euc_jis_2004", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for SHIFT_JIS_2004 to UTF8") + def(shift_jis_2004_to_utf8(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "shift_jis_2004_to_utf8", arguments: [var1, var2, var3, var4, var5]} + end + @doc("get description for object id and shared catalog name") + def(shobj_description(var1, var2)) do + %Sonata.Expr.Call{name: "shobj_description", arguments: [var1, var2]} + end + @doc("sign of value") + def(sign(var1)) do + %Sonata.Expr.Call{name: "sign", arguments: [var1]} + end + @doc("convert SQL99 regexp pattern to POSIX style") + def(similar_escape(var1, var2)) do + %Sonata.Expr.Call{name: "similar_escape", arguments: [var1, var2]} + end + @doc("sine") + def(sin(var1)) do + %Sonata.Expr.Call{name: "sin", arguments: [var1]} + end + @doc("internal conversion function for SJIS to EUC_JP") + def(sjis_to_euc_jp(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "sjis_to_euc_jp", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for SJIS to MULE_INTERNAL") + def(sjis_to_mic(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "sjis_to_mic", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for SJIS to UTF8") + def(sjis_to_utf8(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "sjis_to_utf8", arguments: [var1, var2, var3, var4, var5]} + end + @doc("slope between points") + def(slope(var1, var2)) do + %Sonata.Expr.Call{name: "slope", arguments: [var1, var2]} + end + @doc("storage manager") + def(smgreq(var1, var2)) do + %Sonata.Expr.Call{name: "smgreq", arguments: [var1, var2]} + end + @doc("I/O") + def(smgrin(var1)) do + %Sonata.Expr.Call{name: "smgrin", arguments: [var1]} + end + @doc("storage manager") + def(smgrne(var1, var2)) do + %Sonata.Expr.Call{name: "smgrne", arguments: [var1, var2]} + end + @doc("I/O") + def(smgrout(var1)) do + %Sonata.Expr.Call{name: "smgrout", arguments: [var1]} + end + @doc("SP-GiST support for k-d tree over point") + def(spg_kd_choose(var1, var2)) do + %Sonata.Expr.Call{name: "spg_kd_choose", arguments: [var1, var2]} + end + @doc("SP-GiST support for k-d tree over point") + def(spg_kd_config(var1, var2)) do + %Sonata.Expr.Call{name: "spg_kd_config", arguments: [var1, var2]} + end + @doc("SP-GiST support for k-d tree over point") + def(spg_kd_inner_consistent(var1, var2)) do + %Sonata.Expr.Call{name: "spg_kd_inner_consistent", arguments: [var1, var2]} + end + @doc("SP-GiST support for k-d tree over point") + def(spg_kd_picksplit(var1, var2)) do + %Sonata.Expr.Call{name: "spg_kd_picksplit", arguments: [var1, var2]} + end + @doc("SP-GiST support for quad tree over point") + def(spg_quad_choose(var1, var2)) do + %Sonata.Expr.Call{name: "spg_quad_choose", arguments: [var1, var2]} + end + @doc("SP-GiST support for quad tree over point") + def(spg_quad_config(var1, var2)) do + %Sonata.Expr.Call{name: "spg_quad_config", arguments: [var1, var2]} + end + @doc("SP-GiST support for quad tree over point") + def(spg_quad_inner_consistent(var1, var2)) do + %Sonata.Expr.Call{name: "spg_quad_inner_consistent", arguments: [var1, var2]} + end + @doc("SP-GiST support for quad tree and k-d tree over point") + def(spg_quad_leaf_consistent(var1, var2)) do + %Sonata.Expr.Call{name: "spg_quad_leaf_consistent", arguments: [var1, var2]} + end + @doc("SP-GiST support for quad tree over point") + def(spg_quad_picksplit(var1, var2)) do + %Sonata.Expr.Call{name: "spg_quad_picksplit", arguments: [var1, var2]} + end + @doc("SP-GiST support for quad tree over range") + def(spg_range_quad_choose(var1, var2)) do + %Sonata.Expr.Call{name: "spg_range_quad_choose", arguments: [var1, var2]} + end + @doc("SP-GiST support for quad tree over range") + def(spg_range_quad_config(var1, var2)) do + %Sonata.Expr.Call{name: "spg_range_quad_config", arguments: [var1, var2]} + end + @doc("SP-GiST support for quad tree over range") + def(spg_range_quad_inner_consistent(var1, var2)) do + %Sonata.Expr.Call{name: "spg_range_quad_inner_consistent", arguments: [var1, var2]} + end + @doc("SP-GiST support for quad tree over range") + def(spg_range_quad_leaf_consistent(var1, var2)) do + %Sonata.Expr.Call{name: "spg_range_quad_leaf_consistent", arguments: [var1, var2]} + end + @doc("SP-GiST support for quad tree over range") + def(spg_range_quad_picksplit(var1, var2)) do + %Sonata.Expr.Call{name: "spg_range_quad_picksplit", arguments: [var1, var2]} + end + @doc("SP-GiST support for radix tree over text") + def(spg_text_choose(var1, var2)) do + %Sonata.Expr.Call{name: "spg_text_choose", arguments: [var1, var2]} + end + @doc("SP-GiST support for radix tree over text") + def(spg_text_config(var1, var2)) do + %Sonata.Expr.Call{name: "spg_text_config", arguments: [var1, var2]} + end + @doc("SP-GiST support for radix tree over text") + def(spg_text_inner_consistent(var1, var2)) do + %Sonata.Expr.Call{name: "spg_text_inner_consistent", arguments: [var1, var2]} + end + @doc("SP-GiST support for radix tree over text") + def(spg_text_leaf_consistent(var1, var2)) do + %Sonata.Expr.Call{name: "spg_text_leaf_consistent", arguments: [var1, var2]} + end + @doc("SP-GiST support for radix tree over text") + def(spg_text_picksplit(var1, var2)) do + %Sonata.Expr.Call{name: "spg_text_picksplit", arguments: [var1, var2]} + end + @doc("spgist(internal)") + def(spgbeginscan(var1, var2, var3)) do + %Sonata.Expr.Call{name: "spgbeginscan", arguments: [var1, var2, var3]} + end + @doc("spgist(internal)") + def(spgbuild(var1, var2, var3)) do + %Sonata.Expr.Call{name: "spgbuild", arguments: [var1, var2, var3]} + end + @doc("spgist(internal)") + def(spgbuildempty(var1)) do + %Sonata.Expr.Call{name: "spgbuildempty", arguments: [var1]} + end + @doc("spgist(internal)") + def(spgbulkdelete(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "spgbulkdelete", arguments: [var1, var2, var3, var4]} + end + @doc("spgist(internal)") + def(spgcanreturn(var1, var2)) do + %Sonata.Expr.Call{name: "spgcanreturn", arguments: [var1, var2]} + end + @doc("spgist(internal)") + def(spgcostestimate(var1, var2, var3, var4, var5, var6, var7)) do + %Sonata.Expr.Call{name: "spgcostestimate", arguments: [var1, var2, var3, var4, var5, var6, var7]} + end + @doc("spgist(internal)") + def(spgendscan(var1)) do + %Sonata.Expr.Call{name: "spgendscan", arguments: [var1]} + end + @doc("spgist(internal)") + def(spggetbitmap(var1, var2)) do + %Sonata.Expr.Call{name: "spggetbitmap", arguments: [var1, var2]} + end + @doc("spgist(internal)") + def(spggettuple(var1, var2)) do + %Sonata.Expr.Call{name: "spggettuple", arguments: [var1, var2]} + end + @doc("spgist(internal)") + def(spginsert(var1, var2, var3, var4, var5, var6)) do + %Sonata.Expr.Call{name: "spginsert", arguments: [var1, var2, var3, var4, var5, var6]} + end + @doc("spgist(internal)") + def(spgmarkpos(var1)) do + %Sonata.Expr.Call{name: "spgmarkpos", arguments: [var1]} + end + @doc("spgist(internal)") + def(spgoptions(var1, var2)) do + %Sonata.Expr.Call{name: "spgoptions", arguments: [var1, var2]} + end + @doc("spgist(internal)") + def(spgrescan(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "spgrescan", arguments: [var1, var2, var3, var4, var5]} + end + @doc("spgist(internal)") + def(spgrestrpos(var1)) do + %Sonata.Expr.Call{name: "spgrestrpos", arguments: [var1]} + end + @doc("spgist(internal)") + def(spgvacuumcleanup(var1, var2)) do + %Sonata.Expr.Call{name: "spgvacuumcleanup", arguments: [var1, var2]} + end + @doc("split string by field_sep and return field_num") + def(split_part(var1, var2, var3)) do + %Sonata.Expr.Call{name: "split_part", arguments: [var1, var2, var3]} + end + @doc("square root") + def(sqrt(var1)) do + %Sonata.Expr.Call{name: "sqrt", arguments: [var1]} + end + @doc("current statement time") + def(statement_timestamp()) do + %Sonata.Expr.Call{name: "statement_timestamp", arguments: []} + end + @doc("historical alias for stddev_samp") + def(stddev(var1)) do + %Sonata.Expr.Call{name: "stddev", arguments: [var1]} + end + @doc("population standard deviation of float8 input values") + def(stddev_pop(var1)) do + %Sonata.Expr.Call{name: "stddev_pop", arguments: [var1]} + end + @doc("sample standard deviation of bigint input values") + def(stddev_samp(var1)) do + %Sonata.Expr.Call{name: "stddev_samp", arguments: [var1]} + end + @doc("concatenate aggregate input into a bytea") + def(string_agg(var1, var2)) do + %Sonata.Expr.Call{name: "string_agg", arguments: [var1, var2]} + end + @doc("aggregate final function") + def(string_agg_finalfn(var1)) do + %Sonata.Expr.Call{name: "string_agg_finalfn", arguments: [var1]} + end + @doc("aggregate transition function") + def(string_agg_transfn(var1, var2, var3)) do + %Sonata.Expr.Call{name: "string_agg_transfn", arguments: [var1, var2, var3]} + end + @doc("split delimited text into text[], with null string") + def(string_to_array(var1, var2, var3)) do + %Sonata.Expr.Call{name: "string_to_array", arguments: [var1, var2, var3]} + end + @doc("strip position information") + def(strip(var1)) do + %Sonata.Expr.Call{name: "strip", arguments: [var1]} + end + @doc("position of substring") + def(strpos(var1, var2)) do + %Sonata.Expr.Call{name: "strpos", arguments: [var1, var2]} + end + @doc("extract portion of string") + def(substr(var1, var2)) do + %Sonata.Expr.Call{name: "substr", arguments: [var1, var2]} + end + @doc("extract text matching SQL99 regular expression") + def(substring(var1, var2, var3)) do + %Sonata.Expr.Call{name: "substring", arguments: [var1, var2, var3]} + end + @doc("sum as money across all money input values") + def(sum(var1)) do + %Sonata.Expr.Call{name: "sum", arguments: [var1]} + end + @doc("SYSTEM tablesample method handler") + def(system(var1)) do + %Sonata.Expr.Call{name: "system", arguments: [var1]} + end + @doc("map table contents to XML") + def(table_to_xml(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "table_to_xml", arguments: [var1, var2, var3, var4]} + end + @doc("map table contents and structure to XML and XML Schema") + def(table_to_xml_and_xmlschema(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "table_to_xml_and_xmlschema", arguments: [var1, var2, var3, var4]} + end + @doc("map table structure to XML Schema") + def(table_to_xmlschema(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "table_to_xmlschema", arguments: [var1, var2, var3, var4]} + end + @doc("tangent") + def(tan(var1)) do + %Sonata.Expr.Call{name: "tan", arguments: [var1]} + end + @doc("convert char to text") + def(text(var1)) do + %Sonata.Expr.Call{name: "text", arguments: [var1]} + end + @doc("implementation of >= operator") + def(text_ge(var1, var2)) do + %Sonata.Expr.Call{name: "text_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(text_gt(var1, var2)) do + %Sonata.Expr.Call{name: "text_gt", arguments: [var1, var2]} + end + @doc("larger of two") + def(text_larger(var1, var2)) do + %Sonata.Expr.Call{name: "text_larger", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(text_le(var1, var2)) do + %Sonata.Expr.Call{name: "text_le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(text_lt(var1, var2)) do + %Sonata.Expr.Call{name: "text_lt", arguments: [var1, var2]} + end + @doc("implementation of ~>=~ operator") + def(text_pattern_ge(var1, var2)) do + %Sonata.Expr.Call{name: "text_pattern_ge", arguments: [var1, var2]} + end + @doc("implementation of ~>~ operator") + def(text_pattern_gt(var1, var2)) do + %Sonata.Expr.Call{name: "text_pattern_gt", arguments: [var1, var2]} + end + @doc("implementation of ~<=~ operator") + def(text_pattern_le(var1, var2)) do + %Sonata.Expr.Call{name: "text_pattern_le", arguments: [var1, var2]} + end + @doc("implementation of ~<~ operator") + def(text_pattern_lt(var1, var2)) do + %Sonata.Expr.Call{name: "text_pattern_lt", arguments: [var1, var2]} + end + @doc("smaller of two") + def(text_smaller(var1, var2)) do + %Sonata.Expr.Call{name: "text_smaller", arguments: [var1, var2]} + end + @doc("implementation of || operator") + def(textanycat(var1, var2)) do + %Sonata.Expr.Call{name: "textanycat", arguments: [var1, var2]} + end + @doc("implementation of || operator") + def(textcat(var1, var2)) do + %Sonata.Expr.Call{name: "textcat", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(texteq(var1, var2)) do + %Sonata.Expr.Call{name: "texteq", arguments: [var1, var2]} + end + @doc("implementation of ~~* operator") + def(texticlike(var1, var2)) do + %Sonata.Expr.Call{name: "texticlike", arguments: [var1, var2]} + end + @doc("implementation of !~~* operator") + def(texticnlike(var1, var2)) do + %Sonata.Expr.Call{name: "texticnlike", arguments: [var1, var2]} + end + @doc("implementation of ~* operator") + def(texticregexeq(var1, var2)) do + %Sonata.Expr.Call{name: "texticregexeq", arguments: [var1, var2]} + end + @doc("implementation of !~* operator") + def(texticregexne(var1, var2)) do + %Sonata.Expr.Call{name: "texticregexne", arguments: [var1, var2]} + end + @doc("I/O") + def(textin(var1)) do + %Sonata.Expr.Call{name: "textin", arguments: [var1]} + end + @doc("length") + def(textlen(var1)) do + %Sonata.Expr.Call{name: "textlen", arguments: [var1]} + end + @doc("implementation of ~~ operator") + def(textlike(var1, var2)) do + %Sonata.Expr.Call{name: "textlike", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(textne(var1, var2)) do + %Sonata.Expr.Call{name: "textne", arguments: [var1, var2]} + end + @doc("implementation of !~~ operator") + def(textnlike(var1, var2)) do + %Sonata.Expr.Call{name: "textnlike", arguments: [var1, var2]} + end + @doc("I/O") + def(textout(var1)) do + %Sonata.Expr.Call{name: "textout", arguments: [var1]} + end + @doc("I/O") + def(textrecv(var1)) do + %Sonata.Expr.Call{name: "textrecv", arguments: [var1]} + end + @doc("implementation of ~ operator") + def(textregexeq(var1, var2)) do + %Sonata.Expr.Call{name: "textregexeq", arguments: [var1, var2]} + end + @doc("implementation of !~ operator") + def(textregexne(var1, var2)) do + %Sonata.Expr.Call{name: "textregexne", arguments: [var1, var2]} + end + @doc("I/O") + def(textsend(var1)) do + %Sonata.Expr.Call{name: "textsend", arguments: [var1]} + end + @doc("(internal)") + def(thesaurus_init(var1)) do + %Sonata.Expr.Call{name: "thesaurus_init", arguments: [var1]} + end + @doc("(internal)") + def(thesaurus_lexize(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "thesaurus_lexize", arguments: [var1, var2, var3, var4]} + end + @doc("implementation of = operator") + def(tideq(var1, var2)) do + %Sonata.Expr.Call{name: "tideq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(tidge(var1, var2)) do + %Sonata.Expr.Call{name: "tidge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(tidgt(var1, var2)) do + %Sonata.Expr.Call{name: "tidgt", arguments: [var1, var2]} + end + @doc("I/O") + def(tidin(var1)) do + %Sonata.Expr.Call{name: "tidin", arguments: [var1]} + end + @doc("larger of two") + def(tidlarger(var1, var2)) do + %Sonata.Expr.Call{name: "tidlarger", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(tidle(var1, var2)) do + %Sonata.Expr.Call{name: "tidle", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(tidlt(var1, var2)) do + %Sonata.Expr.Call{name: "tidlt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(tidne(var1, var2)) do + %Sonata.Expr.Call{name: "tidne", arguments: [var1, var2]} + end + @doc("I/O") + def(tidout(var1)) do + %Sonata.Expr.Call{name: "tidout", arguments: [var1]} + end + @doc("I/O") + def(tidrecv(var1)) do + %Sonata.Expr.Call{name: "tidrecv", arguments: [var1]} + end + @doc("I/O") + def(tidsend(var1)) do + %Sonata.Expr.Call{name: "tidsend", arguments: [var1]} + end + @doc("smaller of two") + def(tidsmaller(var1, var2)) do + %Sonata.Expr.Call{name: "tidsmaller", arguments: [var1, var2]} + end + @doc("convert timestamp to time") + def(time(var1)) do + %Sonata.Expr.Call{name: "time", arguments: [var1]} + end + @doc("less-equal-greater") + def(time_cmp(var1, var2)) do + %Sonata.Expr.Call{name: "time_cmp", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(time_eq(var1, var2)) do + %Sonata.Expr.Call{name: "time_eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(time_ge(var1, var2)) do + %Sonata.Expr.Call{name: "time_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(time_gt(var1, var2)) do + %Sonata.Expr.Call{name: "time_gt", arguments: [var1, var2]} + end + @doc("hash") + def(time_hash(var1)) do + %Sonata.Expr.Call{name: "time_hash", arguments: [var1]} + end + @doc("I/O") + def(time_in(var1, var2, var3)) do + %Sonata.Expr.Call{name: "time_in", arguments: [var1, var2, var3]} + end + @doc("larger of two") + def(time_larger(var1, var2)) do + %Sonata.Expr.Call{name: "time_larger", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(time_le(var1, var2)) do + %Sonata.Expr.Call{name: "time_le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(time_lt(var1, var2)) do + %Sonata.Expr.Call{name: "time_lt", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(time_mi_interval(var1, var2)) do + %Sonata.Expr.Call{name: "time_mi_interval", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(time_mi_time(var1, var2)) do + %Sonata.Expr.Call{name: "time_mi_time", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(time_ne(var1, var2)) do + %Sonata.Expr.Call{name: "time_ne", arguments: [var1, var2]} + end + @doc("I/O") + def(time_out(var1)) do + %Sonata.Expr.Call{name: "time_out", arguments: [var1]} + end + @doc("implementation of + operator") + def(time_pl_interval(var1, var2)) do + %Sonata.Expr.Call{name: "time_pl_interval", arguments: [var1, var2]} + end + @doc("I/O") + def(time_recv(var1, var2, var3)) do + %Sonata.Expr.Call{name: "time_recv", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(time_send(var1)) do + %Sonata.Expr.Call{name: "time_send", arguments: [var1]} + end + @doc("smaller of two") + def(time_smaller(var1, var2)) do + %Sonata.Expr.Call{name: "time_smaller", arguments: [var1, var2]} + end + @doc("transform a time length coercion") + def(time_transform(var1)) do + %Sonata.Expr.Call{name: "time_transform", arguments: [var1]} + end + @doc("implementation of + operator") + def(timedate_pl(var1, var2)) do + %Sonata.Expr.Call{name: "timedate_pl", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(timemi(var1, var2)) do + %Sonata.Expr.Call{name: "timemi", arguments: [var1, var2]} + end + @doc("current date and time (abstime)") + def(timenow()) do + %Sonata.Expr.Call{name: "timenow", arguments: []} + end + @doc("current date and time - increments during transactions") + def(timeofday()) do + %Sonata.Expr.Call{name: "timeofday", arguments: []} + end + @doc("implementation of + operator") + def(timepl(var1, var2)) do + %Sonata.Expr.Call{name: "timepl", arguments: [var1, var2]} + end + @doc("adjust timestamp precision") + def(timestamp(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(timestamp_cmp(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_cmp", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(timestamp_cmp_date(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_cmp_date", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(timestamp_cmp_timestamptz(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_cmp_timestamptz", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(timestamp_eq(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_eq", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(timestamp_eq_date(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_eq_date", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(timestamp_eq_timestamptz(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_eq_timestamptz", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(timestamp_ge(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_ge", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(timestamp_ge_date(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_ge_date", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(timestamp_ge_timestamptz(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_ge_timestamptz", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(timestamp_gt(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_gt", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(timestamp_gt_date(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_gt_date", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(timestamp_gt_timestamptz(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_gt_timestamptz", arguments: [var1, var2]} + end + @doc("hash") + def(timestamp_hash(var1)) do + %Sonata.Expr.Call{name: "timestamp_hash", arguments: [var1]} + end + @doc("I/O") + def(timestamp_in(var1, var2, var3)) do + %Sonata.Expr.Call{name: "timestamp_in", arguments: [var1, var2, var3]} + end + @doc("transform a time zone adjustment") + def(timestamp_izone_transform(var1)) do + %Sonata.Expr.Call{name: "timestamp_izone_transform", arguments: [var1]} + end + @doc("larger of two") + def(timestamp_larger(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_larger", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(timestamp_le(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_le", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(timestamp_le_date(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_le_date", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(timestamp_le_timestamptz(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_le_timestamptz", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(timestamp_lt(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_lt", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(timestamp_lt_date(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_lt_date", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(timestamp_lt_timestamptz(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_lt_timestamptz", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(timestamp_mi(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_mi", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(timestamp_mi_interval(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_mi_interval", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(timestamp_ne(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_ne", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(timestamp_ne_date(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_ne_date", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(timestamp_ne_timestamptz(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_ne_timestamptz", arguments: [var1, var2]} + end + @doc("I/O") + def(timestamp_out(var1)) do + %Sonata.Expr.Call{name: "timestamp_out", arguments: [var1]} + end + @doc("implementation of + operator") + def(timestamp_pl_interval(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_pl_interval", arguments: [var1, var2]} + end + @doc("I/O") + def(timestamp_recv(var1, var2, var3)) do + %Sonata.Expr.Call{name: "timestamp_recv", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(timestamp_send(var1)) do + %Sonata.Expr.Call{name: "timestamp_send", arguments: [var1]} + end + @doc("smaller of two") + def(timestamp_smaller(var1, var2)) do + %Sonata.Expr.Call{name: "timestamp_smaller", arguments: [var1, var2]} + end + @doc("sort support") + def(timestamp_sortsupport(var1)) do + %Sonata.Expr.Call{name: "timestamp_sortsupport", arguments: [var1]} + end + @doc("transform a timestamp length coercion") + def(timestamp_transform(var1)) do + %Sonata.Expr.Call{name: "timestamp_transform", arguments: [var1]} + end + @doc("transform a time zone adjustment") + def(timestamp_zone_transform(var1)) do + %Sonata.Expr.Call{name: "timestamp_zone_transform", arguments: [var1]} + end + @doc("I/O typmod") + def(timestamptypmodin(var1)) do + %Sonata.Expr.Call{name: "timestamptypmodin", arguments: [var1]} + end + @doc("I/O typmod") + def(timestamptypmodout(var1)) do + %Sonata.Expr.Call{name: "timestamptypmodout", arguments: [var1]} + end + @doc("convert date and time with time zone to timestamp with time zone") + def(timestamptz(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(timestamptz_cmp(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_cmp", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(timestamptz_cmp_date(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_cmp_date", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(timestamptz_cmp_timestamp(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_cmp_timestamp", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(timestamptz_eq(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_eq", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(timestamptz_eq_date(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_eq_date", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(timestamptz_eq_timestamp(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_eq_timestamp", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(timestamptz_ge(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_ge", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(timestamptz_ge_date(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_ge_date", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(timestamptz_ge_timestamp(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_ge_timestamp", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(timestamptz_gt(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_gt", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(timestamptz_gt_date(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_gt_date", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(timestamptz_gt_timestamp(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_gt_timestamp", arguments: [var1, var2]} + end + @doc("I/O") + def(timestamptz_in(var1, var2, var3)) do + %Sonata.Expr.Call{name: "timestamptz_in", arguments: [var1, var2, var3]} + end + @doc("larger of two") + def(timestamptz_larger(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_larger", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(timestamptz_le(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_le", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(timestamptz_le_date(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_le_date", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(timestamptz_le_timestamp(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_le_timestamp", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(timestamptz_lt(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_lt", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(timestamptz_lt_date(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_lt_date", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(timestamptz_lt_timestamp(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_lt_timestamp", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(timestamptz_mi(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_mi", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(timestamptz_mi_interval(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_mi_interval", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(timestamptz_ne(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_ne", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(timestamptz_ne_date(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_ne_date", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(timestamptz_ne_timestamp(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_ne_timestamp", arguments: [var1, var2]} + end + @doc("I/O") + def(timestamptz_out(var1)) do + %Sonata.Expr.Call{name: "timestamptz_out", arguments: [var1]} + end + @doc("implementation of + operator") + def(timestamptz_pl_interval(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_pl_interval", arguments: [var1, var2]} + end + @doc("I/O") + def(timestamptz_recv(var1, var2, var3)) do + %Sonata.Expr.Call{name: "timestamptz_recv", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(timestamptz_send(var1)) do + %Sonata.Expr.Call{name: "timestamptz_send", arguments: [var1]} + end + @doc("smaller of two") + def(timestamptz_smaller(var1, var2)) do + %Sonata.Expr.Call{name: "timestamptz_smaller", arguments: [var1, var2]} + end + @doc("I/O typmod") + def(timestamptztypmodin(var1)) do + %Sonata.Expr.Call{name: "timestamptztypmodin", arguments: [var1]} + end + @doc("I/O typmod") + def(timestamptztypmodout(var1)) do + %Sonata.Expr.Call{name: "timestamptztypmodout", arguments: [var1]} + end + @doc("I/O typmod") + def(timetypmodin(var1)) do + %Sonata.Expr.Call{name: "timetypmodin", arguments: [var1]} + end + @doc("I/O typmod") + def(timetypmodout(var1)) do + %Sonata.Expr.Call{name: "timetypmodout", arguments: [var1]} + end + @doc("adjust time with time zone precision") + def(timetz(var1, var2)) do + %Sonata.Expr.Call{name: "timetz", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(timetz_cmp(var1, var2)) do + %Sonata.Expr.Call{name: "timetz_cmp", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(timetz_eq(var1, var2)) do + %Sonata.Expr.Call{name: "timetz_eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(timetz_ge(var1, var2)) do + %Sonata.Expr.Call{name: "timetz_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(timetz_gt(var1, var2)) do + %Sonata.Expr.Call{name: "timetz_gt", arguments: [var1, var2]} + end + @doc("hash") + def(timetz_hash(var1)) do + %Sonata.Expr.Call{name: "timetz_hash", arguments: [var1]} + end + @doc("I/O") + def(timetz_in(var1, var2, var3)) do + %Sonata.Expr.Call{name: "timetz_in", arguments: [var1, var2, var3]} + end + @doc("larger of two") + def(timetz_larger(var1, var2)) do + %Sonata.Expr.Call{name: "timetz_larger", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(timetz_le(var1, var2)) do + %Sonata.Expr.Call{name: "timetz_le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(timetz_lt(var1, var2)) do + %Sonata.Expr.Call{name: "timetz_lt", arguments: [var1, var2]} + end + @doc("implementation of - operator") + def(timetz_mi_interval(var1, var2)) do + %Sonata.Expr.Call{name: "timetz_mi_interval", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(timetz_ne(var1, var2)) do + %Sonata.Expr.Call{name: "timetz_ne", arguments: [var1, var2]} + end + @doc("I/O") + def(timetz_out(var1)) do + %Sonata.Expr.Call{name: "timetz_out", arguments: [var1]} + end + @doc("implementation of + operator") + def(timetz_pl_interval(var1, var2)) do + %Sonata.Expr.Call{name: "timetz_pl_interval", arguments: [var1, var2]} + end + @doc("I/O") + def(timetz_recv(var1, var2, var3)) do + %Sonata.Expr.Call{name: "timetz_recv", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(timetz_send(var1)) do + %Sonata.Expr.Call{name: "timetz_send", arguments: [var1]} + end + @doc("smaller of two") + def(timetz_smaller(var1, var2)) do + %Sonata.Expr.Call{name: "timetz_smaller", arguments: [var1, var2]} + end + @doc("implementation of + operator") + def(timetzdate_pl(var1, var2)) do + %Sonata.Expr.Call{name: "timetzdate_pl", arguments: [var1, var2]} + end + @doc("I/O typmod") + def(timetztypmodin(var1)) do + %Sonata.Expr.Call{name: "timetztypmodin", arguments: [var1]} + end + @doc("I/O typmod") + def(timetztypmodout(var1)) do + %Sonata.Expr.Call{name: "timetztypmodout", arguments: [var1]} + end + @doc("adjust time with time zone to new zone") + def(timezone(var1, var2)) do + %Sonata.Expr.Call{name: "timezone", arguments: [var1, var2]} + end + @doc("convert to tinterval") + def(tinterval(var1, var2)) do + %Sonata.Expr.Call{name: "tinterval", arguments: [var1, var2]} + end + @doc("implementation of << operator") + def(tintervalct(var1, var2)) do + %Sonata.Expr.Call{name: "tintervalct", arguments: [var1, var2]} + end + @doc("end of interval") + def(tintervalend(var1)) do + %Sonata.Expr.Call{name: "tintervalend", arguments: [var1]} + end + @doc("implementation of = operator") + def(tintervaleq(var1, var2)) do + %Sonata.Expr.Call{name: "tintervaleq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(tintervalge(var1, var2)) do + %Sonata.Expr.Call{name: "tintervalge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(tintervalgt(var1, var2)) do + %Sonata.Expr.Call{name: "tintervalgt", arguments: [var1, var2]} + end + @doc("I/O") + def(tintervalin(var1)) do + %Sonata.Expr.Call{name: "tintervalin", arguments: [var1]} + end + @doc("implementation of <= operator") + def(tintervalle(var1, var2)) do + %Sonata.Expr.Call{name: "tintervalle", arguments: [var1, var2]} + end + @doc("implementation of #= operator") + def(tintervalleneq(var1, var2)) do + %Sonata.Expr.Call{name: "tintervalleneq", arguments: [var1, var2]} + end + @doc("implementation of #>= operator") + def(tintervallenge(var1, var2)) do + %Sonata.Expr.Call{name: "tintervallenge", arguments: [var1, var2]} + end + @doc("implementation of #> operator") + def(tintervallengt(var1, var2)) do + %Sonata.Expr.Call{name: "tintervallengt", arguments: [var1, var2]} + end + @doc("implementation of #<= operator") + def(tintervallenle(var1, var2)) do + %Sonata.Expr.Call{name: "tintervallenle", arguments: [var1, var2]} + end + @doc("implementation of #< operator") + def(tintervallenlt(var1, var2)) do + %Sonata.Expr.Call{name: "tintervallenlt", arguments: [var1, var2]} + end + @doc("implementation of #<> operator") + def(tintervallenne(var1, var2)) do + %Sonata.Expr.Call{name: "tintervallenne", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(tintervallt(var1, var2)) do + %Sonata.Expr.Call{name: "tintervallt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(tintervalne(var1, var2)) do + %Sonata.Expr.Call{name: "tintervalne", arguments: [var1, var2]} + end + @doc("I/O") + def(tintervalout(var1)) do + %Sonata.Expr.Call{name: "tintervalout", arguments: [var1]} + end + @doc("implementation of && operator") + def(tintervalov(var1, var2)) do + %Sonata.Expr.Call{name: "tintervalov", arguments: [var1, var2]} + end + @doc("I/O") + def(tintervalrecv(var1)) do + %Sonata.Expr.Call{name: "tintervalrecv", arguments: [var1]} + end + @doc("tinterval to reltime") + def(tintervalrel(var1)) do + %Sonata.Expr.Call{name: "tintervalrel", arguments: [var1]} + end + @doc("implementation of ~= operator") + def(tintervalsame(var1, var2)) do + %Sonata.Expr.Call{name: "tintervalsame", arguments: [var1, var2]} + end + @doc("I/O") + def(tintervalsend(var1)) do + %Sonata.Expr.Call{name: "tintervalsend", arguments: [var1]} + end + @doc("implementation of | operator") + def(tintervalstart(var1)) do + %Sonata.Expr.Call{name: "tintervalstart", arguments: [var1]} + end + @doc("encode text from encoding to ASCII text") + def(to_ascii(var1, var2)) do + %Sonata.Expr.Call{name: "to_ascii", arguments: [var1, var2]} + end + @doc("format int4 to text") + def(to_char(var1, var2)) do + %Sonata.Expr.Call{name: "to_char", arguments: [var1, var2]} + end + @doc("convert text to date") + def(to_date(var1, var2)) do + %Sonata.Expr.Call{name: "to_date", arguments: [var1, var2]} + end + @doc("convert int4 number to hex") + def(to_hex(var1)) do + %Sonata.Expr.Call{name: "to_hex", arguments: [var1]} + end + @doc("map input to json") + def(to_json(var1)) do + %Sonata.Expr.Call{name: "to_json", arguments: [var1]} + end + @doc("map input to jsonb") + def(to_jsonb(var1)) do + %Sonata.Expr.Call{name: "to_jsonb", arguments: [var1]} + end + @doc("convert text to numeric") + def(to_number(var1, var2)) do + %Sonata.Expr.Call{name: "to_number", arguments: [var1, var2]} + end + @doc("convert classname to regclass") + def(to_regclass(var1)) do + %Sonata.Expr.Call{name: "to_regclass", arguments: [var1]} + end + @doc("convert namespace name to regnamespace") + def(to_regnamespace(var1)) do + %Sonata.Expr.Call{name: "to_regnamespace", arguments: [var1]} + end + @doc("convert operator name to regoper") + def(to_regoper(var1)) do + %Sonata.Expr.Call{name: "to_regoper", arguments: [var1]} + end + @doc("convert operator name to regoperator") + def(to_regoperator(var1)) do + %Sonata.Expr.Call{name: "to_regoperator", arguments: [var1]} + end + @doc("convert proname to regproc") + def(to_regproc(var1)) do + %Sonata.Expr.Call{name: "to_regproc", arguments: [var1]} + end + @doc("convert proname to regprocedure") + def(to_regprocedure(var1)) do + %Sonata.Expr.Call{name: "to_regprocedure", arguments: [var1]} + end + @doc("convert role name to regrole") + def(to_regrole(var1)) do + %Sonata.Expr.Call{name: "to_regrole", arguments: [var1]} + end + @doc("convert type name to regtype") + def(to_regtype(var1)) do + %Sonata.Expr.Call{name: "to_regtype", arguments: [var1]} + end + @doc("convert text to timestamp with time zone") + def(to_timestamp(var1, var2)) do + %Sonata.Expr.Call{name: "to_timestamp", arguments: [var1, var2]} + end + @doc("make tsquery") + def(to_tsquery(var1, var2)) do + %Sonata.Expr.Call{name: "to_tsquery", arguments: [var1, var2]} + end + @doc("transform to tsvector") + def(to_tsvector(var1, var2)) do + %Sonata.Expr.Call{name: "to_tsvector", arguments: [var1, var2]} + end + @doc("current transaction time") + def(transaction_timestamp()) do + %Sonata.Expr.Call{name: "transaction_timestamp", arguments: []} + end + @doc("map a set of characters appearing in string") + def(translate(var1, var2, var3)) do + %Sonata.Expr.Call{name: "translate", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(trigger_out(var1)) do + %Sonata.Expr.Call{name: "trigger_out", arguments: [var1]} + end + @doc("MAC manufacturer fields") + def(trunc(var1)) do + %Sonata.Expr.Call{name: "trunc", arguments: [var1]} + end + @doc("debug function for text search configuration") + def(ts_debug(var1, var2)) do + %Sonata.Expr.Call{name: "ts_debug", arguments: [var1, var2]} + end + @doc("generate headline") + def(ts_headline(var1, var2)) do + %Sonata.Expr.Call{name: "ts_headline", arguments: [var1, var2]} + end + @doc("normalize one word by dictionary") + def(ts_lexize(var1, var2)) do + %Sonata.Expr.Call{name: "ts_lexize", arguments: [var1, var2]} + end + @doc("implementation of @@ operator") + def(ts_match_qv(var1, var2)) do + %Sonata.Expr.Call{name: "ts_match_qv", arguments: [var1, var2]} + end + @doc("implementation of @@ operator") + def(ts_match_tq(var1, var2)) do + %Sonata.Expr.Call{name: "ts_match_tq", arguments: [var1, var2]} + end + @doc("implementation of @@ operator") + def(ts_match_tt(var1, var2)) do + %Sonata.Expr.Call{name: "ts_match_tt", arguments: [var1, var2]} + end + @doc("implementation of @@ operator") + def(ts_match_vq(var1, var2)) do + %Sonata.Expr.Call{name: "ts_match_vq", arguments: [var1, var2]} + end + @doc("parse text to tokens") + def(ts_parse(var1, var2)) do + %Sonata.Expr.Call{name: "ts_parse", arguments: [var1, var2]} + end + @doc("relevance") + def(ts_rank(var1, var2, var3)) do + %Sonata.Expr.Call{name: "ts_rank", arguments: [var1, var2, var3]} + end + @doc("relevance") + def(ts_rank_cd(var1, var2, var3)) do + %Sonata.Expr.Call{name: "ts_rank_cd", arguments: [var1, var2, var3]} + end + @doc("rewrite tsquery") + def(ts_rewrite(var1, var2)) do + %Sonata.Expr.Call{name: "ts_rewrite", arguments: [var1, var2]} + end + @doc("statistics of tsvector column") + def(ts_stat(var1)) do + %Sonata.Expr.Call{name: "ts_stat", arguments: [var1]} + end + @doc("get parser's token types") + def(ts_token_type(var1)) do + %Sonata.Expr.Call{name: "ts_token_type", arguments: [var1]} + end + @doc("tsvector typanalyze") + def(ts_typanalyze(var1)) do + %Sonata.Expr.Call{name: "ts_typanalyze", arguments: [var1]} + end + @doc("I/O") + def(tsm_handler_in(var1)) do + %Sonata.Expr.Call{name: "tsm_handler_in", arguments: [var1]} + end + @doc("I/O") + def(tsm_handler_out(var1)) do + %Sonata.Expr.Call{name: "tsm_handler_out", arguments: [var1]} + end + @doc("join selectivity of tsvector @@ tsquery") + def(tsmatchjoinsel(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "tsmatchjoinsel", arguments: [var1, var2, var3, var4, var5]} + end + @doc("restriction selectivity of tsvector @@ tsquery") + def(tsmatchsel(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "tsmatchsel", arguments: [var1, var2, var3, var4]} + end + @doc("implementation of <@ operator") + def(tsq_mcontained(var1, var2)) do + %Sonata.Expr.Call{name: "tsq_mcontained", arguments: [var1, var2]} + end + @doc("implementation of @> operator") + def(tsq_mcontains(var1, var2)) do + %Sonata.Expr.Call{name: "tsq_mcontains", arguments: [var1, var2]} + end + @doc("implementation of && operator") + def(tsquery_and(var1, var2)) do + %Sonata.Expr.Call{name: "tsquery_and", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(tsquery_cmp(var1, var2)) do + %Sonata.Expr.Call{name: "tsquery_cmp", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(tsquery_eq(var1, var2)) do + %Sonata.Expr.Call{name: "tsquery_eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(tsquery_ge(var1, var2)) do + %Sonata.Expr.Call{name: "tsquery_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(tsquery_gt(var1, var2)) do + %Sonata.Expr.Call{name: "tsquery_gt", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(tsquery_le(var1, var2)) do + %Sonata.Expr.Call{name: "tsquery_le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(tsquery_lt(var1, var2)) do + %Sonata.Expr.Call{name: "tsquery_lt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(tsquery_ne(var1, var2)) do + %Sonata.Expr.Call{name: "tsquery_ne", arguments: [var1, var2]} + end + @doc("implementation of !! operator") + def(tsquery_not(var1)) do + %Sonata.Expr.Call{name: "tsquery_not", arguments: [var1]} + end + @doc("implementation of || operator") + def(tsquery_or(var1, var2)) do + %Sonata.Expr.Call{name: "tsquery_or", arguments: [var1, var2]} + end + @doc("I/O") + def(tsqueryin(var1)) do + %Sonata.Expr.Call{name: "tsqueryin", arguments: [var1]} + end + @doc("I/O") + def(tsqueryout(var1)) do + %Sonata.Expr.Call{name: "tsqueryout", arguments: [var1]} + end + @doc("I/O") + def(tsqueryrecv(var1)) do + %Sonata.Expr.Call{name: "tsqueryrecv", arguments: [var1]} + end + @doc("I/O") + def(tsquerysend(var1)) do + %Sonata.Expr.Call{name: "tsquerysend", arguments: [var1]} + end + @doc("tsrange constructor") + def(tsrange(var1, var2)) do + %Sonata.Expr.Call{name: "tsrange", arguments: [var1, var2]} + end + @doc("float8 difference of two timestamp values") + def(tsrange_subdiff(var1, var2)) do + %Sonata.Expr.Call{name: "tsrange_subdiff", arguments: [var1, var2]} + end + @doc("tstzrange constructor") + def(tstzrange(var1, var2, var3)) do + %Sonata.Expr.Call{name: "tstzrange", arguments: [var1, var2, var3]} + end + @doc("float8 difference of two timestamp with time zone values") + def(tstzrange_subdiff(var1, var2)) do + %Sonata.Expr.Call{name: "tstzrange_subdiff", arguments: [var1, var2]} + end + @doc("less-equal-greater") + def(tsvector_cmp(var1, var2)) do + %Sonata.Expr.Call{name: "tsvector_cmp", arguments: [var1, var2]} + end + @doc("implementation of || operator") + def(tsvector_concat(var1, var2)) do + %Sonata.Expr.Call{name: "tsvector_concat", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(tsvector_eq(var1, var2)) do + %Sonata.Expr.Call{name: "tsvector_eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(tsvector_ge(var1, var2)) do + %Sonata.Expr.Call{name: "tsvector_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(tsvector_gt(var1, var2)) do + %Sonata.Expr.Call{name: "tsvector_gt", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(tsvector_le(var1, var2)) do + %Sonata.Expr.Call{name: "tsvector_le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(tsvector_lt(var1, var2)) do + %Sonata.Expr.Call{name: "tsvector_lt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(tsvector_ne(var1, var2)) do + %Sonata.Expr.Call{name: "tsvector_ne", arguments: [var1, var2]} + end + @doc("I/O") + def(tsvectorin(var1)) do + %Sonata.Expr.Call{name: "tsvectorin", arguments: [var1]} + end + @doc("I/O") + def(tsvectorout(var1)) do + %Sonata.Expr.Call{name: "tsvectorout", arguments: [var1]} + end + @doc("I/O") + def(tsvectorrecv(var1)) do + %Sonata.Expr.Call{name: "tsvectorrecv", arguments: [var1]} + end + @doc("I/O") + def(tsvectorsend(var1)) do + %Sonata.Expr.Call{name: "tsvectorsend", arguments: [var1]} + end + @doc("get current transaction ID") + def(txid_current()) do + %Sonata.Expr.Call{name: "txid_current", arguments: []} + end + @doc("get current snapshot") + def(txid_current_snapshot()) do + %Sonata.Expr.Call{name: "txid_current_snapshot", arguments: []} + end + @doc("I/O") + def(txid_snapshot_in(var1)) do + %Sonata.Expr.Call{name: "txid_snapshot_in", arguments: [var1]} + end + @doc("I/O") + def(txid_snapshot_out(var1)) do + %Sonata.Expr.Call{name: "txid_snapshot_out", arguments: [var1]} + end + @doc("I/O") + def(txid_snapshot_recv(var1)) do + %Sonata.Expr.Call{name: "txid_snapshot_recv", arguments: [var1]} + end + @doc("I/O") + def(txid_snapshot_send(var1)) do + %Sonata.Expr.Call{name: "txid_snapshot_send", arguments: [var1]} + end + @doc("get set of in-progress txids in snapshot") + def(txid_snapshot_xip(var1)) do + %Sonata.Expr.Call{name: "txid_snapshot_xip", arguments: [var1]} + end + @doc("get xmax of snapshot") + def(txid_snapshot_xmax(var1)) do + %Sonata.Expr.Call{name: "txid_snapshot_xmax", arguments: [var1]} + end + @doc("get xmin of snapshot") + def(txid_snapshot_xmin(var1)) do + %Sonata.Expr.Call{name: "txid_snapshot_xmin", arguments: [var1]} + end + @doc("is txid visible in snapshot?") + def(txid_visible_in_snapshot(var1, var2)) do + %Sonata.Expr.Call{name: "txid_visible_in_snapshot", arguments: [var1, var2]} + end + @doc("internal conversion function for UHC to UTF8") + def(uhc_to_utf8(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "uhc_to_utf8", arguments: [var1, var2, var3, var4, var5]} + end + @doc("I/O") + def(unknownin(var1)) do + %Sonata.Expr.Call{name: "unknownin", arguments: [var1]} + end + @doc("I/O") + def(unknownout(var1)) do + %Sonata.Expr.Call{name: "unknownout", arguments: [var1]} + end + @doc("I/O") + def(unknownrecv(var1)) do + %Sonata.Expr.Call{name: "unknownrecv", arguments: [var1]} + end + @doc("I/O") + def(unknownsend(var1)) do + %Sonata.Expr.Call{name: "unknownsend", arguments: [var1]} + end + @doc("expand array to set of rows") + def(unnest(var1)) do + %Sonata.Expr.Call{name: "unnest", arguments: [var1]} + end + @doc("upper bound of range") + def(upper(var1)) do + %Sonata.Expr.Call{name: "upper", arguments: [var1]} + end + @doc("is the range's upper bound inclusive?") + def(upper_inc(var1)) do + %Sonata.Expr.Call{name: "upper_inc", arguments: [var1]} + end + @doc("is the range's upper bound infinite?") + def(upper_inf(var1)) do + %Sonata.Expr.Call{name: "upper_inf", arguments: [var1]} + end + @doc("internal conversion function for UTF8 to SQL_ASCII") + def(utf8_to_ascii(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "utf8_to_ascii", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for UTF8 to BIG5") + def(utf8_to_big5(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "utf8_to_big5", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for UTF8 to EUC_CN") + def(utf8_to_euc_cn(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "utf8_to_euc_cn", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for UTF8 to EUC_JIS_2004") + def(utf8_to_euc_jis_2004(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "utf8_to_euc_jis_2004", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for UTF8 to EUC_JP") + def(utf8_to_euc_jp(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "utf8_to_euc_jp", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for UTF8 to EUC_KR") + def(utf8_to_euc_kr(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "utf8_to_euc_kr", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for UTF8 to EUC_TW") + def(utf8_to_euc_tw(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "utf8_to_euc_tw", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for UTF8 to GB18030") + def(utf8_to_gb18030(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "utf8_to_gb18030", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for UTF8 to GBK") + def(utf8_to_gbk(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "utf8_to_gbk", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for UTF8 to ISO-8859-8") + def(utf8_to_iso8859(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "utf8_to_iso8859", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for UTF8 to LATIN1") + def(utf8_to_iso8859_1(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "utf8_to_iso8859_1", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for UTF8 to JOHAB") + def(utf8_to_johab(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "utf8_to_johab", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for UTF8 to KOI8R") + def(utf8_to_koi8r(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "utf8_to_koi8r", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for UTF8 to KOI8U") + def(utf8_to_koi8u(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "utf8_to_koi8u", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for UTF8 to SHIFT_JIS_2004") + def(utf8_to_shift_jis_2004(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "utf8_to_shift_jis_2004", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for UTF8 to SJIS") + def(utf8_to_sjis(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "utf8_to_sjis", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for UTF8 to UHC") + def(utf8_to_uhc(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "utf8_to_uhc", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for UTF8 to WIN1258") + def(utf8_to_win(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "utf8_to_win", arguments: [var1, var2, var3, var4, var5]} + end + @doc("less-equal-greater") + def(uuid_cmp(var1, var2)) do + %Sonata.Expr.Call{name: "uuid_cmp", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(uuid_eq(var1, var2)) do + %Sonata.Expr.Call{name: "uuid_eq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(uuid_ge(var1, var2)) do + %Sonata.Expr.Call{name: "uuid_ge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(uuid_gt(var1, var2)) do + %Sonata.Expr.Call{name: "uuid_gt", arguments: [var1, var2]} + end + @doc("hash") + def(uuid_hash(var1)) do + %Sonata.Expr.Call{name: "uuid_hash", arguments: [var1]} + end + @doc("I/O") + def(uuid_in(var1)) do + %Sonata.Expr.Call{name: "uuid_in", arguments: [var1]} + end + @doc("implementation of <= operator") + def(uuid_le(var1, var2)) do + %Sonata.Expr.Call{name: "uuid_le", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(uuid_lt(var1, var2)) do + %Sonata.Expr.Call{name: "uuid_lt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(uuid_ne(var1, var2)) do + %Sonata.Expr.Call{name: "uuid_ne", arguments: [var1, var2]} + end + @doc("I/O") + def(uuid_out(var1)) do + %Sonata.Expr.Call{name: "uuid_out", arguments: [var1]} + end + @doc("I/O") + def(uuid_recv(var1)) do + %Sonata.Expr.Call{name: "uuid_recv", arguments: [var1]} + end + @doc("I/O") + def(uuid_send(var1)) do + %Sonata.Expr.Call{name: "uuid_send", arguments: [var1]} + end + @doc("population variance of float8 input values (square of the population standard deviation)") + def(var_pop(var1)) do + %Sonata.Expr.Call{name: "var_pop", arguments: [var1]} + end + @doc("sample variance of smallint input values (square of the sample standard deviation)") + def(var_samp(var1)) do + %Sonata.Expr.Call{name: "var_samp", arguments: [var1]} + end + @doc("adjust varbit() to typmod length") + def(varbit(var1, var2, var3)) do + %Sonata.Expr.Call{name: "varbit", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(varbit_in(var1, var2, var3)) do + %Sonata.Expr.Call{name: "varbit_in", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(varbit_out(var1)) do + %Sonata.Expr.Call{name: "varbit_out", arguments: [var1]} + end + @doc("I/O") + def(varbit_recv(var1, var2, var3)) do + %Sonata.Expr.Call{name: "varbit_recv", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(varbit_send(var1)) do + %Sonata.Expr.Call{name: "varbit_send", arguments: [var1]} + end + @doc("transform a varbit length coercion") + def(varbit_transform(var1)) do + %Sonata.Expr.Call{name: "varbit_transform", arguments: [var1]} + end + @doc("less-equal-greater") + def(varbitcmp(var1, var2)) do + %Sonata.Expr.Call{name: "varbitcmp", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(varbiteq(var1, var2)) do + %Sonata.Expr.Call{name: "varbiteq", arguments: [var1, var2]} + end + @doc("implementation of >= operator") + def(varbitge(var1, var2)) do + %Sonata.Expr.Call{name: "varbitge", arguments: [var1, var2]} + end + @doc("implementation of > operator") + def(varbitgt(var1, var2)) do + %Sonata.Expr.Call{name: "varbitgt", arguments: [var1, var2]} + end + @doc("implementation of <= operator") + def(varbitle(var1, var2)) do + %Sonata.Expr.Call{name: "varbitle", arguments: [var1, var2]} + end + @doc("implementation of < operator") + def(varbitlt(var1, var2)) do + %Sonata.Expr.Call{name: "varbitlt", arguments: [var1, var2]} + end + @doc("implementation of <> operator") + def(varbitne(var1, var2)) do + %Sonata.Expr.Call{name: "varbitne", arguments: [var1, var2]} + end + @doc("I/O typmod") + def(varbittypmodin(var1)) do + %Sonata.Expr.Call{name: "varbittypmodin", arguments: [var1]} + end + @doc("I/O typmod") + def(varbittypmodout(var1)) do + %Sonata.Expr.Call{name: "varbittypmodout", arguments: [var1]} + end + @doc("adjust varchar() to typmod length") + def(varchar(var1, var2, var3)) do + %Sonata.Expr.Call{name: "varchar", arguments: [var1, var2, var3]} + end + @doc("transform a varchar length coercion") + def(varchar_transform(var1)) do + %Sonata.Expr.Call{name: "varchar_transform", arguments: [var1]} + end + @doc("I/O") + def(varcharin(var1, var2, var3)) do + %Sonata.Expr.Call{name: "varcharin", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(varcharout(var1)) do + %Sonata.Expr.Call{name: "varcharout", arguments: [var1]} + end + @doc("I/O") + def(varcharrecv(var1, var2, var3)) do + %Sonata.Expr.Call{name: "varcharrecv", arguments: [var1, var2, var3]} + end + @doc("I/O") + def(varcharsend(var1)) do + %Sonata.Expr.Call{name: "varcharsend", arguments: [var1]} + end + @doc("I/O typmod") + def(varchartypmodin(var1)) do + %Sonata.Expr.Call{name: "varchartypmodin", arguments: [var1]} + end + @doc("I/O typmod") + def(varchartypmodout(var1)) do + %Sonata.Expr.Call{name: "varchartypmodout", arguments: [var1]} + end + @doc("historical alias for var_samp") + def(variance(var1)) do + %Sonata.Expr.Call{name: "variance", arguments: [var1]} + end + @doc("PostgreSQL version string") + def(version()) do + %Sonata.Expr.Call{name: "version", arguments: []} + end + @doc("I/O") + def(void_in(var1)) do + %Sonata.Expr.Call{name: "void_in", arguments: [var1]} + end + @doc("I/O") + def(void_out(var1)) do + %Sonata.Expr.Call{name: "void_out", arguments: [var1]} + end + @doc("I/O") + def(void_recv(var1)) do + %Sonata.Expr.Call{name: "void_recv", arguments: [var1]} + end + @doc("I/O") + def(void_send(var1)) do + %Sonata.Expr.Call{name: "void_send", arguments: [var1]} + end + @doc("box width") + def(width(var1)) do + %Sonata.Expr.Call{name: "width", arguments: [var1]} + end + @doc("bucket number of operand in equal-width histogram") + def(width_bucket(var1, var2, var3, var4)) do + %Sonata.Expr.Call{name: "width_bucket", arguments: [var1, var2, var3, var4]} + end + @doc("internal conversion function for WIN1250 to LATIN2") + def(win1250_to_latin2(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "win1250_to_latin2", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for WIN1250 to MULE_INTERNAL") + def(win1250_to_mic(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "win1250_to_mic", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for WIN1251 to ISO-8859-5") + def(win1251_to_iso(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "win1251_to_iso", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for WIN1251 to KOI8R") + def(win1251_to_koi8r(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "win1251_to_koi8r", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for WIN1251 to MULE_INTERNAL") + def(win1251_to_mic(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "win1251_to_mic", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for WIN1251 to WIN866") + def(win1251_to_win866(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "win1251_to_win866", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for WIN866 to ISO-8859-5") + def(win866_to_iso(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "win866_to_iso", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for WIN866 to KOI8R") + def(win866_to_koi8r(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "win866_to_koi8r", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for WIN866 to MULE_INTERNAL") + def(win866_to_mic(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "win866_to_mic", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for WIN866 to WIN1251") + def(win866_to_win1251(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "win866_to_win1251", arguments: [var1, var2, var3, var4, var5]} + end + @doc("internal conversion function for WIN1258 to UTF8") + def(win_to_utf8(var1, var2, var3, var4, var5)) do + %Sonata.Expr.Call{name: "win_to_utf8", arguments: [var1, var2, var3, var4, var5]} + end + @doc("implementation of = operator") + def(xideq(var1, var2)) do + %Sonata.Expr.Call{name: "xideq", arguments: [var1, var2]} + end + @doc("implementation of = operator") + def(xideqint4(var1, var2)) do + %Sonata.Expr.Call{name: "xideqint4", arguments: [var1, var2]} + end + @doc("I/O") + def(xidin(var1)) do + %Sonata.Expr.Call{name: "xidin", arguments: [var1]} + end + @doc("I/O") + def(xidout(var1)) do + %Sonata.Expr.Call{name: "xidout", arguments: [var1]} + end + @doc("I/O") + def(xidrecv(var1)) do + %Sonata.Expr.Call{name: "xidrecv", arguments: [var1]} + end + @doc("I/O") + def(xidsend(var1)) do + %Sonata.Expr.Call{name: "xidsend", arguments: [var1]} + end + @doc("perform a non-validating parse of a character string to produce an XML value") + def(xml(var1)) do + %Sonata.Expr.Call{name: "xml", arguments: [var1]} + end + @doc("I/O") + def(xml_in(var1)) do + %Sonata.Expr.Call{name: "xml_in", arguments: [var1]} + end + @doc("determine if a string is well formed XML") + def(xml_is_well_formed(var1)) do + %Sonata.Expr.Call{name: "xml_is_well_formed", arguments: [var1]} + end + @doc("determine if a string is well formed XML content") + def(xml_is_well_formed_content(var1)) do + %Sonata.Expr.Call{name: "xml_is_well_formed_content", arguments: [var1]} + end + @doc("determine if a string is well formed XML document") + def(xml_is_well_formed_document(var1)) do + %Sonata.Expr.Call{name: "xml_is_well_formed_document", arguments: [var1]} + end + @doc("I/O") + def(xml_out(var1)) do + %Sonata.Expr.Call{name: "xml_out", arguments: [var1]} + end + @doc("I/O") + def(xml_recv(var1)) do + %Sonata.Expr.Call{name: "xml_recv", arguments: [var1]} + end + @doc("I/O") + def(xml_send(var1)) do + %Sonata.Expr.Call{name: "xml_send", arguments: [var1]} + end + @doc("concatenate XML values") + def(xmlagg(var1)) do + %Sonata.Expr.Call{name: "xmlagg", arguments: [var1]} + end + @doc("generate XML comment") + def(xmlcomment(var1)) do + %Sonata.Expr.Call{name: "xmlcomment", arguments: [var1]} + end + @doc("aggregate transition function") + def(xmlconcat2(var1, var2)) do + %Sonata.Expr.Call{name: "xmlconcat2", arguments: [var1, var2]} + end + @doc("test XML value against XPath expression") + def(xmlexists(var1, var2)) do + %Sonata.Expr.Call{name: "xmlexists", arguments: [var1, var2]} + end + @doc("validate an XML value") + def(xmlvalidate(var1, var2)) do + %Sonata.Expr.Call{name: "xmlvalidate", arguments: [var1, var2]} + end + @doc("evaluate XPath expression") + def(xpath(var1, var2)) do + %Sonata.Expr.Call{name: "xpath", arguments: [var1, var2]} + end + @doc("test XML value against XPath expression, with namespace support") + def(xpath_exists(var1, var2, var3)) do + %Sonata.Expr.Call{name: "xpath_exists", arguments: [var1, var2, var3]} + end +end diff --git a/lib/sonata/keyword.ex b/lib/sonata/keyword.ex new file mode 100644 index 0000000..993a324 --- /dev/null +++ b/lib/sonata/keyword.ex @@ -0,0 +1,35 @@ +defmodule Sonata.Keyword do + alias Sonata.Expr.Operator + + keywords = [ + :and, + :between, + :is_distinct_from, + :is_not_distinct_from, + :is_null, + :is_not_null, + :is_true, + :is_not_true, + :is_false, + :is_not_false, + :is_unknown, + :is_not_unknown, + :like, + :not_like, + :ilike, + :not_ilike, + :similar_to, + :not_similar_to, + ] + + for keyword <- keywords do + keyword_s = keyword |> to_string() |> String.upcase() |> String.replace("_", " ") + def unquote(keyword)(lhs, rhs) do + %Operator{operator: unquote(keyword_s), lhs: lhs, rhs: rhs} + end + end + + def not(rhs) do + %Sonata.Expr.UnaryOperator{operator: "NOT", rhs: rhs} + end +end diff --git a/lib/sonata/manipulation.ex b/lib/sonata/manipulation.ex index 660e309..a035d48 100644 --- a/lib/sonata/manipulation.ex +++ b/lib/sonata/manipulation.ex @@ -1,76 +1,58 @@ defmodule Sonata.Manipulation do - defmodule Insertion do - defstruct [table: nil, - fields: [], - rows: [], - returning: [], - default_values: nil] - end + alias __MODULE__.{Insertion,Update} - defmodule Update do - defstruct [table: nil, - table_alias: nil, - sets: [], - where: nil, - returning: []] + def insert_into(table) do + %Insertion{table: table} end - defmodule Builder do - alias Sonata.Manipulation.{Insertion,Update} - - def insert_into(table) do - %Insertion{table: table} - end - - # TODO: support `kvs` - def insert_into(table, _kvs) do - insert_into(table) - end + # TODO: support `kvs` + def insert_into(table, _kvs) do + insert_into(table) + end - def fields(insertion = %{fields: fields}, columns) do - %{insertion | fields: fields ++ columns} - end + def fields(insertion = %{fields: fields}, columns) do + %{insertion | fields: fields ++ columns} + end - # TODO: support `INSERT INTO foo (valA, valB) VALUES (SELECT ...)` - def values(insertion = %{rows: rows}, [first | _ ] = values) when is_list(first) do - %{insertion | rows: Enum.into(rows, values)} - end - def values(insertion = %{rows: rows}, values) when is_list(values) do - %{insertion | rows: Enum.into(rows, [values])} - end + # TODO: support `INSERT INTO foo (valA, valB) VALUES (SELECT ...)` + def values(insertion = %{rows: rows}, [first | _ ] = values) when is_list(first) do + %{insertion | rows: Enum.into(rows, values)} + end + def values(insertion = %{rows: rows}, values) when is_list(values) do + %{insertion | rows: Enum.into(rows, [values])} + end - def default_values(insertion = %{default_values: _}) do - %{insertion | default_values: :true} - end + def default_values(insertion = %{default_values: _}) do + %{insertion | default_values: :true} + end - def update(table) do - %Update{table: table} - end + def update(table) do + %Update{table: table} + end - def update(table, table_alias) do - %Update{table: table, table_alias: table_alias} - end + def update(table, table_alias) do + %Update{table: table, table_alias: table_alias} + end - def set(insertion = %Update{sets: sets}, kvs) do - %{insertion | sets: sets ++ Enum.map(kvs, fn - ({fields, value}) when is_list(fields) -> - {Sonata.Expr.column_list(fields), value} - ({fields, _value}) when is_tuple(fields) -> - fields - |> :erlang.tuple_to_list() - |> Sonata.Expr.column_list() - ({field, value}) -> - {Sonata.Expr.column(field), value} - end)} - end + def set(insertion = %Update{sets: sets}, kvs) do + %{insertion | sets: sets ++ Enum.map(kvs, fn + ({fields, value}) when is_list(fields) -> + {Sonata.Expr.column_list(fields), value} + ({fields, _value}) when is_tuple(fields) -> + fields + |> :erlang.tuple_to_list() + |> Sonata.Expr.column_list() + ({field, value}) -> + {Sonata.Expr.column(field), value} + end)} + end - def set(insertion, field, value) do - set(insertion, [{field, value}]) - end + def set(insertion, field, value) do + set(insertion, [{field, value}]) + end - # TODO: support returning alias - def returning(insertion = %{returning: returning}, fields) do - %{insertion | returning: returning ++ fields} - end + # TODO: support returning alias + def returning(insertion = %{returning: returning}, fields) do + %{insertion | returning: returning ++ fields} end end diff --git a/lib/sonata/manipulation/insertion.ex b/lib/sonata/manipulation/insertion.ex new file mode 100644 index 0000000..fbe523a --- /dev/null +++ b/lib/sonata/manipulation/insertion.ex @@ -0,0 +1,71 @@ +defmodule Sonata.Manipulation.Insertion do + defstruct [table: nil, + fields: [], + rows: [], + returning: [], + default_values: nil] +end + +defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do + alias Sonata.Postgres, as: PG + import PG.Utils + + def to_sql(insertion, opts, idx) do + {table, table_params, idx} = table(insertion.table, opts, idx) + {fields, fields_params, idx} = fields(insertion.fields, opts, idx) + {default_values, default_values_params, idx} = default_values(insertion.default_values, opts, idx) + {rows, rows_params, idx} = rows(insertion.rows, opts, idx) + + { + join([ + "INSERT INTO", + table, + fields, + default_values, + rows, + ], " "), + + Stream.concat([ + table_params, + fields_params, + default_values_params, + rows_params, + ]), + + idx + } + end + + defp table(table, _, idx) when table in [nil, false, ""] do + {nil, [], idx} + end + defp table(table, opts, idx) when is_binary(table) do + {escape_keyword(table), opts, idx} + end + + def fields(fields, _, idx) when fields in [nil, false, ""] do + {nil, [], idx} + end + + def default_values(:true, opts, idx) do + {"DEFAULT VALUES", opts, idx} + end + + def rows(rows, _, idx) when rows in [nil, false, ""] do + {nil, [], idx} + end + # TODO + def rows(rows, opts, idx) do + {["VALUES"] ++ rows, opts, idx} + end + + # TODO + # defp on_conflict do + # end + # defp returning do + # end + + def on_row(_, _) do + nil + end +end diff --git a/lib/sonata/manipulation/update.ex b/lib/sonata/manipulation/update.ex new file mode 100644 index 0000000..adc4723 --- /dev/null +++ b/lib/sonata/manipulation/update.ex @@ -0,0 +1,88 @@ +defmodule Sonata.Manipulation.Update do + defstruct [table: nil, + table_alias: nil, + sets: [], + where: nil, + returning: []] +end + +defimpl Sonata.Postgres, for: Sonata.Manipulation.Update do + alias Sonata.Postgres, as: PG + import PG.Utils + + def to_sql(update, opts, idx) do + {table, table_params, idx} = table(update.table, opts, idx) + {table_alias, table_alias_params, idx} = table_alias(update.table_alias, opts, idx) + {sets, sets_params, idx} = sets(update.sets, opts, idx) + {where, where_params, idx} = where(update.where, opts, idx) + {returning, returning_params, idx} = returning(update.returning, opts, idx) + + { + join([ + "UPDATE", + table, + table_alias, + sets, + where, + returning + ], " "), + + Stream.concat([ + table_params, + table_alias_params, + sets_params, + where_params, + returning_params + ]), + + idx + } + end + + def on_row(_, _) do + nil + end + + defp table(table, _, idx) when table in [nil, false, ""] do + {nil, [], idx} + end + defp table(table, opts, idx) when is_binary(table) do + {escape_keyword(table), opts, idx} + end + + defp table_alias(nil, _, idx) do + {nil, [], idx} + end + defp table_alias(alias, opts, idx) do + {[" AS ", escape_keyword(alias)], opts, idx} + end + + defp sets(sets, _, idx) when sets in [nil, false, "", []] do + {nil, [], idx} + end + defp sets(sets, opts, idx) do + {sets, {params, idx}} = Enum.map_reduce(sets, {[], idx}, fn({field, value}, {params, idx}) -> + {field, p, idx} = Sonata.Postgres.to_sql(field, opts, idx) + {value, p, idx} = Sonata.Postgres.to_sql(value, opts, idx) + {[field, " = (", value, ")"], {Stream.concat(params, p), idx}} + end) + {["SET ", Sonata.Postgres.Utils.join(sets, ", ")], params, idx} + end + + defp where(nil, _, idx) do + {nil, [], idx} + end + defp where(expr, opts, idx) do + {where, params, idx} = PG.to_sql(expr, opts, idx) + {["WHERE ", where], params, idx} + end + + # TODO: support returning alias + defp returning(returning, _, idx) when returning in [nil, false, "", []] do + {nil, [], idx} + end + defp returning(returning, opts, idx) do + {sql, params, idx} = PG.Utils.columns(returning, opts, idx) + {["RETURNING ", sql], params, idx} + end +end diff --git a/lib/sonata/misc.ex b/lib/sonata/misc.ex deleted file mode 100644 index d6b3caa..0000000 --- a/lib/sonata/misc.ex +++ /dev/null @@ -1,15 +0,0 @@ -defmodule Sonata.Misc do - defmodule Call do - defstruct [function: nil, arguments: []] - end - - defmodule Builder do - def call(function) do - %Sonata.Misc.Call{function: function} - end - - def call(function, arguments) do - %Sonata.Misc.Call{function: function, arguments: arguments} - end - end -end diff --git a/lib/sonata/operator.ex b/lib/sonata/operator.ex new file mode 100644 index 0000000..5d27f6a --- /dev/null +++ b/lib/sonata/operator.ex @@ -0,0 +1,381 @@ +defmodule Sonata.Operator do + def unquote(:!)(lhs, rhs) do + %Sonata.Expr.Operator{operator: "!", lhs: lhs, rhs: rhs} + end + + def unquote(:"!!")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "!!", lhs: lhs, rhs: rhs} + end + + def unquote(:"!~")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "!~", lhs: lhs, rhs: rhs} + end + + def unquote(:"!~*")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "!~*", lhs: lhs, rhs: rhs} + end + + def unquote(:"!~~")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "!~~", lhs: lhs, rhs: rhs} + end + + def unquote(:"!~~*")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "!~~*", lhs: lhs, rhs: rhs} + end + + def unquote(:"#")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "#", lhs: lhs, rhs: rhs} + end + + def unquote(:"##")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "##", lhs: lhs, rhs: rhs} + end + + def unquote(:"#-")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "#-", lhs: lhs, rhs: rhs} + end + + def unquote(:"#<")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "#<", lhs: lhs, rhs: rhs} + end + + def unquote(:"#<#")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "#<#", lhs: lhs, rhs: rhs} + end + + def unquote(:"#<=")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "#<=", lhs: lhs, rhs: rhs} + end + + def unquote(:"#<=#")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "#<=#", lhs: lhs, rhs: rhs} + end + + def unquote(:"#<>")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "#<>", lhs: lhs, rhs: rhs} + end + + def unquote(:"#=")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "#=", lhs: lhs, rhs: rhs} + end + + def unquote(:"#>")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "#>", lhs: lhs, rhs: rhs} + end + + def unquote(:"#>#")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "#>#", lhs: lhs, rhs: rhs} + end + + def unquote(:"#>=")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "#>=", lhs: lhs, rhs: rhs} + end + + def unquote(:"#>=#")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "#>=#", lhs: lhs, rhs: rhs} + end + + def unquote(:"#>>")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "#>>", lhs: lhs, rhs: rhs} + end + + def unquote(:%)(lhs, rhs) do + %Sonata.Expr.Operator{operator: "%", lhs: lhs, rhs: rhs} + end + + def unquote(:"%#")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "%#", lhs: lhs, rhs: rhs} + end + + def unquote(:"%%")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "%%", lhs: lhs, rhs: rhs} + end + + def unquote(:&)(lhs, rhs) do + %Sonata.Expr.Operator{operator: "&", lhs: lhs, rhs: rhs} + end + + def unquote(:&&)(lhs, rhs) do + %Sonata.Expr.Operator{operator: "&&", lhs: lhs, rhs: rhs} + end + + def unquote(:"&<")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "&<", lhs: lhs, rhs: rhs} + end + + def unquote(:"&<|")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "&<|", lhs: lhs, rhs: rhs} + end + + def unquote(:"&>")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "&>", lhs: lhs, rhs: rhs} + end + + def unquote(:*)(lhs, rhs) do + %Sonata.Expr.Operator{operator: "*", lhs: lhs, rhs: rhs} + end + + def unquote(:"*<")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "*<", lhs: lhs, rhs: rhs} + end + + def unquote(:"*<=")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "*<=", lhs: lhs, rhs: rhs} + end + + def unquote(:"*<>")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "*<>", lhs: lhs, rhs: rhs} + end + + def unquote(:"*=")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "*=", lhs: lhs, rhs: rhs} + end + + def unquote(:"*>")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "*>", lhs: lhs, rhs: rhs} + end + + def unquote(:"*>=")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "*>=", lhs: lhs, rhs: rhs} + end + + def unquote(:+)(lhs, rhs) do + %Sonata.Expr.Operator{operator: "+", lhs: lhs, rhs: rhs} + end + + def unquote(:-)(lhs, rhs) do + %Sonata.Expr.Operator{operator: "-", lhs: lhs, rhs: rhs} + end + + def unquote(:->)(lhs, rhs) do + %Sonata.Expr.Operator{operator: "->", lhs: lhs, rhs: rhs} + end + + def unquote(:"->>")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "->>", lhs: lhs, rhs: rhs} + end + + def unquote(:"-|-")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "-|-", lhs: lhs, rhs: rhs} + end + + def unquote(:/)(lhs, rhs) do + %Sonata.Expr.Operator{operator: "/", lhs: lhs, rhs: rhs} + end + + def unquote(:<)(lhs, rhs) do + %Sonata.Expr.Operator{operator: "<", lhs: lhs, rhs: rhs} + end + + def unquote(:"<#>")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "<#>", lhs: lhs, rhs: rhs} + end + + def unquote(:"<->")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "<->", lhs: lhs, rhs: rhs} + end + + def unquote(:"<<")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "<<", lhs: lhs, rhs: rhs} + end + + def unquote(:"<<=")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "<<=", lhs: lhs, rhs: rhs} + end + + def unquote(:"<<|")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "<<|", lhs: lhs, rhs: rhs} + end + + def unquote(:<=)(lhs, rhs) do + %Sonata.Expr.Operator{operator: "<=", lhs: lhs, rhs: rhs} + end + + def unquote(:<>)(lhs, rhs) do + %Sonata.Expr.Operator{operator: "<>", lhs: lhs, rhs: rhs} + end + + def unquote(:"")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "", lhs: lhs, rhs: rhs} + end + + def unquote(:"<@")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "<@", lhs: lhs, rhs: rhs} + end + + def unquote(:"<^")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "<^", lhs: lhs, rhs: rhs} + end + + def unquote(:=)(lhs, rhs) do + %Sonata.Expr.Operator{operator: "=", lhs: lhs, rhs: rhs} + end + + def unquote(:>)(lhs, rhs) do + %Sonata.Expr.Operator{operator: ">", lhs: lhs, rhs: rhs} + end + + def unquote(:>=)(lhs, rhs) do + %Sonata.Expr.Operator{operator: ">=", lhs: lhs, rhs: rhs} + end + + def unquote(:">>")(lhs, rhs) do + %Sonata.Expr.Operator{operator: ">>", lhs: lhs, rhs: rhs} + end + + def unquote(:">>=")(lhs, rhs) do + %Sonata.Expr.Operator{operator: ">>=", lhs: lhs, rhs: rhs} + end + + def unquote(:">^")(lhs, rhs) do + %Sonata.Expr.Operator{operator: ">^", lhs: lhs, rhs: rhs} + end + + def unquote(:"?")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "?", lhs: lhs, rhs: rhs} + end + + def unquote(:"?#")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "?#", lhs: lhs, rhs: rhs} + end + + def unquote(:"?&")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "?&", lhs: lhs, rhs: rhs} + end + + def unquote(:"?-")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "?-", lhs: lhs, rhs: rhs} + end + + def unquote(:"?-|")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "?-|", lhs: lhs, rhs: rhs} + end + + def unquote(:"?<@")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "?<@", lhs: lhs, rhs: rhs} + end + + def unquote(:"?@")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "?@", lhs: lhs, rhs: rhs} + end + + def unquote(:"?@>")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "?@>", lhs: lhs, rhs: rhs} + end + + def unquote(:"?|")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "?|", lhs: lhs, rhs: rhs} + end + + def unquote(:"?||")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "?||", lhs: lhs, rhs: rhs} + end + + def unquote(:"?~")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "?~", lhs: lhs, rhs: rhs} + end + + def unquote(:@)(lhs, rhs) do + %Sonata.Expr.Operator{operator: "@", lhs: lhs, rhs: rhs} + end + + def unquote(:"@-@")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "@-@", lhs: lhs, rhs: rhs} + end + + def unquote(:"@>")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "@>", lhs: lhs, rhs: rhs} + end + + def unquote(:"@@")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "@@", lhs: lhs, rhs: rhs} + end + + def unquote(:"@@@")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "@@@", lhs: lhs, rhs: rhs} + end + + def unquote(:^)(lhs, rhs) do + %Sonata.Expr.Operator{operator: "^", lhs: lhs, rhs: rhs} + end + + def unquote(:"^<@")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "^<@", lhs: lhs, rhs: rhs} + end + + def unquote(:"^?")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "^?", lhs: lhs, rhs: rhs} + end + + def unquote(:"^@")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "^@", lhs: lhs, rhs: rhs} + end + + def unquote(:"^@>")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "^@>", lhs: lhs, rhs: rhs} + end + + def unquote(:"^~")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "^~", lhs: lhs, rhs: rhs} + end + + def unquote(:|)(lhs, rhs) do + %Sonata.Expr.Operator{operator: "|", lhs: lhs, rhs: rhs} + end + + def unquote(:"|&>")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "|&>", lhs: lhs, rhs: rhs} + end + + def unquote(:"|/")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "|/", lhs: lhs, rhs: rhs} + end + + def unquote(:"|>>")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "|>>", lhs: lhs, rhs: rhs} + end + + def unquote(:||)(lhs, rhs) do + %Sonata.Expr.Operator{operator: "||", lhs: lhs, rhs: rhs} + end + + def unquote(:"||/")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "||/", lhs: lhs, rhs: rhs} + end + + def unquote(:"~")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "~", lhs: lhs, rhs: rhs} + end + + def unquote(:"~*")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "~*", lhs: lhs, rhs: rhs} + end + + def unquote(:"~<=~")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "~<=~", lhs: lhs, rhs: rhs} + end + + def unquote(:"~<~")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "~<~", lhs: lhs, rhs: rhs} + end + + def unquote(:"~=")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "~=", lhs: lhs, rhs: rhs} + end + + def unquote(:"~>=~")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "~>=~", lhs: lhs, rhs: rhs} + end + + def unquote(:"~>~")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "~>~", lhs: lhs, rhs: rhs} + end + + def unquote(:"~~")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "~~", lhs: lhs, rhs: rhs} + end + + def unquote(:"~~*")(lhs, rhs) do + %Sonata.Expr.Operator{operator: "~~*", lhs: lhs, rhs: rhs} + end +end diff --git a/lib/sonata/order_by.ex b/lib/sonata/order_by.ex index 076df30..4deae11 100644 --- a/lib/sonata/order_by.ex +++ b/lib/sonata/order_by.ex @@ -2,18 +2,36 @@ defmodule Sonata.OrderBy do defstruct [query: nil, order_by: []] - defmodule Builder do - def order_by(%{order_by: expressions} = q, e) when is_list(e) do - %{q | order_by: expressions ++ e} - end - def order_by(query, e) when is_list(e) do - order_by(%Sonata.OrderBy{query: query}, e) - end - def order_by(order_by, e) do - order_by(order_by, [e]) - end - def order_by(order_by, e, order) when order in [:asc, :desc] do - order_by(order_by, [{e, order}]) - end + def order_by(%{order_by: expressions} = q, e) when is_list(e) do + %{q | order_by: expressions ++ e} + end + def order_by(query, e) when is_list(e) do + order_by(%Sonata.OrderBy{query: query}, e) + end + def order_by(order_by, e) do + order_by(order_by, [e]) + end + def order_by(order_by, e, order) when order in [:asc, :desc] do + order_by(order_by, [{e, order}]) + end +end + +defimpl Sonata.Postgres, for: Sonata.OrderBy do + alias Sonata.Postgres, as: PG + alias PG.Utils + + def to_sql(%{query: query, order_by: e}, opts, idx) do + {query, query_params, idx} = PG.to_sql(query, opts, idx) + {e, e_params, idx} = Utils.columns(e, opts, idx) + + { + [query, " ORDER BY ", e], + Stream.concat(query_params, e_params), + idx + } + end + + def on_row(_, _) do + nil end end diff --git a/lib/sonata/postgres.ex b/lib/sonata/postgres.ex index 3512f18..96bb340 100644 --- a/lib/sonata/postgres.ex +++ b/lib/sonata/postgres.ex @@ -1,68 +1,6 @@ defprotocol Sonata.Postgres do def to_sql(statement, opts, idx) def on_row(statement, opts) - - Kernel.def to_sql(statement, opts \\ []) do - {sql, params, _idx} = to_sql(statement, opts, 1) - {sql, Enum.to_list(params), on_row(statement, opts)} - end - - defmodule Utils do - import Kernel - def columns([], _, idx) do - {"*", [], idx} - end - def columns(columns, opts, idx) do - {sql, {params, idx}} = Enum.map_reduce(columns, {[], idx}, fn(column, {params, idx}) -> - {column, p, idx} = column(column, opts, idx) - {[", ", column], {Stream.concat(params, p), idx}} - end) - {pop_comma(sql), params, idx} - end - - def column(column, _, idx) when is_binary(column) do - {escape_keyword(column), [], idx} - end - def column(column, _, idx) when is_atom(column) do - {escape_keyword(Atom.to_string(column)), [], idx} - end - def column({column, alias}, opts, idx) do - {column, params, idx} = column(column, opts, idx) - {[column, " AS ", escape_keyword(alias)], params, idx} - end - def column(column, opts, idx) do - Sonata.Postgres.to_sql(column, opts, idx) - end - - def pop_comma({columns, params, idx}) do - {pop_comma(columns), params, idx} - end - def pop_comma([[", " | column] | columns]) do - [column | columns] - end - def pop_comma(other) do - other - end - - def join([], _delim) do - [] - end - def join([item | rest], delim) when item in ["", nil] do - join(rest, delim) - end - def join([item | rest], delim) do - case join(rest, delim) do - [] -> - item - rest -> - [item, delim, rest] - end - end - - def escape_keyword(value) do - to_string(value) - end - end end defimpl Sonata.Postgres, for: [Integer, Float, Atom, BitString] do @@ -79,528 +17,3 @@ defimpl Sonata.Postgres, for: [Integer, Float, Atom, BitString] do nil end end - -defimpl Sonata.Postgres, for: Sonata.OrderBy do - alias Sonata.Postgres, as: PG - alias PG.Utils - - def to_sql(%{query: query, order_by: e}, opts, idx) do - {query, query_params, idx} = PG.to_sql(query, opts, idx) - {e, e_params, idx} = Utils.columns(e, opts, idx) - - { - [query, " ORDER BY ", e], - Stream.concat(query_params, e_params), - idx - } - end - - def on_row(_, _) do - nil - end -end - -defimpl Sonata.Postgres, for: Sonata.Query do - alias Sonata.Postgres, as: PG - import PG.Utils - - def to_sql(query, opts, idx) do - {distinct, distinct_params, idx} = distinct(query.distinct, opts, idx) - {columns, column_params, idx} = columns(query.columns, opts, idx) - {from, from_params, idx} = from(query.from, opts, idx) - {where, where_params, idx} = where(query.where, opts, idx) - {group_by, group_by_params, idx} = group_by(query.group_by, opts, idx) - {having, having_params, idx} = having(query.having, opts, idx) - {order_by, order_by_params, idx} = order_by(query.order_by, opts, idx) - {limit, limit_params, idx} = limit(query.limit, opts, idx) - {offset, offset_params, idx} = offset(query.offset, opts, idx) - - { - join([ - "SELECT", - distinct, - columns, - from, - where, - group_by, - having, - order_by, - limit, - offset - ], " "), - - Stream.concat([ - distinct_params, - column_params, - from_params, - where_params, - group_by_params, - having_params, - order_by_params, - limit_params, - offset_params - ]), - - idx - } - end - - def on_row(%{struct: nil}, _) do - nil - end - def on_row(%{struct: struct}, _) do - fn(row) -> struct.__from_row__(row) end - end - - defp distinct(distinct, _, idx) when distinct in [nil, false, []] do - {nil, [], idx} - end - defp distinct(true, _, idx) do - {"DISTINCT", [], idx} - end - defp distinct(distinct, opts, idx) when is_list(distinct) do - {columns, params, idx} = columns(distinct, opts, idx) - {["DISTINCT ON (", columns, ")"], params, idx} - end - - defp from(nil, _, idx) do - {nil, [], idx} - end - defp from(from, _, idx) when is_binary(from) do - {["FROM ", escape_keyword(from)], [], idx} - end - defp from({from, alias}, opts, idx) do - {from, params, idx} = from(from, opts, idx) - {[from, " AS ", alias], params, idx} - end - defp from(from, opts, idx) do - {from, params, idx} = PG.to_sql(from, opts, idx) - {["FROM (", from, ")"], params, idx} - end - - defp where(nil, _, idx) do - {nil, [], idx} - end - defp where(expr, opts, idx) do - {where, params, idx} = PG.to_sql(expr, opts, idx) - {["WHERE ", where], params, idx} - end - - defp group_by([], _, idx) do - {nil, [], idx} - end - defp group_by(columns, opts, idx) do - {columns, params} = columns(columns, opts, idx) - {["GROUP BY ", columns], params, idx} - end - - defp having(nil, _, idx) do - {nil, [], idx} - end - defp having(expr, opts, idx) do - {having, params} = PG.to_sql(expr, opts, idx) - {["HAVING ", having], params, idx} - end - - defp order_by([], _, idx) do - {nil, [], idx} - end - defp order_by(columns, opts, idx) do - {columns, params, idx} = columns(columns, opts, idx) - {["ORDER BY ", columns], params, idx} - end - - defp limit(limit, _, idx) when limit in [:all, nil] do - {nil, [], idx} - end - defp limit(limit, opts, idx) do - {limit, params, idx} = PG.to_sql(limit, opts, idx) - {["LIMIT ", limit], params, idx} - end - - defp offset(nil, _, idx) do - {nil, [], idx} - end - defp offset(offset, opts, idx) do - {offset, params, idx} = PG.to_sql(offset, opts, idx) - {["OFFSET ", offset], params, idx} - end -end - -defimpl Sonata.Postgres, for: [Sonata.Combination.Union, Sonata.Combination.Intersect, Sonata.Combination.Except] do - alias Sonata.Postgres, as: PG - - @command [" ", (@for |> Module.split() |> List.last() |> String.upcase), " "] - - def to_sql(%{lhs: lhs, rhs: rhs, all: all}, opts, idx) do - {lhs, lhs_params, idx} = PG.to_sql(lhs, opts, idx) - {rhs, rhs_params, idx} = PG.to_sql(rhs, opts, idx) - {["(", lhs, @command, all(all), rhs, ")"], Stream.concat(lhs_params, rhs_params), idx} - end - - # TODO look at the rhs? - def on_row(_, _) do - nil - end - - defp all(true) do - " ALL" - end - defp all(_) do - "" - end -end - -defimpl Sonata.Postgres, for: Sonata.Expr.ColumnList do - alias Sonata.Postgres, as: PG - - def to_sql(%{columns: columns}, opts, idx) do - {sql, params, idx} = PG.Utils.columns(columns, opts, idx) - {["(", sql, ")"], params, idx} - end - - def on_row(_, _) do - nil - end -end - -defimpl Sonata.Postgres, for: Sonata.Expr.Operation do - alias Sonata.Postgres, as: PG - - def to_sql(%{operator: operator, rhs: rhs, lhs: lhs}, opts, idx) do - {lhs, lhs_params, idx} = PG.to_sql(lhs, opts, idx) - {rhs, rhs_params, idx} = PG.to_sql(rhs, opts, idx) - {["(", lhs, " ", operator, " ", rhs, ")"], Stream.concat(lhs_params, rhs_params), idx} - end - - def on_row(_, _) do - nil - end -end - -defimpl Sonata.Postgres, for: Sonata.Expr.Reference do - def to_sql(%{name: name}, _, idx) do - # TODO escape the reference name - {to_string(name), [], idx} - end - - def on_row(_, _) do - nil - end -end - -defimpl Sonata.Postgres, for: Sonata.CreateTable do - def to_sql(%{add_columns: columns, table: table}, opts, idx) do - ## TODO escape the table - sql = ["CREATE TABLE ", table, " ("] - {columns, {params, idx}} = Enum.map_reduce(columns, {[], idx}, fn(column, {acc_params, idx}) -> - {sql, params, idx} = Sonata.Postgres.to_sql(column, opts, idx) - {sql, {Stream.concat(acc_params, params), idx}} - end) - - ## TODO handle the other options - - {[sql, Sonata.Postgres.Utils.join(columns, ", "), ");"], params, idx} - end - - def on_row(_, _) do - nil - end -end - -defimpl Sonata.Postgres, for: Sonata.Definition.Column do - alias Sonata.Postgres, as: PG - import PG.Utils - - def to_sql(column, opts, idx) do - {name, name_params, idx} = name(column.name, opts, idx) - {type, type_params, idx} = type(column.type, opts, idx) - {check, check_params, idx} = check(column.check, opts, idx) - {reference, reference_params, idx} = reference(column.reference, opts, idx) - {primary_key, primary_key_params, idx} = primary_key(column.primary_key, opts, idx) - {constraint, constraint_params, idx} = constraint(column.constraint, opts, idx) - {unique, unique_params, idx} = unique(column.unique, opts, idx) - {default, default_params, idx} = default(column.default, opts, idx) - {not_null, not_null_params, idx} = not_null(column.not_null, opts, idx) - - { - join([ - name, - type, - check, - reference, - primary_key, - constraint, - unique, - default, - not_null - ], " "), - - Stream.concat([ - name_params, - type_params, - check_params, - reference_params, - primary_key_params, - constraint_params, - unique_params, - default_params, - not_null_params - ]), - - idx - } - end - - def on_row(_, _) do - nil - end - - defp name(nil, _, idx) do - {nil, [], idx} - end - defp name(name, _, idx) do - {to_string(name), [], idx} - end - - defp type(nil, _, idx) do - {nil, [], idx} - end - defp type(type, _, idx) do - {to_string(type), [], idx} - end - - defp check(nil, _, idx) do - {nil, [], idx} - end - defp check(check, opts, idx) do - {check, params, idx} = PG.to_sql(check, opts, idx) - {["CHECK ", check], params, idx} - end - - defp reference(nil, _, idx) do - {nil, [], idx} - end - defp reference({column, table}, _, idx) do - {["REFERENCES ", to_string(table), " (", to_string(column), ")"], [], idx} - end - defp reference(table, _, idx) when is_binary(table) or is_atom(table) do - {["REFERENCES ", to_string(table)], [], idx} - end - - defp primary_key(true, _, idx) do - {"PRIMARY KEY", [], idx} - end - defp primary_key(_, _, idx) do - {nil, [], idx} - end - - defp constraint(nil, _, idx) do - {nil, [], idx} - end - defp constraint(constraint, opts, idx) do - {constraint, params, idx} = PG.to_sql(constraint, opts, idx) - {["CONSTRAINT ", constraint], params, idx} - end - - defp unique(true, _, idx) do - {"UNIQUE", [], idx} - end - defp unique(_, _, idx) do - {nil, [], idx} - end - - defp not_null(true, _, idx) do - {"NOT NULL", [], idx} - end - defp not_null(_, _, idx) do - {nil, [], idx} - end - - defp default(nil, _, idx) do - {nil, [], idx} - end - defp default(default, opts, idx) do - {default, params, idx} = PG.to_sql(default, opts, idx) - {["DEFAULT ", default], params, idx} - end -end - -defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do - alias Sonata.Postgres, as: PG - import PG.Utils - - def to_sql(insertion, opts, idx) do - {table, table_params, idx} = table(insertion.table, opts, idx) - {fields, fields_params, idx} = fields(insertion.fields, opts, idx) - {default_values, default_values_params, idx} = default_values(insertion.default_values, opts, idx) - {rows, rows_params, idx} = rows(insertion.rows, opts, idx) - - { - join([ - "INSERT INTO", - table, - fields, - default_values, - rows, - ], " "), - - Stream.concat([ - table_params, - fields_params, - default_values_params, - rows_params, - ]), - - idx - } - end - - defp table(table, _, idx) when table in [nil, false, ""] do - {nil, [], idx} - end - defp table(table, opts, idx) when is_binary(table) do - {escape_keyword(table), opts, idx} - end - - def fields(fields, _, idx) when fields in [nil, false, ""] do - {nil, [], idx} - end - - def default_values(:true, opts, idx) do - {"DEFAULT VALUES", opts, idx} - end - - def rows(rows, _, idx) when rows in [nil, false, ""] do - {nil, [], idx} - end - # TODO - def rows(rows, opts, idx) do - {["VALUES"] ++ rows, opts, idx} - end - - # TODO - # defp on_conflict do - # end - # defp returning do - # end - - def on_row(_, _) do - nil - end -end - -defimpl Sonata.Postgres, for: Sonata.Manipulation.Update do - alias Sonata.Postgres, as: PG - import PG.Utils - - def to_sql(update, opts, idx) do - {table, table_params, idx} = table(update.table, opts, idx) - {table_alias, table_alias_params, idx} = table_alias(update.table_alias, opts, idx) - {sets, sets_params, idx} = sets(update.sets, opts, idx) - {where, where_params, idx} = where(update.where, opts, idx) - {returning, returning_params, idx} = returning(update.returning, opts, idx) - - { - join([ - "UPDATE", - table, - table_alias, - sets, - where, - returning - ], " "), - - Stream.concat([ - table_params, - table_alias_params, - sets_params, - where_params, - returning_params - ]), - - idx - } - end - - def on_row(_, _) do - nil - end - - defp table(table, _, idx) when table in [nil, false, ""] do - {nil, [], idx} - end - defp table(table, opts, idx) when is_binary(table) do - {escape_keyword(table), opts, idx} - end - - defp table_alias(nil, _, idx) do - {nil, [], idx} - end - defp table_alias(alias, opts, idx) do - {[" AS ", escape_keyword(alias)], opts, idx} - end - - defp sets(sets, _, idx) when sets in [nil, false, "", []] do - {nil, [], idx} - end - defp sets(sets, opts, idx) do - {sets, {params, idx}} = Enum.map_reduce(sets, {[], idx}, fn({field, value}, {params, idx}) -> - {field, p, idx} = Sonata.Postgres.to_sql(field, opts, idx) - {value, p, idx} = Sonata.Postgres.to_sql(value, opts, idx) - {[field, " = (", value, ")"], {Stream.concat(params, p), idx}} - end) - {["SET ", Sonata.Postgres.Utils.join(sets, ", ")], params, idx} - end - - defp where(nil, _, idx) do - {nil, [], idx} - end - defp where(expr, opts, idx) do - {where, params, idx} = PG.to_sql(expr, opts, idx) - {["WHERE ", where], params, idx} - end - - # TODO: support returning alias - defp returning(returning, _, idx) when returning in [nil, false, "", []] do - {nil, [], idx} - end - defp returning(returning, opts, idx) do - {sql, params, idx} = PG.Utils.columns(returning, opts, idx) - {["RETURNING ", sql], params, idx} - end -end - -defimpl Sonata.Postgres, for: Sonata.Misc.Call do - def to_sql(%{function: fun, arguments: arguments}, opts, idx) do - {arguments, {params, idx}} = Enum.map_reduce(arguments, {[], idx}, fn(arg, {params, idx}) -> - {arg, p, idx} = Sonata.Postgres.to_sql(arg, opts, idx) - {arg, {Stream.concat(params, p), idx}} - end) - - {[to_string(fun), "(", Sonata.Postgres.Utils.join(arguments, ", "), ")"], params, idx} - end - - def on_row(_, _) do - nil - end -end - -defimpl Sonata.Postgres, for: Sonata.Query.Value do - def to_sql(%{value: value, as: nil}, _, idx) do - {"$#{idx}", [value], idx + 1} - end - def to_sql(%{value: value, as: as}, _, idx) do - {"$#{idx} #{as}", [value], idx + 1} - end - - def on_row(_, _) do - nil - end -end - -defimpl Sonata.Postgres, for: Sonata.Expr.Value do - def to_sql(%{value: value}, _, idx) do - {"$#{idx}", [value], idx + 1} - end -end diff --git a/lib/sonata/postgres/utils.ex b/lib/sonata/postgres/utils.ex new file mode 100644 index 0000000..ec71723 --- /dev/null +++ b/lib/sonata/postgres/utils.ex @@ -0,0 +1,56 @@ +defmodule Sonata.Postgres.Utils do + import Kernel + def columns([], _, idx) do + {"*", [], idx} + end + def columns(columns, opts, idx) do + {sql, {params, idx}} = Enum.map_reduce(columns, {[], idx}, fn(column, {params, idx}) -> + {column, p, idx} = column(column, opts, idx) + {[", ", column], {Stream.concat(params, p), idx}} + end) + {pop_comma(sql), params, idx} + end + + def column(column, _, idx) when is_binary(column) do + {escape_keyword(column), [], idx} + end + def column(column, _, idx) when is_atom(column) do + {escape_keyword(Atom.to_string(column)), [], idx} + end + def column({column, alias}, opts, idx) do + {column, params, idx} = column(column, opts, idx) + {[column, " AS ", escape_keyword(alias)], params, idx} + end + def column(column, opts, idx) do + Sonata.Postgres.to_sql(column, opts, idx) + end + + def pop_comma({columns, params, idx}) do + {pop_comma(columns), params, idx} + end + def pop_comma([[", " | column] | columns]) do + [column | columns] + end + def pop_comma(other) do + other + end + + def join([], _delim) do + [] + end + def join([item | rest], delim) when item in ["", nil] do + join(rest, delim) + end + def join([item | rest], delim) do + case join(rest, delim) do + [] -> + item + rest -> + [item, delim, rest] + end + end + + def escape_keyword(value) do + to_string(value) + end +end diff --git a/lib/sonata/query.ex b/lib/sonata/query.ex index ebe4ed2..d433665 100644 --- a/lib/sonata/query.ex +++ b/lib/sonata/query.ex @@ -11,123 +11,244 @@ defmodule Sonata.Query do offset: nil, struct: nil] - defmodule Value do - defstruct [:value, :as] + def select() do + %__MODULE__{} end - defmodule Builder do - def select() do - %Sonata.Query{} - end + def select(columns) do + select() + |> column(columns) + end - def select(columns) do - select() - |> column(columns) - end + def distinct(q) do + %{q | distinct: true} + end + def distinct(%{distinct: true} = q, d) when is_list(d) do + %{q | distinct: d} + end + def distinct(%{distinct: distinct} = q, d) when is_list(d) do + %{q | distinct: distinct ++ d} + end + def distinct(q, d) do + distinct(q, [d]) + end - def distinct(q) do - %{q | distinct: true} - end - def distinct(%{distinct: true} = q, d) when is_list(d) do - %{q | distinct: d} - end - def distinct(%{distinct: distinct} = q, d) when is_list(d) do - %{q | distinct: distinct ++ d} - end - def distinct(q, d) do - distinct(q, [d]) - end + def column(%{columns: columns} = q, c) when is_list(c) do + %{q | columns: columns ++ c} + end + def column(q, c) do + column(q, [c]) + end + def column(q, c, alias) do + column(q, [{c, alias}]) + end - def column(%{columns: columns} = q, c) when is_list(c) do - %{q | columns: columns ++ c} - end - def column(q, c) do - column(q, [c]) - end - def column(q, c, alias) do - column(q, [{c, alias}]) + def value(q, value, as \\ nil) do + value = %__MODULE__.Value{value: value} + cond do + is_nil(as) -> + column(q, value) + true -> + column(q, value, as) end + end - def value(q, value, as \\ nil) do - value = %Sonata.Query.Value{value: value} - cond do - is_nil(as) -> - column(q, value) - true -> - column(q, value, as) - end - end + def from(q, from) do + %{q | from: from} + end + def from(q, from, alias) do + %{q | from: {from, alias}} + end - def from(q, from) do - %{q | from: from} - end - def from(q, from, alias) do - %{q | from: {from, alias}} - end + ## TODO add support for join + ## def join(q) do + ## + ## end + + #def join() -> inner_join() + #def inner_join() + #def left_outer_join() + #def right_outer_join() + #def full_outer_join() + #def cross_join() + #def natural_join() + + def where(q, field, operator, value) do + where(q, [{field, operator, value}]) + end + def where(q = %{where: where}, [kv | _] = kvs) when is_tuple(kv) do + where = Enum.reduce(kvs, where, fn + ({k, v}, nil) -> + Sonata.Expr.column(k) + |> Sonata.Operator.=(v) + ({k, op, v}, nil) -> + col = Sonata.Expr.column(k) + apply(Sonata.Operator, op, [col, v]) + ({k, v}, acc) -> + k = Sonata.Expr.column(k) + Sonata.Keyword.and(Sonata.Operator.=(k, v), acc) + ({k, op, v}, acc) -> + col = Sonata.Expr.column(k) + apply(Sonata.Operator, op, [col, v]) + |> Sonata.Keyword.and(acc) + end) + %{q | where: where} + end - ## TODO add support for join - ## def join(q) do - ## - ## end - - #def join() -> inner_join() - #def inner_join() - #def left_outer_join() - #def right_outer_join() - #def full_outer_join() - #def cross_join() - #def natural_join() - - def where(q, field, operator, value) do - where(q, [{field, operator, value}]) - end - def where(q = %{where: where}, [kv | _] = kvs) when is_tuple(kv) do - where = Enum.reduce(kvs, where, fn - ({k, v}, nil) -> - Sonata.Expr.column(k) - |> Sonata.Expr.=(v) - ({k, op, v}, nil) -> - col = Sonata.Expr.column(k) - apply(Sonata.Expr, op, [col, v]) - ({k, v}, acc) -> - k = Sonata.Expr.column(k) - Sonata.Expr.and(Sonata.Expr.=(k, v), acc) - ({k, op, v}, acc) -> - col = Sonata.Expr.column(k) - apply(Sonata.Expr, op, [col, v]) - |> Sonata.Expr.and(acc) - end) - %{q | where: where} - end + def group_by(%{group_by: group_by} = q, c) when is_list(c) do + %{q | group_by: group_by ++ c} + end + def group_by(q, c) do + group_by(q, [c]) + end - def group_by(%{group_by: group_by} = q, c) when is_list(c) do - %{q | group_by: group_by ++ c} - end - def group_by(q, c) do - group_by(q, [c]) - end + def having(q, expr) do + %{q | having: expr} + end - def having(q, expr) do - %{q | having: expr} - end + def order_by(q, expr) do + Sonata.OrderBy.order_by(q, expr) + end + def order_by(q, expr, order) do + Sonata.OrderBy.order_by(q, expr, order) + end - def order_by(q, expr) do - Sonata.OrderBy.Builder.order_by(q, expr) - end - def order_by(q, expr, order) do - Sonata.OrderBy.Builder.order_by(q, expr, order) - end + def limit(q, limit) do + %{q | limit: limit} + end - def limit(q, limit) do - %{q | limit: limit} - end + def offset(q, offset) do + %{q | offset: offset} + end - def offset(q, offset) do - %{q | offset: offset} - end + def into_struct(q, struct) do + %{q | struct: struct} + end +end - def into_struct(q, struct) do - %{q | struct: struct} - end +defimpl Sonata.Postgres, for: Sonata.Query do + alias Sonata.Postgres, as: PG + import PG.Utils + + def to_sql(query, opts, idx) do + {distinct, distinct_params, idx} = distinct(query.distinct, opts, idx) + {columns, column_params, idx} = columns(query.columns, opts, idx) + {from, from_params, idx} = from(query.from, opts, idx) + {where, where_params, idx} = where(query.where, opts, idx) + {group_by, group_by_params, idx} = group_by(query.group_by, opts, idx) + {having, having_params, idx} = having(query.having, opts, idx) + {order_by, order_by_params, idx} = order_by(query.order_by, opts, idx) + {limit, limit_params, idx} = limit(query.limit, opts, idx) + {offset, offset_params, idx} = offset(query.offset, opts, idx) + + { + join([ + "SELECT", + distinct, + columns, + from, + where, + group_by, + having, + order_by, + limit, + offset + ], " "), + + Stream.concat([ + distinct_params, + column_params, + from_params, + where_params, + group_by_params, + having_params, + order_by_params, + limit_params, + offset_params + ]), + + idx + } + end + + def on_row(%{struct: nil}, _) do + nil + end + def on_row(%{struct: struct}, _) do + fn(row) -> struct.__from_row__(row) end + end + + defp distinct(distinct, _, idx) when distinct in [nil, false, []] do + {nil, [], idx} + end + defp distinct(true, _, idx) do + {"DISTINCT", [], idx} + end + defp distinct(distinct, opts, idx) when is_list(distinct) do + {columns, params, idx} = columns(distinct, opts, idx) + {["DISTINCT ON (", columns, ")"], params, idx} + end + + defp from(nil, _, idx) do + {nil, [], idx} + end + defp from(from, _, idx) when is_binary(from) do + {["FROM ", escape_keyword(from)], [], idx} + end + defp from({from, alias}, opts, idx) do + {from, params, idx} = from(from, opts, idx) + {[from, " AS ", alias], params, idx} + end + defp from(from, opts, idx) do + {from, params, idx} = PG.to_sql(from, opts, idx) + {["FROM (", from, ")"], params, idx} + end + + defp where(nil, _, idx) do + {nil, [], idx} + end + defp where(expr, opts, idx) do + {where, params, idx} = PG.to_sql(expr, opts, idx) + {["WHERE ", where], params, idx} + end + + defp group_by([], _, idx) do + {nil, [], idx} + end + defp group_by(columns, opts, idx) do + {columns, params} = columns(columns, opts, idx) + {["GROUP BY ", columns], params, idx} + end + + defp having(nil, _, idx) do + {nil, [], idx} + end + defp having(expr, opts, idx) do + {having, params} = PG.to_sql(expr, opts, idx) + {["HAVING ", having], params, idx} + end + + defp order_by([], _, idx) do + {nil, [], idx} + end + defp order_by(columns, opts, idx) do + {columns, params, idx} = columns(columns, opts, idx) + {["ORDER BY ", columns], params, idx} + end + + defp limit(limit, _, idx) when limit in [:all, nil] do + {nil, [], idx} + end + defp limit(limit, opts, idx) do + {limit, params, idx} = PG.to_sql(limit, opts, idx) + {["LIMIT ", limit], params, idx} + end + + defp offset(nil, _, idx) do + {nil, [], idx} + end + defp offset(offset, opts, idx) do + {offset, params, idx} = PG.to_sql(offset, opts, idx) + {["OFFSET ", offset], params, idx} end end diff --git a/lib/sonata/query/value.ex b/lib/sonata/query/value.ex new file mode 100644 index 0000000..cfaa4de --- /dev/null +++ b/lib/sonata/query/value.ex @@ -0,0 +1,16 @@ +defmodule Sonata.Query.Value do + defstruct [:value, :as] +end + +defimpl Sonata.Postgres, for: Sonata.Query.Value do + def to_sql(%{value: value, as: nil}, _, idx) do + {"$#{idx}", [value], idx + 1} + end + def to_sql(%{value: value, as: as}, _, idx) do + {"$#{idx} #{as}", [value], idx + 1} + end + + def on_row(_, _) do + nil + end +end diff --git a/mix.exs b/mix.exs index 917ef8e..6c8b723 100644 --- a/mix.exs +++ b/mix.exs @@ -10,23 +10,14 @@ defmodule Sonata.Mixfile do deps: deps()] end - # Configuration for the OTP application - # - # Type "mix help compile.app" for more information def application do [applications: [:logger]] end - # Dependencies can be Hex packages: - # - # {:mydep, "~> 0.3.0"} - # - # Or git/path repositories: - # - # {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"} - # - # Type "mix help deps" for more examples and options defp deps do - [] + [{:csv, "~> 2.0", only: :dev}, + {:ecto, "~> 2.1.4", only: :test}, + {:mix_test_watch, "~> 0.4.1", only: :dev}, + {:postgrex, "~> 0.13.3", only: :test},] end end diff --git a/mix.lock b/mix.lock new file mode 100644 index 0000000..c7d50f4 --- /dev/null +++ b/mix.lock @@ -0,0 +1,11 @@ +%{"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [], [], "hexpm"}, + "csv": {:hex, :csv, "2.0.0", "c66fea89ba7862b94901baf0871285e9b73cad89c5fdb57a6386d2adcf29593e", [], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm"}, + "db_connection": {:hex, :db_connection, "1.1.2", "2865c2a4bae0714e2213a0ce60a1b12d76a6efba0c51fbda59c9ab8d1accc7a8", [], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, + "decimal": {:hex, :decimal, "1.4.0", "fac965ce71a46aab53d3a6ce45662806bdd708a4a95a65cde8a12eb0124a1333", [], [], "hexpm"}, + "ecto": {:hex, :ecto, "2.1.4", "d1ba932813ec0e0d9db481ef2c17777f1cefb11fc90fa7c142ff354972dfba7e", [], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, + "epgsql": {:hex, :epgsql, "3.3.0", "974a578340e52012cbab820ce756e7ed1df1baf0110c59a6753d8337a2cf9454", [], [], "hexpm"}, + "fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [], [], "hexpm"}, + "mix_test_watch": {:hex, :mix_test_watch, "0.4.1", "a98a84c795623f1ba020324f4354cf30e7120ba4dab65f9c2ae300f830a25f75", [], [{:fs, "~> 0.9.1", [hex: :fs, repo: "hexpm", optional: false]}], "hexpm"}, + "parallel_stream": {:hex, :parallel_stream, "1.0.5", "4c78d3e675f9eff885cbe252c89a8fc1d2fb803c0d03a914281e587834e09431", [], [], "hexpm"}, + "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [], [], "hexpm"}, + "postgrex": {:hex, :postgrex, "0.13.3", "c277cfb2a9c5034d445a722494c13359e361d344ef6f25d604c2353185682bfc", [], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"}} diff --git a/test/create_table_test.exs b/test/create_table_test.exs new file mode 100644 index 0000000..ff6e089 --- /dev/null +++ b/test/create_table_test.exs @@ -0,0 +1,48 @@ +defmodule Test.Sonata.CreateTable do + use Test.Sonata + + test "my_first_table" do + create_table("my_first_table") + |> add_column("first_column", "text") + |> add_column("second_column", "integer") + |> assert_sql(table_info("my_first_table")) + end + + test "products" do + create_table("products") + |> add_column("product_no", "integer") + |> add_column("name", "text") + |> add_column("price", "numeric") + |> assert_sql(table_info("products")) + end + + test "default products" do + create_table("products") + |> add_column([ + column("product_no", "integer"), + column("name", "text"), + column("price", "numeric") + |> default(9.99), + ]) + |> assert_sql(table_info("products")) + end + + test "default product no" do + create_table("products") + |> add_column([ + column("product_no", "integer") + |> default(nextval("products_product_no_seq")), + ]) + |> assert_sql(table_info("products")) + end + + defp table_info(name) do + """ + SELECT + column_name, + data_type + FROM INFORMATION_SCHEMA.COLUMNS + WHERE table_name = '#{name}'; + """ + end +end diff --git a/test/definition_test.exs b/test/definition_test.exs deleted file mode 100644 index cc84f8c..0000000 --- a/test/definition_test.exs +++ /dev/null @@ -1,66 +0,0 @@ -defmodule Test.Sonata.Definition do - use ExUnit.Case - - test "create table" do - ## https://www.postgresql.org/docs/9.6/static/ddl-basics.html - ## https://www.postgresql.org/docs/9.6/static/ddl-default.html - ## https://www.postgresql.org/docs/9.6/static/ddl-constraints.html - create_table("users") - |> field("id", [ - type("text"), - unique, - primary_key - ]) - |> field("name", [ - type("text"), - not_null - ]) - |> field("age", &( - &1 - |> type("integer") - |> default(0) - |> check(gte("age", 0)) - )) - |> check(lte("age", 120)) - - # constraint("name", unique) - - # unique("field") - # unique(["field1", "field2"]) - - # primary_key("field") - # primary_key(["field1", "field2"]) - - # references("organizations") - # references("organizations", "id") - # references("organizations") |> on_delete_cascade() - end - - test "alter" do - ## https://www.postgresql.org/docs/9.6/static/ddl-alter.html - alter_table("users") - |> add_column("birthday", [ - type("timestamp") - ]) - |> drop_column("age") - - end - - test "priviledge" do - ## https://www.postgresql.org/docs/9.6/static/ddl-priv.html - - grant("users", [update]) - |> to("joe") - - revoke("users", ["ALL"]) - |> to("joe") - end - - test "inherits" do - ## https://www.postgresql.org/docs/9.6/static/ddl-inherit.html - end - - test "drop table" do - drop_table("users") - end -end diff --git a/test/manipulation_test.exs b/test/manipulation_test.exs deleted file mode 100644 index a779118..0000000 --- a/test/manipulation_test.exs +++ /dev/null @@ -1,22 +0,0 @@ -defmodule Test.Sonata.Manipulation do - use ExUnit.Case - - test "insert" do - insert_into("users", {"name", "birthday"}) - |> values({"Joe", "1960"}) - |> values([ - {"Mike", "1961"}, - {"Robert", "1962"} - ]) - |> on_conflict() # TODO - end - - test "update" do - update("users") - |> set(eql("name", "Joe")) - end - - test "delete" do - delete_from("users") - end -end diff --git a/test/query_test.exs b/test/query_test.exs deleted file mode 100644 index 7e6cb43..0000000 --- a/test/query_test.exs +++ /dev/null @@ -1,16 +0,0 @@ -defmodule Test.Sonata.Query do - use ExUnit.Case - - test "select" do - ## https://www.postgresql.org/docs/9.5/static/queries-overview.html - select() - |> column("name") - |> column(add(field("age"), 2)) - |> column(call("random")) - |> from("users", "u") - end - - test "join" do - ## https://www.postgresql.org/docs/9.5/static/queries-table-expressions.html - end -end diff --git a/test/sonata_test.exs b/test/sonata_test.exs deleted file mode 100644 index f3fdd05..0000000 --- a/test/sonata_test.exs +++ /dev/null @@ -1,72 +0,0 @@ -defmodule SonataTest do - use ExUnit.Case - - test "create table" do - ## https://www.postgresql.org/docs/9.6/static/ddl-basics.html - ## https://www.postgresql.org/docs/9.6/static/ddl-default.html - ## https://www.postgresql.org/docs/9.6/static/ddl-constraints.html - create_table("users") - |> field("id", [ - type("text"), - unique, - primary_key - ]) - |> field("name", [ - type("text"), - not_null - ]) - |> field("age", &( - &1 - |> type("integer") - |> default(0) - |> check(gte("age", 0)) - )) - |> check(lte("age", 120)) - - # constraint("name", unique) - - # unique("field") - # unique(["field1", "field2"]) - - # primary_key("field") - # primary_key(["field1", "field2"]) - - # references("organizations") - # references("organizations", "id") - # references("organizations") |> on_delete_cascade() - end - - test "alter" do - ## https://www.postgresql.org/docs/9.6/static/ddl-alter.html - alter_table("users") - |> add_column("birthday", [ - type("timestamp") - ]) - |> drop_column("age") - - end - - test "priviledge" do - ## https://www.postgresql.org/docs/9.6/static/ddl-priv.html - - grant("users", [update]) - |> to("joe") - - revoke("users", ["ALL"]) - |> to("joe") - end - - test "inherits" do - ## https://www.postgresql.org/docs/9.6/static/ddl-inherit.html - end - - test "drop table" do - drop_table("users") - end - - test "select" do - select(["*"]) - |> from("users") - |> where(eq("name", 3)) - end -end diff --git a/test/test_helper.exs b/test/test_helper.exs index 869559e..d41ec2c 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -1 +1,121 @@ +defmodule Test.Sonata.Repo do + use Ecto.Repo, + otp_app: :sonata +end + +alias Test.Sonata.Repo +Application.ensure_all_started(:postgrex) +Repo.start_link() +Ecto.Adapters.SQL.Sandbox.mode(Repo, :manual) + +defmodule Test.Sonata do + use ExUnit.CaseTemplate, async: true + + using do + quote do + use Sonata + import unquote(__MODULE__) + end + end + + defp load_snapshot(path) do + {contents, []} = Code.eval_file(path) + contents + rescue + Code.LoadError -> + %{} + end + + setup_all context do + %{case: name} = context + + path = "_snapshots/#{inspect(name)}.snapshot" + + snapshots = load_snapshot(path) + + File.mkdir_p!(Path.dirname(path)) + + pid = spawn(__MODULE__, :__loop__, [snapshots]) + :erlang.register(name, pid) + + on_exit fn -> + send(pid, {:close, self()}) + receive do + {:snapshots, snapshots} -> + File.write!(path, inspect(snapshots, limit: :infinity, pretty: true)) + end + end + + [snapshots: snapshots] + end + + setup context do + %{test: test, snapshots: snapshots} = context + + Process.put(:test_name, test) + Process.put(:snapshot, snapshots[test]) + + :ok = Ecto.Adapters.SQL.Sandbox.checkout(Repo) + end + + def __loop__(snapshots) do + receive do + {:add_snapshot, {key, value}} -> + snapshots + |> Map.put(key, value) + |> __loop__() + {:close, pid} -> + send(pid, {:snapshots, snapshots}) + end + end + + defmacro assert_sql(struct, command) do + quote do + {sql, params, _on_row} = Sonata.to_sql(unquote(struct)) + sql = :erlang.iolist_to_binary(sql) + + Ecto.Adapters.SQL.query!(Repo, sql, params) + + result = Ecto.Adapters.SQL.query!(Repo, unquote(command)) + |> postgrex_result() + + record_result(__MODULE__, result) + end + end + + defmacro assert_snapshot(struct) do + quote do + {sql, params, on_row} = Sonata.to_sql(unquote(struct)) + sql = :erlang.iolist_to_binary(sql) + + result = Ecto.Adapters.SQL.query!(Repo, sql, params) + |> postgrex_result() + |> Enum.map(on_row) + + record_result(__MODULE__, result) + end + end + + def record_result(module, result) do + test_name = Process.get(:test_name) + case Process.get(:snapshot) do + nil -> + :ok + snapshot -> + assert result == snapshot + end + + send(module, {:add_snapshot, {test_name, result}}) + end + + def postgrex_result(%{columns: columns, rows: rows}) do + rows + |> Enum.map(fn(row) -> + columns + |> Stream.zip(row) + |> Enum.into(%{}) + end) + end +end + ExUnit.start() From da5c9ed2e99ee00d3167f07b46b2dfcc48f85e11 Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Wed, 26 Jul 2017 19:21:46 -0600 Subject: [PATCH 06/43] add travis file --- .travis.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..75b4422 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +language: elixir +elixir: + - 1.5.0 +otp_release: + - 20.0 +env: + global: + - DATABASE_URL=postgres://postgres:@localhost:5433/sonata +services: + - postgresql +addons: + postgresql: "9.6" +before_script: + - psql -c 'create database sonata;' -U postgres From dba3cd26eceb556263a61957a95972b0d47b1c10 Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Wed, 26 Jul 2017 19:25:34 -0600 Subject: [PATCH 07/43] fix travis port --- .travis.yml | 2 +- README.md | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 75b4422..4fbc789 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ otp_release: - 20.0 env: global: - - DATABASE_URL=postgres://postgres:@localhost:5433/sonata + - DATABASE_URL=postgres://postgres:@localhost:5432/sonata services: - postgresql addons: diff --git a/README.md b/README.md index c363ee8..7c57c5c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# sonata +# sonata [![Build Status](https://travis-ci.org/exstruct/sonata.svg?branch=master)](https://travis-ci.org/exstruct/sonata) sql functions for elixir @@ -8,12 +8,16 @@ If [available in Hex](https://hex.pm/docs/publish), the package can be installed 1. Add sonata to your list of dependencies in `mix.exs`: - def deps do - [{:sonata, "~> 0.1.0"}] - end + ```elixir + def deps do + [{:sonata, "~> 0.1.0"}] + end + ``` 2. Ensure sonata is started before your application: - def application do - [applications: [:sonata]] - end + ```elixir + def application do + [applications: [:sonata]] + end + ``` From 17bb9b18dc0cb838be848bba97ff0030ea6d87dc Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Wed, 26 Jul 2017 19:29:13 -0600 Subject: [PATCH 08/43] cache build directories --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 4fbc789..26177d8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,3 +12,7 @@ addons: postgresql: "9.6" before_script: - psql -c 'create database sonata;' -U postgres +cache: + directories: + - _build + - deps From 7d2f001d463317df6c0d5f1572a16c85c11e9fa7 Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Wed, 26 Jul 2017 21:34:41 -0600 Subject: [PATCH 09/43] fix tests --- _snapshots/Test.Sonata.CreateTable.snapshot | 29 ++++++++- lib/sonata.ex | 7 +- lib/sonata/create_table.ex | 9 ++- lib/sonata/definition/column.ex | 72 ++++++++++++++++++--- lib/sonata/expr.ex | 40 ++++++++++++ lib/sonata/keyword.ex | 35 ---------- lib/sonata/postgres.ex | 10 +++ lib/sonata/query.ex | 4 +- test/create_table_test.exs | 43 +++++++++++- test/test_helper.exs | 19 ++++++ 10 files changed, 216 insertions(+), 52 deletions(-) delete mode 100644 lib/sonata/keyword.ex diff --git a/_snapshots/Test.Sonata.CreateTable.snapshot b/_snapshots/Test.Sonata.CreateTable.snapshot index e3af21e..4186bff 100644 --- a/_snapshots/Test.Sonata.CreateTable.snapshot +++ b/_snapshots/Test.Sonata.CreateTable.snapshot @@ -1,6 +1,31 @@ -%{"test my_first_table": [%{"column_name" => "first_column", +%{"test default product no": [%{"column_name" => "product_no", + "data_type" => "integer"}], + "test default products": [%{"column_name" => "product_no", + "data_type" => "integer"}, + %{"column_name" => "name", "data_type" => "text"}, + %{"column_name" => "price", "data_type" => "numeric"}], + "test my_first_table": [%{"column_name" => "first_column", "data_type" => "text"}, %{"column_name" => "second_column", "data_type" => "integer"}], + "test product SERIAL": [%{"column_name" => "product_no", + "data_type" => "integer"}], "test products": [%{"column_name" => "product_no", "data_type" => "integer"}, %{"column_name" => "name", "data_type" => "text"}, - %{"column_name" => "price", "data_type" => "numeric"}]} \ No newline at end of file + %{"column_name" => "price", "data_type" => "numeric"}], + "test products CHECK price > 0": %Postgrex.Error{connection_id: nil, + message: nil, + postgres: %{code: :check_violation, constraint: "products_price_check", + detail: "Failing row contains (1, My product, -1).", file: "execMain.c", + line: "1760", + message: "new row for relation \"products\" violates check constraint \"products_price_check\"", + pg_code: "23514", routine: "ExecConstraints", schema: "public", + severity: "ERROR", table: "products", unknown: "ERROR"}}, + "test products SERIAL": [%{"column_name" => "product_no", + "data_type" => "integer"}], + "test products named CHECK": %Postgrex.Error{connection_id: nil, message: nil, + postgres: %{code: :check_violation, constraint: "positive_price", + detail: "Failing row contains (1, My product, -1).", file: "execMain.c", + line: "1760", + message: "new row for relation \"products\" violates check constraint \"positive_price\"", + pg_code: "23514", routine: "ExecConstraints", schema: "public", + severity: "ERROR", table: "products", unknown: "ERROR"}}} \ No newline at end of file diff --git a/lib/sonata.ex b/lib/sonata.ex index e58f1c3..a3a6778 100644 --- a/lib/sonata.ex +++ b/lib/sonata.ex @@ -1,7 +1,12 @@ defmodule Sonata do defmacro __using__(_) do quote do - import Sonata.{CreateTable,Definition.Column,Function} + import Sonata.{ + CreateTable, + Definition.Column, + Expr, + Function + } end end diff --git a/lib/sonata/create_table.ex b/lib/sonata/create_table.ex index 90939b5..1362c3f 100644 --- a/lib/sonata/create_table.ex +++ b/lib/sonata/create_table.ex @@ -12,17 +12,22 @@ defmodule Sonata.CreateTable do end defimpl Sonata.Postgres, for: Sonata.CreateTable do + alias Sonata.Postgres, as: PG + alias PG.Utils + def to_sql(%{add_columns: columns, table: table}, opts, idx) do + opts = Map.put(opts, :params, false) + ## TODO escape the table sql = ["CREATE TABLE ", table, " ("] {columns, {params, idx}} = Enum.map_reduce(columns, {[], idx}, fn(column, {acc_params, idx}) -> - {sql, params, idx} = Sonata.Postgres.to_sql(column, opts, idx) + {sql, params, idx} = PG.to_sql(column, opts, idx) {sql, {Stream.concat(acc_params, params), idx}} end) ## TODO handle the other options - {[sql, Sonata.Postgres.Utils.join(columns, ", "), ");"], params, idx} + {[sql, Utils.join(columns, ", "), ");"], params, idx} end def on_row(_, _) do diff --git a/lib/sonata/definition/column.ex b/lib/sonata/definition/column.ex index 6835026..768342f 100644 --- a/lib/sonata/definition/column.ex +++ b/lib/sonata/definition/column.ex @@ -15,16 +15,51 @@ defmodule Sonata.Definition.Column do deferrable: false, initially: nil,] + defmodule Check do + defstruct [ + name: nil, + expr: nil, + inherit: true, + ] + end + def column(name, type) do - %Sonata.Definition.Column{name: name, type: type} + %__MODULE__{name: name, type: type} end - def check(column, check) do - %{column | check: {:inherit, check}} + def check(column, name \\ nil, expr) do + merge_check(column, %Check{ + name: name, + expr: expr, + }) end - def check(column, check, :no_inherit) do - %{column | check: {:no_inherit, check}} + def check_no_inherit(column, name \\ nil, expr) do + merge_check(column, %Check{ + name: name, + expr: expr, + inherit: false, + }) + end + + defp merge_check(%{check: nil} = column, check) do + %{column | check: check} + end + defp merge_check(%{ + check: %{ + expr: e, + name: n, + inherit: i + } + } = column, %{ + inherit: i, + expr: expr, + } = check) do + %{column | check: %Check{ + name: n, + expr: Sonata.Expr.and(e, expr), + inherit: i, + }} end def references(column, table) do @@ -167,8 +202,7 @@ defimpl Sonata.Postgres, for: Sonata.Definition.Column do {nil, [], idx} end defp check(check, opts, idx) do - {check, params, idx} = PG.to_sql(check, opts, idx) - {["CHECK ", check], params, idx} + PG.to_sql(check, opts, idx) end defp reference(nil, _, idx) do @@ -216,7 +250,27 @@ defimpl Sonata.Postgres, for: Sonata.Definition.Column do defp default(default, opts, idx) do {default, params, idx} = PG.to_sql(default, opts, idx) {["DEFAULT ", default], params, idx} - # TODO wtf postgrex? - # {["DEFAULT ", inspect(default)], [], idx} + end +end + +defimpl Sonata.Postgres, for: Sonata.Definition.Column.Check do + alias Sonata.Postgres, as: PG + import PG.Utils + + def to_sql(%{name: name, expr: expr, inherit: inherit}, opts, idx) do + {expr, params, idx} = PG.to_sql(expr, opts, idx) + {[name(name), "CHECK ", expr], params, idx} + end + + defp name(nil) do + "" + end + defp name(name) do + # TODO escape + ["CONSTRAINT ", name, " "] + end + + def on_row(_, _) do + nil end end diff --git a/lib/sonata/expr.ex b/lib/sonata/expr.ex index a11bdf3..7336861 100644 --- a/lib/sonata/expr.ex +++ b/lib/sonata/expr.ex @@ -22,4 +22,44 @@ defmodule Sonata.Expr do def value(value) do %__MODULE__.Value{value: value} end + + defmacro op(lhs, name, rhs) do + quote do + Sonata.Operator.unquote(name)(unquote(lhs), unquote(rhs)) + end + end + + alias Sonata.Expr.Operator + + keywords = [ + :and, + :between, + :is_distinct_from, + :is_not_distinct_from, + :is_null, + :is_not_null, + :is_true, + :is_not_true, + :is_false, + :is_not_false, + :is_unknown, + :is_not_unknown, + :like, + :not_like, + :ilike, + :not_ilike, + :similar_to, + :not_similar_to, + ] + + for keyword <- keywords do + keyword_s = keyword |> to_string() |> String.upcase() |> String.replace("_", " ") + def unquote(keyword)(lhs, rhs) do + %Operator{operator: unquote(keyword_s), lhs: lhs, rhs: rhs} + end + end + + def not(rhs) do + %Sonata.Expr.UnaryOperator{operator: "NOT", rhs: rhs} + end end diff --git a/lib/sonata/keyword.ex b/lib/sonata/keyword.ex deleted file mode 100644 index 993a324..0000000 --- a/lib/sonata/keyword.ex +++ /dev/null @@ -1,35 +0,0 @@ -defmodule Sonata.Keyword do - alias Sonata.Expr.Operator - - keywords = [ - :and, - :between, - :is_distinct_from, - :is_not_distinct_from, - :is_null, - :is_not_null, - :is_true, - :is_not_true, - :is_false, - :is_not_false, - :is_unknown, - :is_not_unknown, - :like, - :not_like, - :ilike, - :not_ilike, - :similar_to, - :not_similar_to, - ] - - for keyword <- keywords do - keyword_s = keyword |> to_string() |> String.upcase() |> String.replace("_", " ") - def unquote(keyword)(lhs, rhs) do - %Operator{operator: unquote(keyword_s), lhs: lhs, rhs: rhs} - end - end - - def not(rhs) do - %Sonata.Expr.UnaryOperator{operator: "NOT", rhs: rhs} - end -end diff --git a/lib/sonata/postgres.ex b/lib/sonata/postgres.ex index 96bb340..68651c9 100644 --- a/lib/sonata/postgres.ex +++ b/lib/sonata/postgres.ex @@ -9,10 +9,20 @@ defimpl Sonata.Postgres, for: [Integer, Float, Atom, BitString] do |> Atom.to_string() |> to_sql(opts, idx) end + def to_sql(value, %{params: false}, idx) do + {escape(value), [], idx} + end def to_sql(value, _opts, idx) do {"$#{idx}", [value], idx + 1} end + defp escape(value) when is_number(value) do + to_string(value) + end + defp escape(value) when is_binary(value) do + "'" <> String.replace(value, "'", "''") <> "'" + end + def on_row(_, _) do nil end diff --git a/lib/sonata/query.ex b/lib/sonata/query.ex index d433665..e45cf1f 100644 --- a/lib/sonata/query.ex +++ b/lib/sonata/query.ex @@ -86,11 +86,11 @@ defmodule Sonata.Query do apply(Sonata.Operator, op, [col, v]) ({k, v}, acc) -> k = Sonata.Expr.column(k) - Sonata.Keyword.and(Sonata.Operator.=(k, v), acc) + Sonata.Expr.and(Sonata.Operator.=(k, v), acc) ({k, op, v}, acc) -> col = Sonata.Expr.column(k) apply(Sonata.Operator, op, [col, v]) - |> Sonata.Keyword.and(acc) + |> Sonata.Expr.and(acc) end) %{q | where: where} end diff --git a/test/create_table_test.exs b/test/create_table_test.exs index ff6e089..94d82c7 100644 --- a/test/create_table_test.exs +++ b/test/create_table_test.exs @@ -31,11 +31,52 @@ defmodule Test.Sonata.CreateTable do create_table("products") |> add_column([ column("product_no", "integer") - |> default(nextval("products_product_no_seq")), + |> default(random()), ]) |> assert_sql(table_info("products")) end + test "products SERIAL" do + create_table("products") + |> add_column([ + column("product_no", "SERIAL") + ]) + |> assert_sql(table_info("products")) + end + + test "products CHECK price > 0" do + create_table("products") + |> add_column([ + column("product_no", "integer"), + column("name", "text"), + column("price", "numeric") + |> check( + op(column("price"), :>, 0) + ), + ]) + |> assert_sql_error(""" + INSERT INTO products VALUES + (1, 'My product', -1); + """) + end + + test "products named CHECK" do + create_table("products") + |> add_column([ + column("product_no", "integer"), + column("name", "text"), + column("price", "numeric") + |> check( + "positive_price", + op(column("price"), :>, 0) + ), + ]) + |> assert_sql_error(""" + INSERT INTO products VALUES + (1, 'My product', -1); + """) + end + defp table_info(name) do """ SELECT diff --git a/test/test_helper.exs b/test/test_helper.exs index d41ec2c..c06c6ef 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -83,6 +83,25 @@ defmodule Test.Sonata do end end + defmacro assert_sql_error(struct, command) do + quote do + {sql, params, _on_row} = Sonata.to_sql(unquote(struct)) + sql = :erlang.iolist_to_binary(sql) + + Ecto.Adapters.SQL.query!(Repo, sql, params) + + error = assert_raise Postgrex.Error, fn -> + Ecto.Adapters.SQL.query!(Repo, unquote(command)) + end + + error = Map.merge(error, %{ + connection_id: nil + }) + + record_result(__MODULE__, error) + end + end + defmacro assert_snapshot(struct) do quote do {sql, params, on_row} = Sonata.to_sql(unquote(struct)) From 9000a83494db6d89c45ddcb19a0a09643d56f5dc Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Thu, 27 Jul 2017 01:28:22 -0600 Subject: [PATCH 10/43] escape columns and tables --- _snapshots/Test.Sonata.CreateTable.snapshot | 17 ++- lib/sonata.ex | 9 +- lib/sonata/alter_table.ex | 4 +- lib/sonata/builder.ex | 12 ++ lib/sonata/combination.ex | 4 +- lib/sonata/create_table.ex | 126 ++++++++++++++++++-- lib/sonata/definition.ex | 87 -------------- lib/sonata/definition/check.ex | 28 +++++ lib/sonata/definition/column.ex | 117 ++++++++---------- lib/sonata/drop_table.ex | 24 ++++ lib/sonata/expr.ex | 11 ++ lib/sonata/expr/call.ex | 9 +- lib/sonata/expr/reference.ex | 5 +- lib/sonata/expr/unary_operator.ex | 13 ++ lib/sonata/manipulation/insertion.ex | 6 +- lib/sonata/manipulation/update.ex | 8 +- lib/sonata/postgres.ex | 22 +++- lib/sonata/postgres/utils.ex | 33 +++-- lib/sonata/query.ex | 43 ++++--- test/create_table_test.exs | 71 ++++++++--- 20 files changed, 411 insertions(+), 238 deletions(-) delete mode 100644 lib/sonata/definition.ex create mode 100644 lib/sonata/definition/check.ex create mode 100644 lib/sonata/drop_table.ex diff --git a/_snapshots/Test.Sonata.CreateTable.snapshot b/_snapshots/Test.Sonata.CreateTable.snapshot index 4186bff..0dab39b 100644 --- a/_snapshots/Test.Sonata.CreateTable.snapshot +++ b/_snapshots/Test.Sonata.CreateTable.snapshot @@ -7,11 +7,17 @@ "test my_first_table": [%{"column_name" => "first_column", "data_type" => "text"}, %{"column_name" => "second_column", "data_type" => "integer"}], - "test product SERIAL": [%{"column_name" => "product_no", - "data_type" => "integer"}], "test products": [%{"column_name" => "product_no", "data_type" => "integer"}, %{"column_name" => "name", "data_type" => "text"}, %{"column_name" => "price", "data_type" => "numeric"}], + "test products CHECK operator": %Postgrex.Error{connection_id: nil, + message: nil, + postgres: %{code: :check_violation, constraint: "products_price_check", + detail: "Failing row contains (1, My product, -1).", file: "execMain.c", + line: "1760", + message: "new row for relation \"products\" violates check constraint \"products_price_check\"", + pg_code: "23514", routine: "ExecConstraints", schema: "public", + severity: "ERROR", table: "products", unknown: "ERROR"}}, "test products CHECK price > 0": %Postgrex.Error{connection_id: nil, message: nil, postgres: %{code: :check_violation, constraint: "products_price_check", @@ -28,4 +34,11 @@ line: "1760", message: "new row for relation \"products\" violates check constraint \"positive_price\"", pg_code: "23514", routine: "ExecConstraints", schema: "public", + severity: "ERROR", table: "products", unknown: "ERROR"}}, + "test table-wide checks": %Postgrex.Error{connection_id: nil, message: nil, + postgres: %{code: :check_violation, constraint: "products_check", + detail: "Failing row contains (1, My product, 100, 400).", + file: "execMain.c", line: "1760", + message: "new row for relation \"products\" violates check constraint \"products_check\"", + pg_code: "23514", routine: "ExecConstraints", schema: "public", severity: "ERROR", table: "products", unknown: "ERROR"}}} \ No newline at end of file diff --git a/lib/sonata.ex b/lib/sonata.ex index a3a6778..3d43278 100644 --- a/lib/sonata.ex +++ b/lib/sonata.ex @@ -2,10 +2,17 @@ defmodule Sonata do defmacro __using__(_) do quote do import Sonata.{ + AlterTable, + Builder, + Combination, CreateTable, + DropTable, Definition.Column, Expr, - Function + Function, + Manipulation, + OrderBy, + Query } end end diff --git a/lib/sonata/alter_table.ex b/lib/sonata/alter_table.ex index 7ff9eac..080588c 100644 --- a/lib/sonata/alter_table.ex +++ b/lib/sonata/alter_table.ex @@ -1,7 +1,7 @@ defmodule Sonata.AlterTable do - use Sonata.Definition + defstruct [table: nil] def alter_table(table) do - %Sonata.AlterTable{table: table} + %__MODULE__{table: table} end end diff --git a/lib/sonata/builder.ex b/lib/sonata/builder.ex index fa0448e..e2672c9 100644 --- a/lib/sonata/builder.ex +++ b/lib/sonata/builder.ex @@ -1,5 +1,17 @@ defmodule Sonata.Builder do + defprotocol Check do + def check(struct, name, check) + end + + defprotocol Column do + def column(struct, type) + end + defprotocol Constraint do def constraint(struct, name, constraint) end + + defdelegate check(struct, name \\ nil, check), to: Check + defdelegate column(struct, type), to: Column + defdelegate constraint(struct, name, constraint), to: Constraint end diff --git a/lib/sonata/combination.ex b/lib/sonata/combination.ex index b49fd0d..9af7362 100644 --- a/lib/sonata/combination.ex +++ b/lib/sonata/combination.ex @@ -19,13 +19,13 @@ defmodule Sonata.Combination do for {call, struct} <- structs do def unquote(call)(lhs, rhs) when is_function(rhs) do - unquote(call)(lhs, rhs.()) + %unquote(struct){lhs: lhs, rhs: rhs.()} end def unquote(call)(lhs, rhs) do %unquote(struct){lhs: lhs, rhs: rhs} end def unquote(:"#{call}_all")(lhs, rhs) when is_function(rhs) do - unquote(:"#{call}_all")(lhs, rhs.()) + %unquote(struct){lhs: lhs, rhs: rhs.(), all: true} end def unquote(:"#{call}_all")(lhs, rhs) do %unquote(struct){lhs: lhs, rhs: rhs, all: true} diff --git a/lib/sonata/create_table.ex b/lib/sonata/create_table.ex index 1362c3f..0ef41f1 100644 --- a/lib/sonata/create_table.ex +++ b/lib/sonata/create_table.ex @@ -1,33 +1,137 @@ defmodule Sonata.CreateTable do - use Sonata.Definition + defstruct [table: nil, + add_columns: [], + checks: [], + references: [], + primary_key: nil, + constraints: [], + unique: [], + if_not_exists: nil, + temporary: nil, + unlogged: nil, + inherits: [], + tablespace: nil, + on_commit: nil] def create_table(table) do - %Sonata.CreateTable{table: table} + %__MODULE__{table: table} end def create_table(table, columns) do create_table(table) |> add_column(columns) end + + def add_column(%{add_columns: columns} = d, c) when is_list(c) do + %{d | add_columns: columns ++ c} + end + def add_column(d, c) do + add_column(d, [c]) + end + + def add_column(d, name, type) do + col = Sonata.Builder.Column.column(name, type) + add_column(d, [col]) + end + + def unique(%{unique: unique} = d, u) do + %{d | unique: unique ++ [u]} + end + + def primary_key(d, key) do + %{d | primary_key: key} + end + + def references(%{references: references} = d, r) when is_list(r) do + %{d | references: references ++ r} + end + def references(d, r) do + references(d, [r]) + end + + def if_not_exists(d) do + %{d | if_not_exists: true} + end + + def temporary(d) do + %{d | temporary: true} + end + + def unlogged(d) do + %{d | unlogged: true} + end + + def inherits(%{inherits: inherits} = d, tables) when is_list(tables) do + %{d | inherits: inherits ++ tables} + end + def inherits(d, table) do + inherits(d, [table]) + end + + def tablespace(d, name) do + %{d | tablespace: name} + end + + def on_commit(d, type) when type in [:preserve_rows, :delete_rows, :drop] do + %{d | on_commit: type} + end + + defimpl Sonata.Builder.Constraint do + def constraint(%{constraints: constraints} = d, name, constraint) do + %{d | constraints: constraints ++ [{name, constraint}]} + end + end + + defimpl Sonata.Builder.Check do + def check(%{checks: checks} = d, name, expr) do + check = %Sonata.Definition.Check{ + name: name, + expr: expr, + } + %{d | checks: [check | checks]} + end + end end defimpl Sonata.Postgres, for: Sonata.CreateTable do alias Sonata.Postgres, as: PG alias PG.Utils - def to_sql(%{add_columns: columns, table: table}, opts, idx) do + def to_sql(%{add_columns: columns, table: table} = ct, opts, idx) do opts = Map.put(opts, :params, false) - ## TODO escape the table - sql = ["CREATE TABLE ", table, " ("] - {columns, {params, idx}} = Enum.map_reduce(columns, {[], idx}, fn(column, {acc_params, idx}) -> - {sql, params, idx} = PG.to_sql(column, opts, idx) - {sql, {Stream.concat(acc_params, params), idx}} - end) + {columns, params, idx} = Utils.list_to_sql(columns, opts, idx) + + {checks, checks_params, idx} = checks(ct.checks, opts, idx) - ## TODO handle the other options + { + Utils.join([ + "CREATE TABLE ", + Utils.escape(table), + " (", + Utils.join(Stream.concat([ + columns, + checks, + ]), ", "), + ");" + ], ""), - {[sql, Utils.join(columns, ", "), ");"], params, idx} + Stream.concat([ + params, + checks_params, + ]), + + idx + } + end + + defp checks([], _, idx) do + {[], [], idx} + end + defp checks(checks, opts, idx) do + checks + |> Enum.reverse() + |> Utils.list_to_sql(opts, idx) end def on_row(_, _) do diff --git a/lib/sonata/definition.ex b/lib/sonata/definition.ex deleted file mode 100644 index e6ed9ab..0000000 --- a/lib/sonata/definition.ex +++ /dev/null @@ -1,87 +0,0 @@ -defmodule Sonata.Definition do - defmacro __using__(_) do - quote do - defstruct [table: nil, - add_columns: [], - drop_columns: [], - checks: [], - references: [], - primary_key: nil, - constraints: [], - unique: [], - if_not_exists: nil, - temporary: nil, - unlogged: nil, - inherits: [], - tablespace: nil, - on_commit: nil] - - def add_column(%{add_columns: columns} = d, c) when is_list(c) do - %{d | add_columns: columns ++ c} - end - def add_column(d, c) do - add_column(d, [c]) - end - - def add_column(d, name, type) do - col = Sonata.Definition.Column.column(name, type) - add_column(d, [col]) - end - - def drop_column(%{drop_columns: columns} = d, c) when is_list(c) do - %{d | drop_columns: columns ++ c} - end - def drop_column(d, c) do - drop_column(d, [c]) - end - - def unique(%{unique: unique} = d, u) do - %{d | unique: unique ++ [u]} - end - - def primary_key(d, key) do - %{d | primary_key: key} - end - - def references(%{references: references} = d, r) when is_list(r) do - %{d | references: references ++ r} - end - def references(d, r) do - references(d, [r]) - end - - def if_not_exists(d) do - %{d | if_not_exists: true} - end - - def temporary(d) do - %{d | temporary: true} - end - - def unlogged(d) do - %{d | unlogged: true} - end - - def inherits(%{inherits: inherits} = d, tables) when is_list(tables) do - %{d | inherits: inherits ++ tables} - end - def inherits(d, table) do - inherits(d, [table]) - end - - def tablespace(d, name) do - %{d | tablespace: name} - end - - def on_commit(d, type) when type in [:preserve_rows, :delete_rows, :drop] do - %{d | on_commit: type} - end - - defimpl Sonata.Builder.Constraint do - def constraint(%{constraints: constraints} = d, name, constraint) do - %{d | constraints: constraints ++ [{name, constraint}]} - end - end - end - end -end diff --git a/lib/sonata/definition/check.ex b/lib/sonata/definition/check.ex new file mode 100644 index 0000000..8445a15 --- /dev/null +++ b/lib/sonata/definition/check.ex @@ -0,0 +1,28 @@ +defmodule Sonata.Definition.Check do + defstruct [ + name: nil, + expr: nil, + inherit: true, + ] +end + +defimpl Sonata.Postgres, for: Sonata.Definition.Check do + alias Sonata.Postgres, as: PG + alias PG.Utils + + def to_sql(%{name: name, expr: expr, inherit: inherit}, opts, idx) do + {expr, params, idx} = PG.to_sql(expr, opts, idx) + {[name(name), "CHECK ", expr], params, idx} + end + + defp name(nil) do + "" + end + defp name(name) do + ["CONSTRAINT ", Utils.escape(name), " "] + end + + def on_row(_, _) do + nil + end +end diff --git a/lib/sonata/definition/column.ex b/lib/sonata/definition/column.ex index 768342f..9154e16 100644 --- a/lib/sonata/definition/column.ex +++ b/lib/sonata/definition/column.ex @@ -15,51 +15,12 @@ defmodule Sonata.Definition.Column do deferrable: false, initially: nil,] - defmodule Check do - defstruct [ - name: nil, - expr: nil, - inherit: true, - ] - end + require Sonata.Expr - def column(name, type) do - %__MODULE__{name: name, type: type} - end - - def check(column, name \\ nil, expr) do - merge_check(column, %Check{ - name: name, - expr: expr, - }) - end - - def check_no_inherit(column, name \\ nil, expr) do - merge_check(column, %Check{ - name: name, - expr: expr, - inherit: false, - }) - end - - defp merge_check(%{check: nil} = column, check) do - %{column | check: check} - end - defp merge_check(%{ - check: %{ - expr: e, - name: n, - inherit: i - } - } = column, %{ - inherit: i, - expr: expr, - } = check) do - %{column | check: %Check{ - name: n, - expr: Sonata.Expr.and(e, expr), - inherit: i, - }} + def check_op(%{name: col} = column, name \\ nil, op, rhs) do + col = Sonata.Expr.column(col) + expr = Sonata.Expr.op(col, op, rhs) + Sonata.Builder.Check.check(column, name, expr) end def references(column, table) do @@ -134,11 +95,48 @@ defmodule Sonata.Definition.Column do def initially_immediate(column) do %{column | initially: :immediate} end + + defimpl Sonata.Builder.Check do + alias Sonata.Definition.Check + + def check(column, name, expr) do + merge_check(column, %Check{ + name: name, + expr: expr, + }) + end + + defp merge_check(%{check: nil} = column, check) do + %{column | check: check} + end + defp merge_check(%{ + check: %{ + expr: e, + name: n, + inherit: i + } + } = column, %{ + inherit: i, + expr: expr, + } = check) do + %{column | check: %Check{ + name: n, + expr: Sonata.Expr.and(e, expr), + inherit: i, + }} + end + end +end + +defimpl Sonata.Builder.Column, for: [Atom, Bitstring] do + def column(name, type) do + %Sonata.Definition.Column{name: name, type: type} + end end defimpl Sonata.Postgres, for: Sonata.Definition.Column do alias Sonata.Postgres, as: PG - import PG.Utils + alias PG.Utils def to_sql(column, opts, idx) do {name, name_params, idx} = name(column.name, opts, idx) @@ -152,7 +150,7 @@ defimpl Sonata.Postgres, for: Sonata.Definition.Column do {null, null_params, idx} = null(column.null, opts, idx) { - join([ + Utils.join([ name, type, check, @@ -188,14 +186,15 @@ defimpl Sonata.Postgres, for: Sonata.Definition.Column do {nil, [], idx} end defp name(name, _, idx) do - {to_string(name), [], idx} + {Utils.escape(name), [], idx} end defp type(nil, _, idx) do {nil, [], idx} end defp type(type, _, idx) do - {to_string(type), [], idx} + [type | _] = type |> to_string() |> String.split(" ") + {type, [], idx} end defp check(nil, _, idx) do @@ -252,25 +251,3 @@ defimpl Sonata.Postgres, for: Sonata.Definition.Column do {["DEFAULT ", default], params, idx} end end - -defimpl Sonata.Postgres, for: Sonata.Definition.Column.Check do - alias Sonata.Postgres, as: PG - import PG.Utils - - def to_sql(%{name: name, expr: expr, inherit: inherit}, opts, idx) do - {expr, params, idx} = PG.to_sql(expr, opts, idx) - {[name(name), "CHECK ", expr], params, idx} - end - - defp name(nil) do - "" - end - defp name(name) do - # TODO escape - ["CONSTRAINT ", name, " "] - end - - def on_row(_, _) do - nil - end -end diff --git a/lib/sonata/drop_table.ex b/lib/sonata/drop_table.ex new file mode 100644 index 0000000..a8614f3 --- /dev/null +++ b/lib/sonata/drop_table.ex @@ -0,0 +1,24 @@ +defmodule Sonata.DropTable do + defstruct [table: nil] + + def drop_table(table) do + %__MODULE__{table: table} + end +end + +defimpl Sonata.Postgres, for: Sonata.DropTable do + alias Sonata.Postgres, as: PG + alias PG.Utils + + def to_sql(%{table: table}, opts, idx) do + { + ["DROP TABLE", Utils.escape(table), ";"], + [], + idx + } + end + + def on_row(_, _) do + nil + end +end diff --git a/lib/sonata/expr.ex b/lib/sonata/expr.ex index 7336861..71ffe19 100644 --- a/lib/sonata/expr.ex +++ b/lib/sonata/expr.ex @@ -23,7 +23,18 @@ defmodule Sonata.Expr do %__MODULE__.Value{value: value} end + defmacro op(lhs, name, rhs) when is_atom(name) do + quote do + Sonata.Operator.unquote(name)(unquote(lhs), unquote(rhs)) + end + end defmacro op(lhs, name, rhs) do + quote do + apply(Sonata.Operator, unquote(name), [unquote(lhs), unquote(rhs)]) + end + end + + defmacro op({name, _, [lhs, rhs]}) when is_atom(name) do quote do Sonata.Operator.unquote(name)(unquote(lhs), unquote(rhs)) end diff --git a/lib/sonata/expr/call.ex b/lib/sonata/expr/call.ex index 79ddd2b..489405b 100644 --- a/lib/sonata/expr/call.ex +++ b/lib/sonata/expr/call.ex @@ -3,13 +3,12 @@ defmodule Sonata.Expr.Call do end defimpl Sonata.Postgres, for: Sonata.Expr.Call do + alias Sonata.Postgres.Utils + def to_sql(%{name: fun, arguments: arguments}, opts, idx) do - {arguments, {params, idx}} = Enum.map_reduce(arguments, {[], idx}, fn(arg, {params, idx}) -> - {arg, p, idx} = Sonata.Postgres.to_sql(arg, opts, idx) - {arg, {Stream.concat(params, p), idx}} - end) + {arguments, params, idx} = Utils.list_to_sql(arguments, opts, idx) - {[to_string(fun), "(", Sonata.Postgres.Utils.join(arguments, ", "), ")"], params, idx} + {[Utils.escape(fun), "(", Utils.join(arguments, ", "), ")"], params, idx} end def on_row(_, _) do diff --git a/lib/sonata/expr/reference.ex b/lib/sonata/expr/reference.ex index c9cb705..0a1c731 100644 --- a/lib/sonata/expr/reference.ex +++ b/lib/sonata/expr/reference.ex @@ -3,9 +3,10 @@ defmodule Sonata.Expr.Reference do end defimpl Sonata.Postgres, for: Sonata.Expr.Reference do + alias Sonata.Postgres.Utils + def to_sql(%{name: name}, _, idx) do - # TODO escape the reference name - {to_string(name), [], idx} + {Utils.escape(name), [], idx} end def on_row(_, _) do diff --git a/lib/sonata/expr/unary_operator.ex b/lib/sonata/expr/unary_operator.ex index d3dfe98..8b203a7 100644 --- a/lib/sonata/expr/unary_operator.ex +++ b/lib/sonata/expr/unary_operator.ex @@ -1,3 +1,16 @@ defmodule Sonata.Expr.UnaryOperator do defstruct [:operator, :rhs] end + +defimpl Sonata.Postgres, for: Sonata.Expr.UnaryOperator do + alias Sonata.Postgres, as: PG + + def to_sql(%{operator: operator, rhs: rhs}, opts, idx) do + {rhs, rhs_params, idx} = PG.to_sql(rhs, opts, idx) + {["(", operator, " ", rhs, ")"], rhs_params, idx} + end + + def on_row(_, _) do + nil + end +end diff --git a/lib/sonata/manipulation/insertion.ex b/lib/sonata/manipulation/insertion.ex index fbe523a..675a326 100644 --- a/lib/sonata/manipulation/insertion.ex +++ b/lib/sonata/manipulation/insertion.ex @@ -8,7 +8,7 @@ end defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do alias Sonata.Postgres, as: PG - import PG.Utils + alias PG.Utils def to_sql(insertion, opts, idx) do {table, table_params, idx} = table(insertion.table, opts, idx) @@ -17,7 +17,7 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do {rows, rows_params, idx} = rows(insertion.rows, opts, idx) { - join([ + Utils.join([ "INSERT INTO", table, fields, @@ -40,7 +40,7 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do {nil, [], idx} end defp table(table, opts, idx) when is_binary(table) do - {escape_keyword(table), opts, idx} + {Utils.escape(table), opts, idx} end def fields(fields, _, idx) when fields in [nil, false, ""] do diff --git a/lib/sonata/manipulation/update.ex b/lib/sonata/manipulation/update.ex index adc4723..385bbc0 100644 --- a/lib/sonata/manipulation/update.ex +++ b/lib/sonata/manipulation/update.ex @@ -8,7 +8,7 @@ end defimpl Sonata.Postgres, for: Sonata.Manipulation.Update do alias Sonata.Postgres, as: PG - import PG.Utils + alias PG.Utils def to_sql(update, opts, idx) do {table, table_params, idx} = table(update.table, opts, idx) @@ -18,7 +18,7 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Update do {returning, returning_params, idx} = returning(update.returning, opts, idx) { - join([ + Utils.join([ "UPDATE", table, table_alias, @@ -47,14 +47,14 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Update do {nil, [], idx} end defp table(table, opts, idx) when is_binary(table) do - {escape_keyword(table), opts, idx} + {Utils.escape(table), opts, idx} end defp table_alias(nil, _, idx) do {nil, [], idx} end defp table_alias(alias, opts, idx) do - {[" AS ", escape_keyword(alias)], opts, idx} + {[" AS ", Utils.escape(alias)], opts, idx} end defp sets(sets, _, idx) when sets in [nil, false, "", []] do diff --git a/lib/sonata/postgres.ex b/lib/sonata/postgres.ex index 68651c9..001f8d0 100644 --- a/lib/sonata/postgres.ex +++ b/lib/sonata/postgres.ex @@ -4,24 +4,36 @@ defprotocol Sonata.Postgres do end defimpl Sonata.Postgres, for: [Integer, Float, Atom, BitString] do - def to_sql(value, opts, idx) when is_atom(value) and not value in [true, false] do - value - |> Atom.to_string() - |> to_sql(opts, idx) - end def to_sql(value, %{params: false}, idx) do {escape(value), [], idx} end + def to_sql(value, _opts, idx) when is_atom(value) and not value in [true, false, nil] do + {escape(value), [], idx} + end def to_sql(value, _opts, idx) do {"$#{idx}", [value], idx + 1} end + defp escape(true) do + "TRUE" + end + defp escape(false) do + "FALSE" + end + defp escape(nil) do + "NULL" + end defp escape(value) when is_number(value) do to_string(value) end defp escape(value) when is_binary(value) do "'" <> String.replace(value, "'", "''") <> "'" end + defp escape(value) when is_atom(value) do + value + |> Atom.to_string() + |> Sonata.Postgres.Utils.escape() + end def on_row(_, _) do nil diff --git a/lib/sonata/postgres/utils.ex b/lib/sonata/postgres/utils.ex index ec71723..a114d9d 100644 --- a/lib/sonata/postgres/utils.ex +++ b/lib/sonata/postgres/utils.ex @@ -1,5 +1,6 @@ defmodule Sonata.Postgres.Utils do - import Kernel + alias Sonata.Postgres, as: PG + def columns([], _, idx) do {"*", [], idx} end @@ -12,17 +13,17 @@ defmodule Sonata.Postgres.Utils do end def column(column, _, idx) when is_binary(column) do - {escape_keyword(column), [], idx} + {escape(column), [], idx} end def column(column, _, idx) when is_atom(column) do - {escape_keyword(Atom.to_string(column)), [], idx} + {escape(Atom.to_string(column)), [], idx} end def column({column, alias}, opts, idx) do {column, params, idx} = column(column, opts, idx) - {[column, " AS ", escape_keyword(alias)], params, idx} + {[column, " AS ", escape(alias)], params, idx} end def column(column, opts, idx) do - Sonata.Postgres.to_sql(column, opts, idx) + PG.to_sql(column, opts, idx) end def pop_comma({columns, params, idx}) do @@ -49,8 +50,26 @@ defmodule Sonata.Postgres.Utils do [item, delim, rest] end end + def join(stream, delim) do + stream + |> Enum.to_list() + |> join(delim) + end + + def list_to_sql(list, opts, idx) do + {sql, {params, idx}} = Enum.map_reduce(list, {[], idx}, fn(item, {acc_params, idx}) -> + {sql, params, idx} = PG.to_sql(item, opts, idx) + {sql, {Stream.concat(acc_params, params), idx}} + end) + {sql, params, idx} + end - def escape_keyword(value) do - to_string(value) + def escape(value) when is_binary(value) do + "\"" <> String.replace(value, "\"", "\"\"") <> "\"" + end + def escape(value) when is_atom(value) do + value + |> Atom.to_string() + |> escape() end end diff --git a/lib/sonata/query.ex b/lib/sonata/query.ex index e45cf1f..481fbad 100644 --- a/lib/sonata/query.ex +++ b/lib/sonata/query.ex @@ -11,13 +11,19 @@ defmodule Sonata.Query do offset: nil, struct: nil] + alias Sonata.Builder.Column + def select() do %__MODULE__{} end def select(columns) do select() - |> column(columns) + |> Column.column(columns) + end + + def column(q, c, alias) do + Column.column(q, [{c, alias}]) end def distinct(q) do @@ -33,21 +39,11 @@ defmodule Sonata.Query do distinct(q, [d]) end - def column(%{columns: columns} = q, c) when is_list(c) do - %{q | columns: columns ++ c} - end - def column(q, c) do - column(q, [c]) - end - def column(q, c, alias) do - column(q, [{c, alias}]) - end - def value(q, value, as \\ nil) do value = %__MODULE__.Value{value: value} cond do is_nil(as) -> - column(q, value) + Column.column(q, value) true -> column(q, value, as) end @@ -124,15 +120,24 @@ defmodule Sonata.Query do def into_struct(q, struct) do %{q | struct: struct} end + + defimpl Column do + def column(%{columns: columns} = q, c) when is_list(c) do + %{q | columns: columns ++ c} + end + def column(q, c) do + column(q, [c]) + end + end end defimpl Sonata.Postgres, for: Sonata.Query do alias Sonata.Postgres, as: PG - import PG.Utils + alias PG.Utils def to_sql(query, opts, idx) do {distinct, distinct_params, idx} = distinct(query.distinct, opts, idx) - {columns, column_params, idx} = columns(query.columns, opts, idx) + {columns, column_params, idx} = Utils.columns(query.columns, opts, idx) {from, from_params, idx} = from(query.from, opts, idx) {where, where_params, idx} = where(query.where, opts, idx) {group_by, group_by_params, idx} = group_by(query.group_by, opts, idx) @@ -142,7 +147,7 @@ defimpl Sonata.Postgres, for: Sonata.Query do {offset, offset_params, idx} = offset(query.offset, opts, idx) { - join([ + Utils.join([ "SELECT", distinct, columns, @@ -185,7 +190,7 @@ defimpl Sonata.Postgres, for: Sonata.Query do {"DISTINCT", [], idx} end defp distinct(distinct, opts, idx) when is_list(distinct) do - {columns, params, idx} = columns(distinct, opts, idx) + {columns, params, idx} = Utils.columns(distinct, opts, idx) {["DISTINCT ON (", columns, ")"], params, idx} end @@ -193,7 +198,7 @@ defimpl Sonata.Postgres, for: Sonata.Query do {nil, [], idx} end defp from(from, _, idx) when is_binary(from) do - {["FROM ", escape_keyword(from)], [], idx} + {["FROM ", Utils.escape(from)], [], idx} end defp from({from, alias}, opts, idx) do {from, params, idx} = from(from, opts, idx) @@ -216,7 +221,7 @@ defimpl Sonata.Postgres, for: Sonata.Query do {nil, [], idx} end defp group_by(columns, opts, idx) do - {columns, params} = columns(columns, opts, idx) + {columns, params} = Utils.columns(columns, opts, idx) {["GROUP BY ", columns], params, idx} end @@ -232,7 +237,7 @@ defimpl Sonata.Postgres, for: Sonata.Query do {nil, [], idx} end defp order_by(columns, opts, idx) do - {columns, params, idx} = columns(columns, opts, idx) + {columns, params, idx} = Utils.columns(columns, opts, idx) {["ORDER BY ", columns], params, idx} end diff --git a/test/create_table_test.exs b/test/create_table_test.exs index 94d82c7..a9a66dc 100644 --- a/test/create_table_test.exs +++ b/test/create_table_test.exs @@ -3,25 +3,25 @@ defmodule Test.Sonata.CreateTable do test "my_first_table" do create_table("my_first_table") - |> add_column("first_column", "text") - |> add_column("second_column", "integer") + |> add_column(:first_column, "text") + |> add_column(:second_column, "integer") |> assert_sql(table_info("my_first_table")) end test "products" do create_table("products") - |> add_column("product_no", "integer") - |> add_column("name", "text") - |> add_column("price", "numeric") + |> add_column(:product_no, "integer") + |> add_column(:name, "text") + |> add_column(:price, "numeric") |> assert_sql(table_info("products")) end test "default products" do create_table("products") |> add_column([ - column("product_no", "integer"), - column("name", "text"), - column("price", "numeric") + column(:product_no, "integer"), + column(:name, "text"), + column(:price, "numeric") |> default(9.99), ]) |> assert_sql(table_info("products")) @@ -30,7 +30,7 @@ defmodule Test.Sonata.CreateTable do test "default product no" do create_table("products") |> add_column([ - column("product_no", "integer") + column(:product_no, "integer") |> default(random()), ]) |> assert_sql(table_info("products")) @@ -39,7 +39,7 @@ defmodule Test.Sonata.CreateTable do test "products SERIAL" do create_table("products") |> add_column([ - column("product_no", "SERIAL") + column(:product_no, "SERIAL") ]) |> assert_sql(table_info("products")) end @@ -47,11 +47,11 @@ defmodule Test.Sonata.CreateTable do test "products CHECK price > 0" do create_table("products") |> add_column([ - column("product_no", "integer"), - column("name", "text"), - column("price", "numeric") + column(:product_no, "integer"), + column(:name, "text"), + column(:price, "numeric") |> check( - op(column("price"), :>, 0) + op(:price > 0) ), ]) |> assert_sql_error(""" @@ -63,12 +63,12 @@ defmodule Test.Sonata.CreateTable do test "products named CHECK" do create_table("products") |> add_column([ - column("product_no", "integer"), - column("name", "text"), - column("price", "numeric") + column(:product_no, "integer"), + column(:name, "text"), + column(:price, "numeric") |> check( "positive_price", - op(column("price"), :>, 0) + op(:price > 0) ), ]) |> assert_sql_error(""" @@ -77,6 +77,41 @@ defmodule Test.Sonata.CreateTable do """) end + test "products CHECK operator" do + create_table("products") + |> add_column([ + column(:product_no, "integer"), + column(:name, "text"), + column(:price, "numeric") + |> check_op(:>, 0), + ]) + |> assert_sql_error(""" + INSERT INTO products VALUES + (1, 'My product', -1); + """) + end + + test "table-wide checks" do + create_table("products") + |> add_column([ + column(:product_no, "integer"), + column(:name, "text"), + column(:price, "numeric"), + column(:discounted_price, "numeric"), + ]) + |> check( + op(:price > :discounted_price) + ) + |> check( + "min_discount", + op(:discounted_price > 0) + ) + |> assert_sql_error(""" + INSERT INTO products VALUES + (1, 'My product', 100, 400); + """) + end + defp table_info(name) do """ SELECT From 91a7b8749c1cf278a4c6514995e97c90fb936da7 Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Thu, 27 Jul 2017 11:21:04 -0600 Subject: [PATCH 11/43] add primary key tests --- _snapshots/Test.Sonata.CreateTable.snapshot | 35 +++++++++ lib/sonata/create_table.ex | 29 ++++++- lib/sonata/postgres/utils.ex | 4 +- test/create_table_test.exs | 87 +++++++++++++++++++-- test/test_helper.exs | 10 ++- 5 files changed, 155 insertions(+), 10 deletions(-) diff --git a/_snapshots/Test.Sonata.CreateTable.snapshot b/_snapshots/Test.Sonata.CreateTable.snapshot index 0dab39b..749f7d3 100644 --- a/_snapshots/Test.Sonata.CreateTable.snapshot +++ b/_snapshots/Test.Sonata.CreateTable.snapshot @@ -7,6 +7,27 @@ "test my_first_table": [%{"column_name" => "first_column", "data_type" => "text"}, %{"column_name" => "second_column", "data_type" => "integer"}], + "test not null": %Postgrex.Error{connection_id: nil, message: nil, + postgres: %{code: :not_null_violation, column: "product_no", + detail: "Failing row contains (null, null, null).", file: "execMain.c", + line: "1734", + message: "null value in column \"product_no\" violates not-null constraint", + pg_code: "23502", routine: "ExecConstraints", schema: "public", + severity: "ERROR", table: "products", unknown: "ERROR"}}, + "test primary key": %Postgrex.Error{connection_id: nil, message: nil, + postgres: %{code: :unique_violation, constraint: "products_pkey", + detail: "Key (product_no)=(1) already exists.", file: "nbtinsert.c", + line: "433", + message: "duplicate key value violates unique constraint \"products_pkey\"", + pg_code: "23505", routine: "_bt_check_unique", schema: "public", + severity: "ERROR", table: "products", unknown: "ERROR"}}, + "test primary key multiple": %Postgrex.Error{connection_id: nil, message: nil, + postgres: %{code: :unique_violation, constraint: "products_pkey", + detail: "Key (a, b)=(1, 2) already exists.", file: "nbtinsert.c", + line: "433", + message: "duplicate key value violates unique constraint \"products_pkey\"", + pg_code: "23505", routine: "_bt_check_unique", schema: "public", + severity: "ERROR", table: "products", unknown: "ERROR"}}, "test products": [%{"column_name" => "product_no", "data_type" => "integer"}, %{"column_name" => "name", "data_type" => "text"}, %{"column_name" => "price", "data_type" => "numeric"}], @@ -41,4 +62,18 @@ file: "execMain.c", line: "1760", message: "new row for relation \"products\" violates check constraint \"products_check\"", pg_code: "23514", routine: "ExecConstraints", schema: "public", + severity: "ERROR", table: "products", unknown: "ERROR"}}, + "test unique": %Postgrex.Error{connection_id: nil, message: nil, + postgres: %{code: :unique_violation, constraint: "products_product_no_key", + detail: "Key (product_no)=(1) already exists.", file: "nbtinsert.c", + line: "433", + message: "duplicate key value violates unique constraint \"products_product_no_key\"", + pg_code: "23505", routine: "_bt_check_unique", schema: "public", + severity: "ERROR", table: "products", unknown: "ERROR"}}, + "test unique multiple": %Postgrex.Error{connection_id: nil, message: nil, + postgres: %{code: :unique_violation, constraint: "products_a_b_key", + detail: "Key (a, b)=(1, 2) already exists.", file: "nbtinsert.c", + line: "433", + message: "duplicate key value violates unique constraint \"products_a_b_key\"", + pg_code: "23505", routine: "_bt_check_unique", schema: "public", severity: "ERROR", table: "products", unknown: "ERROR"}}} \ No newline at end of file diff --git a/lib/sonata/create_table.ex b/lib/sonata/create_table.ex index 0ef41f1..741fb6f 100644 --- a/lib/sonata/create_table.ex +++ b/lib/sonata/create_table.ex @@ -34,10 +34,16 @@ defmodule Sonata.CreateTable do add_column(d, [col]) end + def unique(d, u) when is_list(u) do + unique(d, Sonata.Expr.column_list(u)) + end def unique(%{unique: unique} = d, u) do - %{d | unique: unique ++ [u]} + %{d | unique: [u | unique]} end + def primary_key(d, u) when is_list(u) do + primary_key(d, Sonata.Expr.column_list(u)) + end def primary_key(d, key) do %{d | primary_key: key} end @@ -103,6 +109,8 @@ defimpl Sonata.Postgres, for: Sonata.CreateTable do {columns, params, idx} = Utils.list_to_sql(columns, opts, idx) {checks, checks_params, idx} = checks(ct.checks, opts, idx) + {primary_key, primary_key_params, idx} = primary_key(ct.primary_key, opts, idx) + {unique, unique_params, idx} = unique(ct.unique, opts, idx) { Utils.join([ @@ -112,6 +120,8 @@ defimpl Sonata.Postgres, for: Sonata.CreateTable do Utils.join(Stream.concat([ columns, checks, + primary_key, + unique, ]), ", "), ");" ], ""), @@ -119,6 +129,8 @@ defimpl Sonata.Postgres, for: Sonata.CreateTable do Stream.concat([ params, checks_params, + primary_key_params, + unique_params, ]), idx @@ -134,6 +146,21 @@ defimpl Sonata.Postgres, for: Sonata.CreateTable do |> Utils.list_to_sql(opts, idx) end + defp primary_key(nil, _, idx) do + {[], [], idx} + end + defp primary_key(primary_key, opts, idx) do + {sql, params, idx} = PG.to_sql(primary_key, opts, idx) + {[["PRIMARY KEY ", sql]], params, idx} + end + + defp unique([], _, idx) do + {[], [], idx} + end + defp unique(unique, opts, idx) do + Utils.list_to_sql(unique, opts, idx, &(["UNIQUE ", &1])) + end + def on_row(_, _) do nil end diff --git a/lib/sonata/postgres/utils.ex b/lib/sonata/postgres/utils.ex index a114d9d..83767cf 100644 --- a/lib/sonata/postgres/utils.ex +++ b/lib/sonata/postgres/utils.ex @@ -56,10 +56,10 @@ defmodule Sonata.Postgres.Utils do |> join(delim) end - def list_to_sql(list, opts, idx) do + def list_to_sql(list, opts, idx, mapper \\ &(&1)) do {sql, {params, idx}} = Enum.map_reduce(list, {[], idx}, fn(item, {acc_params, idx}) -> {sql, params, idx} = PG.to_sql(item, opts, idx) - {sql, {Stream.concat(acc_params, params), idx}} + {mapper.(sql), {Stream.concat(acc_params, params), idx}} end) {sql, params, idx} end diff --git a/test/create_table_test.exs b/test/create_table_test.exs index a9a66dc..c48f74b 100644 --- a/test/create_table_test.exs +++ b/test/create_table_test.exs @@ -9,11 +9,11 @@ defmodule Test.Sonata.CreateTable do end test "products" do - create_table("products") + create_table("pro\\ducts") |> add_column(:product_no, "integer") |> add_column(:name, "text") |> add_column(:price, "numeric") - |> assert_sql(table_info("products")) + |> assert_sql(table_info("pro\\ducts")) end test "default products" do @@ -57,7 +57,7 @@ defmodule Test.Sonata.CreateTable do |> assert_sql_error(""" INSERT INTO products VALUES (1, 'My product', -1); - """) + """, :check_violation) end test "products named CHECK" do @@ -74,7 +74,7 @@ defmodule Test.Sonata.CreateTable do |> assert_sql_error(""" INSERT INTO products VALUES (1, 'My product', -1); - """) + """, :check_violation) end test "products CHECK operator" do @@ -88,7 +88,7 @@ defmodule Test.Sonata.CreateTable do |> assert_sql_error(""" INSERT INTO products VALUES (1, 'My product', -1); - """) + """, :check_violation) end test "table-wide checks" do @@ -109,7 +109,82 @@ defmodule Test.Sonata.CreateTable do |> assert_sql_error(""" INSERT INTO products VALUES (1, 'My product', 100, 400); - """) + """, :check_violation) + end + + test "not null" do + create_table("products") + |> add_column([ + column(:product_no, "integer") + |> not_null(), + column(:name, "text") + |> not_null(), + column(:price, "numeric") + |> not_null() + |> check_op(:>, 0) + ]) + |> assert_sql_error(""" + INSERT INTO products VALUES + (NULL, NULL, NULL); + """, :not_null_violation) + end + + test "unique" do + create_table("products") + |> add_column([ + column(:product_no, "integer") + |> unique(), + column(:name, "text"), + column(:price, "numeric"), + ]) + |> assert_sql_error(""" + INSERT INTO products VALUES + (1, 'First', 2), + (1, 'Second', 2); + """, :unique_violation) + end + + test "unique multiple" do + create_table("products") + |> add_column([ + column(:a, "integer"), + column(:b, "integer"), + ]) + |> unique([:a, :b]) + |> assert_sql_error(""" + INSERT INTO products VALUES + (1, 2), + (1, 2); + """, :unique_violation) + end + + test "primary key" do + create_table("products") + |> add_column([ + column(:product_no, "integer") + |> primary_key(), + column(:name, "text"), + column(:price, "numeric"), + ]) + |> assert_sql_error(""" + INSERT INTO products VALUES + (1, 'First', 1), + (1, 'Second', 2); + """, :unique_violation) + end + + test "primary key multiple" do + create_table("products") + |> add_column([ + column(:a, "integer"), + column(:b, "integer"), + ]) + |> primary_key([:a, :b]) + |> assert_sql_error(""" + INSERT INTO products VALUES + (1, 2), + (1, 2); + """, :unique_violation) end defp table_info(name) do diff --git a/test/test_helper.exs b/test/test_helper.exs index c06c6ef..181e878 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -74,6 +74,8 @@ defmodule Test.Sonata do {sql, params, _on_row} = Sonata.to_sql(unquote(struct)) sql = :erlang.iolist_to_binary(sql) + # IO.puts sql + Ecto.Adapters.SQL.query!(Repo, sql, params) result = Ecto.Adapters.SQL.query!(Repo, unquote(command)) @@ -83,17 +85,21 @@ defmodule Test.Sonata do end end - defmacro assert_sql_error(struct, command) do + defmacro assert_sql_error(struct, command, code) do quote do {sql, params, _on_row} = Sonata.to_sql(unquote(struct)) sql = :erlang.iolist_to_binary(sql) + # IO.puts sql + Ecto.Adapters.SQL.query!(Repo, sql, params) error = assert_raise Postgrex.Error, fn -> Ecto.Adapters.SQL.query!(Repo, unquote(command)) end + assert error.postgres.code == unquote(code) + error = Map.merge(error, %{ connection_id: nil }) @@ -107,6 +113,8 @@ defmodule Test.Sonata do {sql, params, on_row} = Sonata.to_sql(unquote(struct)) sql = :erlang.iolist_to_binary(sql) + # IO.puts sql + result = Ecto.Adapters.SQL.query!(Repo, sql, params) |> postgrex_result() |> Enum.map(on_row) From 30a0f874e165cf9e41548518a7f7ed86db9aeca6 Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Thu, 27 Jul 2017 12:37:12 -0600 Subject: [PATCH 12/43] implement foreign keys --- _snapshots/Test.Sonata.CreateTable.snapshot | 31 +++++++ lib/sonata.ex | 3 +- lib/sonata/create_table.ex | 24 ++++-- lib/sonata/definition/column.ex | 27 ++++-- lib/sonata/definition/foreign_key.ex | 45 ++++++++++ lib/sonata/transaction.ex | 35 ++++++++ test/create_table_test.exs | 94 ++++++++++++++++++--- test/test_helper.exs | 38 ++++----- 8 files changed, 249 insertions(+), 48 deletions(-) create mode 100644 lib/sonata/definition/foreign_key.ex create mode 100644 lib/sonata/transaction.ex diff --git a/_snapshots/Test.Sonata.CreateTable.snapshot b/_snapshots/Test.Sonata.CreateTable.snapshot index 749f7d3..4e49281 100644 --- a/_snapshots/Test.Sonata.CreateTable.snapshot +++ b/_snapshots/Test.Sonata.CreateTable.snapshot @@ -4,6 +4,13 @@ "data_type" => "integer"}, %{"column_name" => "name", "data_type" => "text"}, %{"column_name" => "price", "data_type" => "numeric"}], + "test foreign key": %Postgrex.Error{connection_id: nil, message: nil, + postgres: %{code: :foreign_key_violation, constraint: "t1_a_fkey", + detail: "Key (a, b)=(1, 1) is not present in table \"other_table\".", + file: "ri_triggers.c", line: "3324", + message: "insert or update on table \"t1\" violates foreign key constraint \"t1_a_fkey\"", + pg_code: "23503", routine: "ri_ReportViolation", schema: "public", + severity: "ERROR", table: "t1", unknown: "ERROR"}}, "test my_first_table": [%{"column_name" => "first_column", "data_type" => "text"}, %{"column_name" => "second_column", "data_type" => "integer"}], @@ -56,6 +63,30 @@ message: "new row for relation \"products\" violates check constraint \"positive_price\"", pg_code: "23514", routine: "ExecConstraints", schema: "public", severity: "ERROR", table: "products", unknown: "ERROR"}}, + "test references": %Postgrex.Error{connection_id: nil, message: nil, + postgres: %{code: :foreign_key_violation, + constraint: "orders_product_no_fkey", + detail: "Key (product_no)=(1) is not present in table \"products\".", + file: "ri_triggers.c", line: "3324", + message: "insert or update on table \"orders\" violates foreign key constraint \"orders_product_no_fkey\"", + pg_code: "23503", routine: "ri_ReportViolation", schema: "public", + severity: "ERROR", table: "orders", unknown: "ERROR"}}, + "test references explicit": %Postgrex.Error{connection_id: nil, message: nil, + postgres: %{code: :foreign_key_violation, + constraint: "orders_product_no_fkey", + detail: "Key (product_no)=(1) is not present in table \"products\".", + file: "ri_triggers.c", line: "3324", + message: "insert or update on table \"orders\" violates foreign key constraint \"orders_product_no_fkey\"", + pg_code: "23503", routine: "ri_ReportViolation", schema: "public", + severity: "ERROR", table: "orders", unknown: "ERROR"}}, + "test references pk": %Postgrex.Error{connection_id: nil, message: nil, + postgres: %{code: :foreign_key_violation, + constraint: "orders_product_no_fkey", + detail: "Key (product_no)=(1) is not present in table \"products\".", + file: "ri_triggers.c", line: "3324", + message: "insert or update on table \"orders\" violates foreign key constraint \"orders_product_no_fkey\"", + pg_code: "23503", routine: "ri_ReportViolation", schema: "public", + severity: "ERROR", table: "orders", unknown: "ERROR"}}, "test table-wide checks": %Postgrex.Error{connection_id: nil, message: nil, postgres: %{code: :check_violation, constraint: "products_check", detail: "Failing row contains (1, My product, 100, 400).", diff --git a/lib/sonata.ex b/lib/sonata.ex index 3d43278..97970de 100644 --- a/lib/sonata.ex +++ b/lib/sonata.ex @@ -12,7 +12,8 @@ defmodule Sonata do Function, Manipulation, OrderBy, - Query + Query, + Transaction, } end end diff --git a/lib/sonata/create_table.ex b/lib/sonata/create_table.ex index 741fb6f..f090343 100644 --- a/lib/sonata/create_table.ex +++ b/lib/sonata/create_table.ex @@ -2,7 +2,7 @@ defmodule Sonata.CreateTable do defstruct [table: nil, add_columns: [], checks: [], - references: [], + foreign_keys: [], primary_key: nil, constraints: [], unique: [], @@ -48,11 +48,13 @@ defmodule Sonata.CreateTable do %{d | primary_key: key} end - def references(%{references: references} = d, r) when is_list(r) do - %{d | references: references ++ r} - end - def references(d, r) do - references(d, [r]) + def foreign_key(%{foreign_keys: foreign_keys} = d, cols, table, table_cols) do + fk = Sonata.Definition.ForeignKey.new( + cols, + table, + table_cols + ) + %{d | foreign_keys: [fk | foreign_keys]} end def if_not_exists(d) do @@ -110,6 +112,7 @@ defimpl Sonata.Postgres, for: Sonata.CreateTable do {checks, checks_params, idx} = checks(ct.checks, opts, idx) {primary_key, primary_key_params, idx} = primary_key(ct.primary_key, opts, idx) + {foreign_keys, foreign_keys_params, idx} = foreign_keys(ct.foreign_keys, opts, idx) {unique, unique_params, idx} = unique(ct.unique, opts, idx) { @@ -121,6 +124,7 @@ defimpl Sonata.Postgres, for: Sonata.CreateTable do columns, checks, primary_key, + foreign_keys, unique, ]), ", "), ");" @@ -130,6 +134,7 @@ defimpl Sonata.Postgres, for: Sonata.CreateTable do params, checks_params, primary_key_params, + foreign_keys_params, unique_params, ]), @@ -154,6 +159,13 @@ defimpl Sonata.Postgres, for: Sonata.CreateTable do {[["PRIMARY KEY ", sql]], params, idx} end + defp foreign_keys([], _, idx) do + {[], [], idx} + end + defp foreign_keys(foreign_keys, opts, idx) do + Utils.list_to_sql(foreign_keys, opts, idx) + end + defp unique([], _, idx) do {[], [], idx} end diff --git a/lib/sonata/definition/column.ex b/lib/sonata/definition/column.ex index 9154e16..1c6fcec 100644 --- a/lib/sonata/definition/column.ex +++ b/lib/sonata/definition/column.ex @@ -23,14 +23,24 @@ defmodule Sonata.Definition.Column do Sonata.Builder.Check.check(column, name, expr) end - def references(column, table) do - %{column | reference: table} - end - def primary_key(column) do %{column | primary_key: true} end + def references(column, table, columns \\ nil) + def references(column, table, columns) when is_list(columns) do + columns = Sonata.Expr.column_list(columns) + references(column, table, columns) + end + def references(column, table, col) + when is_atom(col) and not is_nil(col) + or is_binary(col) do + references(column, table, [col]) + end + def references(column, table, columns) do + %{column | reference: {table, columns}} + end + def constraint(column, name, expr) do %{column | constraint: {name, expr}} end @@ -207,11 +217,12 @@ defimpl Sonata.Postgres, for: Sonata.Definition.Column do defp reference(nil, _, idx) do {nil, [], idx} end - defp reference({column, table}, _, idx) do - {["REFERENCES ", to_string(table), " (", to_string(column), ")"], [], idx} + defp reference({table, nil}, _, idx) do + {["REFERENCES ", Utils.escape(table)], [], idx} end - defp reference(table, _, idx) when is_binary(table) or is_atom(table) do - {["REFERENCES ", to_string(table)], [], idx} + defp reference({table, columns}, opts, idx) do + {columns, params, idx} = PG.to_sql(columns, opts, idx) + {["REFERENCES ", Utils.escape(table), " ", columns], params, idx} end defp primary_key(true, _, idx) do diff --git a/lib/sonata/definition/foreign_key.ex b/lib/sonata/definition/foreign_key.ex new file mode 100644 index 0000000..b952d5e --- /dev/null +++ b/lib/sonata/definition/foreign_key.ex @@ -0,0 +1,45 @@ +defmodule Sonata.Definition.ForeignKey do + defstruct [:columns, + :table, + :table_columns] + + alias Sonata.Expr + + def new(cols, table, table_cols) when length(cols) == length(table_cols) do + %__MODULE__{ + columns: Expr.column_list(cols), + table: table, + table_columns: Expr.column_list(table_cols), + } + end + def new(col, table, table_col) + when is_atom(col) or is_binary(col) + and is_atom(table_col) or is_binary(table_col) do + new([col], table, [table_col]) + end +end + +defimpl Sonata.Postgres, for: Sonata.Definition.ForeignKey do + alias Sonata.Postgres, as: PG + alias PG.Utils + + def to_sql(%{columns: cols, table: t, table_columns: tc}, opts, idx) do + {cols, cols_params, idx} = PG.to_sql(cols, opts, idx) + {tc, tc_params, idx} = PG.to_sql(tc, opts, idx) + { + Utils.join([ + "FOREIGN KEY", + cols, + "REFERENCES", + Utils.escape(t), + tc + ], " "), + Stream.concat(cols_params, tc_params), + idx + } + end + + def on_row(_, _) do + nil + end +end diff --git a/lib/sonata/transaction.ex b/lib/sonata/transaction.ex new file mode 100644 index 0000000..0baeb4b --- /dev/null +++ b/lib/sonata/transaction.ex @@ -0,0 +1,35 @@ +defmodule Sonata.Transaction do + defstruct [statements: [], + mode: nil] + + def start_transaction(statements \\ []) do + %__MODULE__{statements: statements} + end + + def begin_transaction(statements \\ []) do + %__MODULE__{statements: statements} + end +end + +defimpl Sonata.Postgres, for: Sonata.Transaction do + alias Sonata.Postgres, as: PG + alias PG.Utils + + def to_sql(%{statements: statements}, opts, idx) do + {statements, params, idx} = Utils.list_to_sql(statements, opts, idx) + { + [ + "BEGIN TRANSACTION; ", + Utils.join(statements, " "), + " END TRANSACTION;" + ], + params, + idx + } + end + + def on_row(_, _) do + # TODO + nil + end +end diff --git a/test/create_table_test.exs b/test/create_table_test.exs index c48f74b..f197fd5 100644 --- a/test/create_table_test.exs +++ b/test/create_table_test.exs @@ -2,14 +2,14 @@ defmodule Test.Sonata.CreateTable do use Test.Sonata test "my_first_table" do - create_table("my_first_table") + create_table(:my_first_table) |> add_column(:first_column, "text") |> add_column(:second_column, "integer") |> assert_sql(table_info("my_first_table")) end test "products" do - create_table("pro\\ducts") + create_table(:"pro\\ducts") |> add_column(:product_no, "integer") |> add_column(:name, "text") |> add_column(:price, "numeric") @@ -17,7 +17,7 @@ defmodule Test.Sonata.CreateTable do end test "default products" do - create_table("products") + create_table(:products) |> add_column([ column(:product_no, "integer"), column(:name, "text"), @@ -28,7 +28,7 @@ defmodule Test.Sonata.CreateTable do end test "default product no" do - create_table("products") + create_table(:products) |> add_column([ column(:product_no, "integer") |> default(random()), @@ -37,7 +37,7 @@ defmodule Test.Sonata.CreateTable do end test "products SERIAL" do - create_table("products") + create_table(:products) |> add_column([ column(:product_no, "SERIAL") ]) @@ -45,7 +45,7 @@ defmodule Test.Sonata.CreateTable do end test "products CHECK price > 0" do - create_table("products") + create_table(:products) |> add_column([ column(:product_no, "integer"), column(:name, "text"), @@ -61,7 +61,7 @@ defmodule Test.Sonata.CreateTable do end test "products named CHECK" do - create_table("products") + create_table(:products) |> add_column([ column(:product_no, "integer"), column(:name, "text"), @@ -78,7 +78,7 @@ defmodule Test.Sonata.CreateTable do end test "products CHECK operator" do - create_table("products") + create_table(:products) |> add_column([ column(:product_no, "integer"), column(:name, "text"), @@ -92,7 +92,7 @@ defmodule Test.Sonata.CreateTable do end test "table-wide checks" do - create_table("products") + create_table(:products) |> add_column([ column(:product_no, "integer"), column(:name, "text"), @@ -113,7 +113,7 @@ defmodule Test.Sonata.CreateTable do end test "not null" do - create_table("products") + create_table(:products) |> add_column([ column(:product_no, "integer") |> not_null(), @@ -130,7 +130,7 @@ defmodule Test.Sonata.CreateTable do end test "unique" do - create_table("products") + create_table(:products) |> add_column([ column(:product_no, "integer") |> unique(), @@ -145,7 +145,7 @@ defmodule Test.Sonata.CreateTable do end test "unique multiple" do - create_table("products") + create_table(:products) |> add_column([ column(:a, "integer"), column(:b, "integer"), @@ -159,7 +159,7 @@ defmodule Test.Sonata.CreateTable do end test "primary key" do - create_table("products") + create_table(:products) |> add_column([ column(:product_no, "integer") |> primary_key(), @@ -174,7 +174,7 @@ defmodule Test.Sonata.CreateTable do end test "primary key multiple" do - create_table("products") + create_table(:products) |> add_column([ column(:a, "integer"), column(:b, "integer"), @@ -187,6 +187,72 @@ defmodule Test.Sonata.CreateTable do """, :unique_violation) end + test "references pk" do + [ + create_table(:products) + |> add_column([ + column(:product_no, "integer") + |> primary_key(), + ]), + + create_table(:orders) + |> add_column([ + column(:order_id, "integer") + |> primary_key(), + column(:product_no, "integer") + |> references(:products), + ]) + ] + |> assert_sql_error(""" + INSERT INTO orders VALUES + (1, 1); + """, :foreign_key_violation) + end + + test "references explicit" do + [ + create_table(:products) + |> add_column([ + column(:product_no, "integer") + |> primary_key(), + ]), + + create_table(:orders) + |> add_column([ + column(:order_id, "integer") + |> primary_key(), + column(:product_no, "integer") + |> references(:products, :product_no), + ]) + ] + |> assert_sql_error(""" + INSERT INTO orders VALUES + (1, 1); + """, :foreign_key_violation) + end + + test "foreign key" do + [ + create_table(:other_table) + |> add_column([ + column(:c1, "integer"), + column(:c2, "integer"), + ]) + |> primary_key([:c1, :c2]), + + create_table(:t1) + |> add_column([ + column(:a, "integer"), + column(:b, "integer"), + ]) + |> foreign_key([:a, :b], :other_table, [:c1, :c2]) + ] + |> assert_sql_error(""" + INSERT INTO t1 VALUES + (1, 1); + """, :foreign_key_violation) + end + defp table_info(name) do """ SELECT diff --git a/test/test_helper.exs b/test/test_helper.exs index 181e878..874bca8 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -20,7 +20,7 @@ defmodule Test.Sonata do defp load_snapshot(path) do {contents, []} = Code.eval_file(path) - contents + contents || %{} rescue Code.LoadError -> %{} @@ -71,12 +71,7 @@ defmodule Test.Sonata do defmacro assert_sql(struct, command) do quote do - {sql, params, _on_row} = Sonata.to_sql(unquote(struct)) - sql = :erlang.iolist_to_binary(sql) - - # IO.puts sql - - Ecto.Adapters.SQL.query!(Repo, sql, params) + query!(unquote(struct)) result = Ecto.Adapters.SQL.query!(Repo, unquote(command)) |> postgrex_result() @@ -87,12 +82,7 @@ defmodule Test.Sonata do defmacro assert_sql_error(struct, command, code) do quote do - {sql, params, _on_row} = Sonata.to_sql(unquote(struct)) - sql = :erlang.iolist_to_binary(sql) - - # IO.puts sql - - Ecto.Adapters.SQL.query!(Repo, sql, params) + query!(unquote(struct)) error = assert_raise Postgrex.Error, fn -> Ecto.Adapters.SQL.query!(Repo, unquote(command)) @@ -110,12 +100,8 @@ defmodule Test.Sonata do defmacro assert_snapshot(struct) do quote do - {sql, params, on_row} = Sonata.to_sql(unquote(struct)) - sql = :erlang.iolist_to_binary(sql) - - # IO.puts sql - - result = Ecto.Adapters.SQL.query!(Repo, sql, params) + {response, on_row} = query!(unquote(struct)) + result = response |> postgrex_result() |> Enum.map(on_row) @@ -123,6 +109,20 @@ defmodule Test.Sonata do end end + def query!(structs) when is_list(structs) do + Repo.transaction fn -> + Enum.each(structs, &query!/1) + end + end + def query!(struct) do + {sql, params, on_row} = Sonata.to_sql(struct) + sql = :erlang.iolist_to_binary(sql) + + IO.puts sql + + {Ecto.Adapters.SQL.query!(Repo, sql, params), on_row} + end + def record_result(module, result) do test_name = Process.get(:test_name) case Process.get(:snapshot) do From c7113dba07669a17727d9793529f4bddae3079ed Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Thu, 27 Jul 2017 12:52:44 -0600 Subject: [PATCH 13/43] escape column types --- lib/sonata/definition/column.ex | 2 +- test/test_helper.exs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/sonata/definition/column.ex b/lib/sonata/definition/column.ex index 1c6fcec..ad3cd99 100644 --- a/lib/sonata/definition/column.ex +++ b/lib/sonata/definition/column.ex @@ -203,7 +203,7 @@ defimpl Sonata.Postgres, for: Sonata.Definition.Column do {nil, [], idx} end defp type(type, _, idx) do - [type | _] = type |> to_string() |> String.split(" ") + type = Regex.replace(~r/[^a-zA-Z0-9_]/, to_string(type), "") {type, [], idx} end diff --git a/test/test_helper.exs b/test/test_helper.exs index 874bca8..dcbf7b6 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -109,6 +109,7 @@ defmodule Test.Sonata do end end + require Logger def query!(structs) when is_list(structs) do Repo.transaction fn -> Enum.each(structs, &query!/1) @@ -118,7 +119,7 @@ defmodule Test.Sonata do {sql, params, on_row} = Sonata.to_sql(struct) sql = :erlang.iolist_to_binary(sql) - IO.puts sql + Logger.debug(sql) {Ecto.Adapters.SQL.query!(Repo, sql, params), on_row} end From 9405c66b99538e56b1d9a4c7cc32f84d90ddee53 Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Thu, 27 Jul 2017 13:07:53 -0600 Subject: [PATCH 14/43] don't execute list of statements in transaction --- test/test_helper.exs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_helper.exs b/test/test_helper.exs index dcbf7b6..b483d8a 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -111,9 +111,7 @@ defmodule Test.Sonata do require Logger def query!(structs) when is_list(structs) do - Repo.transaction fn -> - Enum.each(structs, &query!/1) - end + Enum.each(structs, &query!/1) end def query!(struct) do {sql, params, on_row} = Sonata.to_sql(struct) @@ -121,7 +119,9 @@ defmodule Test.Sonata do Logger.debug(sql) - {Ecto.Adapters.SQL.query!(Repo, sql, params), on_row} + result = Ecto.Adapters.SQL.query!(Repo, sql, params) + + {result, on_row} end def record_result(module, result) do From 9f5b5a5c4aef5f0002be6ba9298e3f686fb53c1b Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Thu, 27 Jul 2017 13:48:03 -0600 Subject: [PATCH 15/43] add drop tests --- test/drop_table_test.exs | 80 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 test/drop_table_test.exs diff --git a/test/drop_table_test.exs b/test/drop_table_test.exs new file mode 100644 index 0000000..877fc1c --- /dev/null +++ b/test/drop_table_test.exs @@ -0,0 +1,80 @@ +defmodule Test.Sonata.CreateTable do + use Test.Sonata + + test "should drop table" do + [ + create_table("my_first_table") + |> add_column(:first_column, "text") + |> add_column(:second_column, "integer"), + + drop_table("my_first_table"), + ] + |> assert_sql_error(""" + SELECT * FROM my_first_table + """, :reference_error) + end + + test "should successfully drop table, whether it exists or not, pt.1" do + drop_table("doesnt_exist") + |> if_exists() + |> assert_snapshot() + end + + test "should successfully drop table, whether it exists or not, pt.2" do + [ + create_table("exists") + |> add_column(:first_column, "text"), + + drop_table("exists") + |> if_exists() + ] + |> assert_snapshot() + end + + test "should fail to drop table" do + drop_table("doesnt_exist") + |> assert_sql_error(:foo) + end + + test "should rop table, and dependent objects (view)" do + [ + create_table("parent") + |> add_column(:parent_column, "text"), + + create_view("child") + |> add_column( + column(:child_column, "text") + |> as( + select(:parent_column) + from("parent") + ) + ), + + drop_table("my_first_table") + |> cascade(), + ] + |> assert_sql_error(""" + SELECT * FROM child_view + """, :reference_error) + end + + test "`restrict()` should prevent the drop because of dependent object" do + [ + create_table("parent") + |> add_column(:parent_column, "text"), + + create_view("child") + |> add_column( + column(:child_column, "text") + |> as( + select(:parent_column) + from("parent") + ) + ), + + drop_table("my_first_table") + |> restrict(), + ] + |> assert_snapshot() + end +end From 62c1c2780b9b8ab12f5e5213d6ca44fcace48741 Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Thu, 27 Jul 2017 13:54:08 -0600 Subject: [PATCH 16/43] copy/pasta shame --- test/drop_table_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/drop_table_test.exs b/test/drop_table_test.exs index 877fc1c..476e559 100644 --- a/test/drop_table_test.exs +++ b/test/drop_table_test.exs @@ -1,4 +1,4 @@ -defmodule Test.Sonata.CreateTable do +defmodule Test.Sonata.DropTable do use Test.Sonata test "should drop table" do From aa4f3ffc7ab8cf5f0c58d5b7680c1bf68f8a37e7 Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Thu, 27 Jul 2017 14:24:58 -0600 Subject: [PATCH 17/43] implement drop table --- _snapshots/Test.Sonata.DropTable.snapshot | 12 ++++ lib/sonata/drop_table.ex | 19 +++++- test/drop_table_test.exs | 76 +++++++++++------------ test/test_helper.exs | 35 +++++++++-- 4 files changed, 97 insertions(+), 45 deletions(-) create mode 100644 _snapshots/Test.Sonata.DropTable.snapshot diff --git a/_snapshots/Test.Sonata.DropTable.snapshot b/_snapshots/Test.Sonata.DropTable.snapshot new file mode 100644 index 0000000..4b6f11c --- /dev/null +++ b/_snapshots/Test.Sonata.DropTable.snapshot @@ -0,0 +1,12 @@ +%{"test should drop table": %Postgrex.Error{connection_id: nil, message: nil, + postgres: %{code: :undefined_table, file: "parse_relation.c", line: "1160", + message: "relation \"my_first_table\" does not exist", pg_code: "42P01", + position: "15", routine: "parserOpenTable", severity: "ERROR", + unknown: "ERROR"}}, + "test should fail to drop table": %Postgrex.Error{connection_id: nil, + message: nil, + postgres: %{code: :undefined_table, file: "tablecmds.c", line: "760", + message: "table \"doesnt_exist\" does not exist", pg_code: "42P01", + routine: "DropErrorMsgNonExistent", severity: "ERROR", unknown: "ERROR"}}, + "test should successfully drop table, whether it exists or not, pt.1": :drop_table, + "test should successfully drop table, whether it exists or not, pt.2": :drop_table} \ No newline at end of file diff --git a/lib/sonata/drop_table.ex b/lib/sonata/drop_table.ex index a8614f3..0996bb5 100644 --- a/lib/sonata/drop_table.ex +++ b/lib/sonata/drop_table.ex @@ -1,23 +1,36 @@ defmodule Sonata.DropTable do - defstruct [table: nil] + defstruct [table: nil, + if_exists: nil] def drop_table(table) do %__MODULE__{table: table} end + + def if_exists(table) do + %{table | if_exists: true} + end end defimpl Sonata.Postgres, for: Sonata.DropTable do alias Sonata.Postgres, as: PG alias PG.Utils - def to_sql(%{table: table}, opts, idx) do + def to_sql(%{table: table, if_exists: if_exists}, opts, idx) do + if_exists = if_exists(if_exists) { - ["DROP TABLE", Utils.escape(table), ";"], + ["DROP TABLE ", if_exists, Utils.escape(table), ";"], [], idx } end + def if_exists(true) do + "IF EXISTS " + end + def if_exists(_) do + "" + end + def on_row(_, _) do nil end diff --git a/test/drop_table_test.exs b/test/drop_table_test.exs index 476e559..e06239a 100644 --- a/test/drop_table_test.exs +++ b/test/drop_table_test.exs @@ -11,7 +11,7 @@ defmodule Test.Sonata.DropTable do ] |> assert_sql_error(""" SELECT * FROM my_first_table - """, :reference_error) + """, :undefined_table) end test "should successfully drop table, whether it exists or not, pt.1" do @@ -33,48 +33,48 @@ defmodule Test.Sonata.DropTable do test "should fail to drop table" do drop_table("doesnt_exist") - |> assert_sql_error(:foo) + |> assert_sql_error(:undefined_table) end - test "should rop table, and dependent objects (view)" do - [ - create_table("parent") - |> add_column(:parent_column, "text"), + # test "should drop table, and dependent objects (view)" do + # [ + # create_table("parent") + # |> add_column(:parent_column, "text"), - create_view("child") - |> add_column( - column(:child_column, "text") - |> as( - select(:parent_column) - from("parent") - ) - ), + # create_view("child") + # |> add_column( + # column(:child_column, "text") + # |> as( + # select(:parent_column) + # from("parent") + # ) + # ), - drop_table("my_first_table") - |> cascade(), - ] - |> assert_sql_error(""" - SELECT * FROM child_view - """, :reference_error) - end + # drop_table("my_first_table") + # |> cascade(), + # ] + # |> assert_sql_error(""" + # SELECT * FROM child_view + # """, :reference_error) + # end - test "`restrict()` should prevent the drop because of dependent object" do - [ - create_table("parent") - |> add_column(:parent_column, "text"), + # test "`restrict()` should prevent the drop because of dependent object" do + # [ + # create_table("parent") + # |> add_column(:parent_column, "text"), - create_view("child") - |> add_column( - column(:child_column, "text") - |> as( - select(:parent_column) - from("parent") - ) - ), + # create_view("child") + # |> add_column( + # column(:child_column, "text") + # |> as( + # select(:parent_column) + # from("parent") + # ) + # ), - drop_table("my_first_table") - |> restrict(), - ] - |> assert_snapshot() - end + # drop_table("my_first_table") + # |> restrict(), + # ] + # |> assert_snapshot() + # end end diff --git a/test/test_helper.exs b/test/test_helper.exs index b483d8a..67a6895 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -80,6 +80,22 @@ defmodule Test.Sonata do end end + defmacro assert_sql_error(struct, code) do + quote do + error = assert_raise Postgrex.Error, fn -> + query!(unquote(struct)) + end + + assert error.postgres.code == unquote(code) + + error = Map.merge(error, %{ + connection_id: nil + }) + + record_result(__MODULE__, error) + end + end + defmacro assert_sql_error(struct, command, code) do quote do query!(unquote(struct)) @@ -102,8 +118,7 @@ defmodule Test.Sonata do quote do {response, on_row} = query!(unquote(struct)) result = response - |> postgrex_result() - |> Enum.map(on_row) + |> postgrex_result(on_row) record_result(__MODULE__, result) end @@ -111,7 +126,11 @@ defmodule Test.Sonata do require Logger def query!(structs) when is_list(structs) do - Enum.each(structs, &query!/1) + structs + |> Stream.map(&query!/1) + |> Enum.reduce({nil, nil}, fn(res, _) -> + res + end) end def query!(struct) do {sql, params, on_row} = Sonata.to_sql(struct) @@ -136,12 +155,20 @@ defmodule Test.Sonata do send(module, {:add_snapshot, {test_name, result}}) end - def postgrex_result(%{columns: columns, rows: rows}) do + def postgrex_result(res, on_row \\ &(&1)) + def postgrex_result(res, nil) do + postgrex_result(res, &(&1)) + end + def postgrex_result(%{command: command, rows: nil}, _) do + command + end + def postgrex_result(%{columns: columns, rows: rows}, on_row) do rows |> Enum.map(fn(row) -> columns |> Stream.zip(row) |> Enum.into(%{}) + |> on_row.() end) end end From 66262c219eba0c41bc4921221887f6657a40234b Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Thu, 27 Jul 2017 14:26:00 -0600 Subject: [PATCH 18/43] manipulation tests --- test/manipulation.ex | 130 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 test/manipulation.ex diff --git a/test/manipulation.ex b/test/manipulation.ex new file mode 100644 index 0000000..2601b1f --- /dev/null +++ b/test/manipulation.ex @@ -0,0 +1,130 @@ +defmodule Test.Sonata.Manipulation do + use Test.Sonata + + test "should insert row" do + [ + create_table("my_first_table") + |> add_column(:first_column, "text") + |> add_column(:second_column, "integer"), + + insert_into("my_first_table") + |> fields([:first_column]) + |> values(["foo"]) + ] + |> assert_sql(""" + SELECT * FROM my_first_table + """) + end + + test "should insert row without specifying columns" do + [ + create_table("my_first_table") + |> add_column(:first_column, "text") + |> add_column(:second_column, "integer"), + + insert_into("my_first_table") + |> values(["foo", "bar"]) + ] + |> assert_sql(""" + SELECT * FROM my_first_table + """) + end + + test "should insert with defaults" do + [ + create_table("my_first_table") + |> add_column([ + column(:first_column, "text"), + column(:second_column, "integer") + |> default(123) + ]) + + insert_into("my_first_table") + |> fields([:first_column, :second_column]) + |> values(["foo", default()]) + ] + |> assert_sql(""" + SELECT * FROM my_first_table where second_column = 123; + """) + end + + test "should insert value other than default" do + [ + create_table("my_first_table") + |> add_column([ + column(:first_column, "text"), + column(:second_column, "integer") + |> default(123) + ]), + + insert_into("my_first_table") + |> values(["foo", 456]) + ] + |> assert_sql(""" + SELECT * FROM my_first_table where second_column = 456; + """) + end + + test "should return value after insert" do + [ + create_table("my_first_table") + |> add_column(:first_column, "text") + |> add_column(:second_column, "integer"), + + insert_into("my_first_table") + |> values(["foo", 789]) + |> returning([:first_column, {:second_column, :as_this_label}]) + ] + |> assert_snapshot() + end + + test "should do nothing on conflict" do + [ + create_table("my_first_table") + |> add_column([ + column(:id, "serial") + |> unique(), + column(:value, "integer") + ]) + + insert_into("my_first_table") + |> values([1, 123]) + + insert_into("my_first_table") + |> values([1, 456]) + |> on_conflict( + do_nothing() + ) + ] + |> assert_sql(""" + SELECT * FROM my_first_table where second_column = 123; + """) + end + + # TODO not sure if the `set([{:value, 456}])` is right + test "should update on conflict" do + [ + create_table("my_first_table") + |> add_column([ + column(:id, "serial") + |> unique(), + column(:value, "integer") + ]) + + insert_into("my_first_table") + |> values([1, 123]) + + insert_into("my_first_table") + |> values([1, 456]) + |> on_conflict( + do_update() + |> set([ + {:value, 456}, + ]) + ) + ] + |> assert_sql(""" + SELECT * FROM my_first_table where second_column = 123; + """) + end +end From 0297076d982fd888444b07cbff15e1e06965d408 Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Thu, 27 Jul 2017 15:03:18 -0600 Subject: [PATCH 19/43] partially implement insertion --- _snapshots/Test.Sonata.Manipulation.snapshot | 6 ++++ lib/sonata/expr.ex | 4 +++ lib/sonata/expr/call.ex | 2 +- lib/sonata/expr/default.ex | 9 ++++++ lib/sonata/manipulation.ex | 29 ++++++++++++++----- lib/sonata/manipulation/insertion.ex | 24 ++++++++++----- lib/sonata/postgres/utils.ex | 4 +-- ...{manipulation.ex => manipulation_test.exs} | 10 +++---- 8 files changed, 66 insertions(+), 22 deletions(-) create mode 100644 _snapshots/Test.Sonata.Manipulation.snapshot create mode 100644 lib/sonata/expr/default.ex rename test/{manipulation.ex => manipulation_test.exs} (97%) diff --git a/_snapshots/Test.Sonata.Manipulation.snapshot b/_snapshots/Test.Sonata.Manipulation.snapshot new file mode 100644 index 0000000..29019c1 --- /dev/null +++ b/_snapshots/Test.Sonata.Manipulation.snapshot @@ -0,0 +1,6 @@ +%{"test should insert row": [%{"first_column" => "foo", + "second_column" => nil}], + "test should insert value other than default": [%{"first_column" => "foo", + "second_column" => 456}], + "test should insert with defaults": [%{"first_column" => "foo", + "second_column" => 123}], "test should return value after insert": :insert} \ No newline at end of file diff --git a/lib/sonata/expr.ex b/lib/sonata/expr.ex index 71ffe19..3e2d8fb 100644 --- a/lib/sonata/expr.ex +++ b/lib/sonata/expr.ex @@ -23,6 +23,10 @@ defmodule Sonata.Expr do %__MODULE__.Value{value: value} end + def default() do + %__MODULE__.Default{} + end + defmacro op(lhs, name, rhs) when is_atom(name) do quote do Sonata.Operator.unquote(name)(unquote(lhs), unquote(rhs)) diff --git a/lib/sonata/expr/call.ex b/lib/sonata/expr/call.ex index 489405b..9bca1de 100644 --- a/lib/sonata/expr/call.ex +++ b/lib/sonata/expr/call.ex @@ -1,5 +1,5 @@ defmodule Sonata.Expr.Call do - defstruct [:name, :arguments] + defstruct [name: nil, arguments: []] end defimpl Sonata.Postgres, for: Sonata.Expr.Call do diff --git a/lib/sonata/expr/default.ex b/lib/sonata/expr/default.ex new file mode 100644 index 0000000..35b76a9 --- /dev/null +++ b/lib/sonata/expr/default.ex @@ -0,0 +1,9 @@ +defmodule Sonata.Expr.Default do + defstruct [] +end + +defimpl Sonata.Postgres, for: Sonata.Expr.Default do + def to_sql(_, _, idx) do + {"DEFAULT", [], idx} + end +end diff --git a/lib/sonata/manipulation.ex b/lib/sonata/manipulation.ex index a035d48..ed54a5c 100644 --- a/lib/sonata/manipulation.ex +++ b/lib/sonata/manipulation.ex @@ -1,6 +1,9 @@ defmodule Sonata.Manipulation do alias __MODULE__.{Insertion,Update} + alias Sonata.Expr + require Expr + def insert_into(table) do %Insertion{table: table} end @@ -16,13 +19,13 @@ defmodule Sonata.Manipulation do # TODO: support `INSERT INTO foo (valA, valB) VALUES (SELECT ...)` def values(insertion = %{rows: rows}, [first | _ ] = values) when is_list(first) do - %{insertion | rows: Enum.into(rows, values)} + %{insertion | rows: rows ++ values} end - def values(insertion = %{rows: rows}, values) when is_list(values) do - %{insertion | rows: Enum.into(rows, [values])} + def values(insertion, values) when is_list(values) do + values(insertion, [values]) end - def default_values(insertion = %{default_values: _}) do + def default_values(insertion) do %{insertion | default_values: :true} end @@ -34,16 +37,16 @@ defmodule Sonata.Manipulation do %Update{table: table, table_alias: table_alias} end - def set(insertion = %Update{sets: sets}, kvs) do + def set(insertion = %{sets: sets}, kvs) do %{insertion | sets: sets ++ Enum.map(kvs, fn ({fields, value}) when is_list(fields) -> - {Sonata.Expr.column_list(fields), value} + Expr.op(Sonata.Expr.column_list(fields) = value) ({fields, _value}) when is_tuple(fields) -> fields |> :erlang.tuple_to_list() |> Sonata.Expr.column_list() ({field, value}) -> - {Sonata.Expr.column(field), value} + Expr.op(Sonata.Expr.column(field) = value) end)} end @@ -55,4 +58,16 @@ defmodule Sonata.Manipulation do def returning(insertion = %{returning: returning}, fields) do %{insertion | returning: returning ++ fields} end + + def on_conflict(m, behavior) do + m + end + + def do_update() do + %{sets: []} + end + + def do_nothing() do + :DO_NOTHING + end end diff --git a/lib/sonata/manipulation/insertion.ex b/lib/sonata/manipulation/insertion.ex index 675a326..d16f71a 100644 --- a/lib/sonata/manipulation/insertion.ex +++ b/lib/sonata/manipulation/insertion.ex @@ -43,21 +43,31 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do {Utils.escape(table), opts, idx} end - def fields(fields, _, idx) when fields in [nil, false, ""] do + def fields([], _, idx) do + {nil, [], idx} + end + def fields(fields, opts, idx) do + # TODO {nil, [], idx} end - def default_values(:true, opts, idx) do - {"DEFAULT VALUES", opts, idx} + def default_values(true, opts, idx) do + {"DEFAULT VALUES", [], idx} + end + def default_values(_, _, idx) do + {nil, [], idx} end - def rows(rows, _, idx) when rows in [nil, false, ""] do + def rows([], _, idx) do {nil, [], idx} end - # TODO def rows(rows, opts, idx) do - {["VALUES"] ++ rows, opts, idx} - end + {rows, params, idx} = Utils.list_to_sql(rows, opts, idx, &(&1), fn(row, opts, idx) -> + {row, params, idx} = Utils.list_to_sql(row, opts, idx) + {Utils.join(row, ", "), params, idx} + end) + {["VALUES (", Utils.join(rows, "), ("), ")"], params, idx} + end # TODO # defp on_conflict do diff --git a/lib/sonata/postgres/utils.ex b/lib/sonata/postgres/utils.ex index 83767cf..5b2fe4f 100644 --- a/lib/sonata/postgres/utils.ex +++ b/lib/sonata/postgres/utils.ex @@ -56,9 +56,9 @@ defmodule Sonata.Postgres.Utils do |> join(delim) end - def list_to_sql(list, opts, idx, mapper \\ &(&1)) do + def list_to_sql(list, opts, idx, mapper \\ &(&1), to_sql \\ &PG.to_sql/3) do {sql, {params, idx}} = Enum.map_reduce(list, {[], idx}, fn(item, {acc_params, idx}) -> - {sql, params, idx} = PG.to_sql(item, opts, idx) + {sql, params, idx} = to_sql.(item, opts, idx) {mapper.(sql), {Stream.concat(acc_params, params), idx}} end) {sql, params, idx} diff --git a/test/manipulation.ex b/test/manipulation_test.exs similarity index 97% rename from test/manipulation.ex rename to test/manipulation_test.exs index 2601b1f..cfe873a 100644 --- a/test/manipulation.ex +++ b/test/manipulation_test.exs @@ -37,7 +37,7 @@ defmodule Test.Sonata.Manipulation do column(:first_column, "text"), column(:second_column, "integer") |> default(123) - ]) + ]), insert_into("my_first_table") |> fields([:first_column, :second_column]) @@ -85,10 +85,10 @@ defmodule Test.Sonata.Manipulation do column(:id, "serial") |> unique(), column(:value, "integer") - ]) + ]), insert_into("my_first_table") - |> values([1, 123]) + |> values([1, 123]), insert_into("my_first_table") |> values([1, 456]) @@ -109,10 +109,10 @@ defmodule Test.Sonata.Manipulation do column(:id, "serial") |> unique(), column(:value, "integer") - ]) + ]), insert_into("my_first_table") - |> values([1, 123]) + |> values([1, 123]), insert_into("my_first_table") |> values([1, 456]) From 954cf97beef14cb584c9c0f334370316ca452e85 Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Thu, 27 Jul 2017 15:44:00 -0600 Subject: [PATCH 20/43] finish insertions --- _snapshots/Test.Sonata.Manipulation.snapshot | 9 ++++-- lib/sonata/definition/do_nothing.ex | 15 +++++++++ lib/sonata/definition/do_update.ex | 32 ++++++++++++++++++++ lib/sonata/definition/on_conflict.ex | 18 +++++++++++ lib/sonata/expr/operator.ex | 10 +++++- lib/sonata/manipulation.ex | 12 +++++--- lib/sonata/manipulation/insertion.ex | 23 +++++++++----- test/manipulation_test.exs | 15 ++++----- 8 files changed, 112 insertions(+), 22 deletions(-) create mode 100644 lib/sonata/definition/do_nothing.ex create mode 100644 lib/sonata/definition/do_update.ex create mode 100644 lib/sonata/definition/on_conflict.ex diff --git a/_snapshots/Test.Sonata.Manipulation.snapshot b/_snapshots/Test.Sonata.Manipulation.snapshot index 29019c1..ca760c8 100644 --- a/_snapshots/Test.Sonata.Manipulation.snapshot +++ b/_snapshots/Test.Sonata.Manipulation.snapshot @@ -1,6 +1,9 @@ -%{"test should insert row": [%{"first_column" => "foo", - "second_column" => nil}], +%{"test should do nothing on conflict": [%{"id" => 1, "value" => 123}], + "test should insert row": [%{"first_column" => nil, "second_column" => 1}], + "test should insert row without specifying columns": [%{"first_column" => "foo", + "second_column" => 345}], "test should insert value other than default": [%{"first_column" => "foo", "second_column" => 456}], "test should insert with defaults": [%{"first_column" => "foo", - "second_column" => 123}], "test should return value after insert": :insert} \ No newline at end of file + "second_column" => 123}], "test should return value after insert": :insert, + "test should update on conflict": []} \ No newline at end of file diff --git a/lib/sonata/definition/do_nothing.ex b/lib/sonata/definition/do_nothing.ex new file mode 100644 index 0000000..9736391 --- /dev/null +++ b/lib/sonata/definition/do_nothing.ex @@ -0,0 +1,15 @@ +defmodule Sonata.Manipulation.DoNothing do + defstruct [] +end + +defimpl Sonata.Postgres, for: Sonata.Manipulation.DoNothing do + alias Sonata.Postgres.Utils + + def to_sql(_, _, idx) do + {"DO NOTHING", [], idx} + end + + def on_row(_, _) do + nil + end +end diff --git a/lib/sonata/definition/do_update.ex b/lib/sonata/definition/do_update.ex new file mode 100644 index 0000000..7ec0d8d --- /dev/null +++ b/lib/sonata/definition/do_update.ex @@ -0,0 +1,32 @@ +defmodule Sonata.Manipulation.DoUpdate do + defstruct [sets: [], where: nil] +end + +defimpl Sonata.Postgres, for: Sonata.Manipulation.DoUpdate do + alias Sonata.Postgres, as: PG + alias PG.Utils + + def to_sql(%{sets: sets}, opts, idx) do + {sets, s_params, idx} = sets(sets, opts, idx) + + { + Utils.join([ + "DO UPDATE", + sets, + ], " "), + Stream.concat([ + s_params + ]), + idx + } + end + + defp sets([], _, idx) do + {nil, [], idx} + end + defp sets(sets, opts, idx) do + opts = Map.put(opts, :parens, false) + {sql, params, idx} = Utils.list_to_sql(sets, opts, idx) + {["SET ", Utils.join(sql, ", ")], params, idx} + end +end diff --git a/lib/sonata/definition/on_conflict.ex b/lib/sonata/definition/on_conflict.ex new file mode 100644 index 0000000..164205e --- /dev/null +++ b/lib/sonata/definition/on_conflict.ex @@ -0,0 +1,18 @@ +defmodule Sonata.Manipulation.OnConflict do + defstruct [:target, :action] +end + +defimpl Sonata.Postgres, for: Sonata.Manipulation.OnConflict do + alias Sonata.Postgres, as: PG + + def to_sql(%{target: target, action: action}, opts, idx) do + {target, t_params, idx} = PG.to_sql(target, opts, idx) + {action, a_params, idx} = PG.to_sql(action, opts, idx) + {[ + "ON CONFLICT ", + target, + " ", + action, + ], Stream.concat(t_params, a_params), idx} + end +end diff --git a/lib/sonata/expr/operator.ex b/lib/sonata/expr/operator.ex index c82ce0e..88639b5 100644 --- a/lib/sonata/expr/operator.ex +++ b/lib/sonata/expr/operator.ex @@ -6,9 +6,17 @@ defimpl Sonata.Postgres, for: Sonata.Expr.Operator do alias Sonata.Postgres, as: PG def to_sql(%{operator: operator, rhs: rhs, lhs: lhs}, opts, idx) do + {parens, opts} = Map.pop(opts, :parens) {lhs, lhs_params, idx} = PG.to_sql(lhs, opts, idx) {rhs, rhs_params, idx} = PG.to_sql(rhs, opts, idx) - {["(", lhs, " ", operator, " ", rhs, ")"], Stream.concat(lhs_params, rhs_params), idx} + sql = [lhs, " ", operator, " ", rhs] + sql = + if parens == false do + sql + else + ["(", sql, ")"] + end + {sql, Stream.concat(lhs_params, rhs_params), idx} end def on_row(_, _) do diff --git a/lib/sonata/manipulation.ex b/lib/sonata/manipulation.ex index ed54a5c..8e5b39b 100644 --- a/lib/sonata/manipulation.ex +++ b/lib/sonata/manipulation.ex @@ -59,15 +59,19 @@ defmodule Sonata.Manipulation do %{insertion | returning: returning ++ fields} end - def on_conflict(m, behavior) do - m + def on_conflict(m, column, action) when is_atom(column) do + on_conflict = %__MODULE__.OnConflict{ + target: Sonata.Expr.column_list([column]), + action: action, + } + %{m | on_conflict: on_conflict} end def do_update() do - %{sets: []} + %__MODULE__.DoUpdate{} end def do_nothing() do - :DO_NOTHING + %__MODULE__.DoNothing{} end end diff --git a/lib/sonata/manipulation/insertion.ex b/lib/sonata/manipulation/insertion.ex index d16f71a..e29679f 100644 --- a/lib/sonata/manipulation/insertion.ex +++ b/lib/sonata/manipulation/insertion.ex @@ -3,7 +3,8 @@ defmodule Sonata.Manipulation.Insertion do fields: [], rows: [], returning: [], - default_values: nil] + default_values: nil, + on_conflict: nil,] end defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do @@ -15,21 +16,24 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do {fields, fields_params, idx} = fields(insertion.fields, opts, idx) {default_values, default_values_params, idx} = default_values(insertion.default_values, opts, idx) {rows, rows_params, idx} = rows(insertion.rows, opts, idx) + {on_conflict, on_conflict_params, idx} = on_conflict(insertion.on_conflict, opts, idx) { - Utils.join([ + [Utils.join([ "INSERT INTO", table, fields, default_values, rows, - ], " "), + on_conflict, + ], " "), ";"], Stream.concat([ table_params, fields_params, default_values_params, rows_params, + on_conflict_params, ]), idx @@ -47,8 +51,8 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do {nil, [], idx} end def fields(fields, opts, idx) do - # TODO - {nil, [], idx} + {fields, params, idx} = Utils.list_to_sql(fields, opts, idx) + {["(", Utils.join(fields, ", "), ")"], params, idx} end def default_values(true, opts, idx) do @@ -69,9 +73,14 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do {["VALUES (", Utils.join(rows, "), ("), ")"], params, idx} end + defp on_conflict(nil, _, idx) do + {nil, [], idx} + end + defp on_conflict(on_conflict, opts, idx) do + PG.to_sql(on_conflict, opts, idx) + end + # TODO - # defp on_conflict do - # end # defp returning do # end diff --git a/test/manipulation_test.exs b/test/manipulation_test.exs index cfe873a..bac6c95 100644 --- a/test/manipulation_test.exs +++ b/test/manipulation_test.exs @@ -8,8 +8,8 @@ defmodule Test.Sonata.Manipulation do |> add_column(:second_column, "integer"), insert_into("my_first_table") - |> fields([:first_column]) - |> values(["foo"]) + |> fields([:second_column]) + |> values([1]) ] |> assert_sql(""" SELECT * FROM my_first_table @@ -23,7 +23,7 @@ defmodule Test.Sonata.Manipulation do |> add_column(:second_column, "integer"), insert_into("my_first_table") - |> values(["foo", "bar"]) + |> values(["foo", 345]) ] |> assert_sql(""" SELECT * FROM my_first_table @@ -93,15 +93,15 @@ defmodule Test.Sonata.Manipulation do insert_into("my_first_table") |> values([1, 456]) |> on_conflict( + :id, do_nothing() ) ] |> assert_sql(""" - SELECT * FROM my_first_table where second_column = 123; + SELECT * FROM my_first_table where value = 123; """) end - # TODO not sure if the `set([{:value, 456}])` is right test "should update on conflict" do [ create_table("my_first_table") @@ -117,14 +117,15 @@ defmodule Test.Sonata.Manipulation do insert_into("my_first_table") |> values([1, 456]) |> on_conflict( + :id, do_update() |> set([ - {:value, 456}, + value: 456, ]) ) ] |> assert_sql(""" - SELECT * FROM my_first_table where second_column = 123; + SELECT * FROM my_first_table where value = 123; """) end end From 113f3c13057225b1583e3fed645466f10658a6c0 Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Thu, 27 Jul 2017 15:47:53 -0600 Subject: [PATCH 21/43] query tests --- _snapshots/Test.Sonata.Query.snapshot | 1 + lib/sonata/query.ex | 10 +- mix.lock | 20 ++-- test/query_test.exs | 130 ++++++++++++++++++++++++++ 4 files changed, 148 insertions(+), 13 deletions(-) create mode 100644 _snapshots/Test.Sonata.Query.snapshot create mode 100644 test/query_test.exs diff --git a/_snapshots/Test.Sonata.Query.snapshot b/_snapshots/Test.Sonata.Query.snapshot new file mode 100644 index 0000000..2c55f3b --- /dev/null +++ b/_snapshots/Test.Sonata.Query.snapshot @@ -0,0 +1 @@ +%{} \ No newline at end of file diff --git a/lib/sonata/query.ex b/lib/sonata/query.ex index 481fbad..b2723cb 100644 --- a/lib/sonata/query.ex +++ b/lib/sonata/query.ex @@ -56,10 +56,14 @@ defmodule Sonata.Query do %{q | from: {from, alias}} end + # TODO + def count(q, {column, alias}) do + end + ## TODO add support for join - ## def join(q) do - ## - ## end + def join(q, table, on) do + + end #def join() -> inner_join() #def inner_join() diff --git a/mix.lock b/mix.lock index c7d50f4..d6436d7 100644 --- a/mix.lock +++ b/mix.lock @@ -1,11 +1,11 @@ -%{"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [], [], "hexpm"}, - "csv": {:hex, :csv, "2.0.0", "c66fea89ba7862b94901baf0871285e9b73cad89c5fdb57a6386d2adcf29593e", [], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm"}, - "db_connection": {:hex, :db_connection, "1.1.2", "2865c2a4bae0714e2213a0ce60a1b12d76a6efba0c51fbda59c9ab8d1accc7a8", [], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, - "decimal": {:hex, :decimal, "1.4.0", "fac965ce71a46aab53d3a6ce45662806bdd708a4a95a65cde8a12eb0124a1333", [], [], "hexpm"}, - "ecto": {:hex, :ecto, "2.1.4", "d1ba932813ec0e0d9db481ef2c17777f1cefb11fc90fa7c142ff354972dfba7e", [], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, +%{"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"}, + "csv": {:hex, :csv, "2.0.0", "c66fea89ba7862b94901baf0871285e9b73cad89c5fdb57a6386d2adcf29593e", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm"}, + "db_connection": {:hex, :db_connection, "1.1.2", "2865c2a4bae0714e2213a0ce60a1b12d76a6efba0c51fbda59c9ab8d1accc7a8", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, + "decimal": {:hex, :decimal, "1.4.0", "fac965ce71a46aab53d3a6ce45662806bdd708a4a95a65cde8a12eb0124a1333", [:mix], [], "hexpm"}, + "ecto": {:hex, :ecto, "2.1.4", "d1ba932813ec0e0d9db481ef2c17777f1cefb11fc90fa7c142ff354972dfba7e", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, "epgsql": {:hex, :epgsql, "3.3.0", "974a578340e52012cbab820ce756e7ed1df1baf0110c59a6753d8337a2cf9454", [], [], "hexpm"}, - "fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [], [], "hexpm"}, - "mix_test_watch": {:hex, :mix_test_watch, "0.4.1", "a98a84c795623f1ba020324f4354cf30e7120ba4dab65f9c2ae300f830a25f75", [], [{:fs, "~> 0.9.1", [hex: :fs, repo: "hexpm", optional: false]}], "hexpm"}, - "parallel_stream": {:hex, :parallel_stream, "1.0.5", "4c78d3e675f9eff885cbe252c89a8fc1d2fb803c0d03a914281e587834e09431", [], [], "hexpm"}, - "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [], [], "hexpm"}, - "postgrex": {:hex, :postgrex, "0.13.3", "c277cfb2a9c5034d445a722494c13359e361d344ef6f25d604c2353185682bfc", [], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"}} + "fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], [], "hexpm"}, + "mix_test_watch": {:hex, :mix_test_watch, "0.4.1", "a98a84c795623f1ba020324f4354cf30e7120ba4dab65f9c2ae300f830a25f75", [:mix], [{:fs, "~> 0.9.1", [hex: :fs, repo: "hexpm", optional: false]}], "hexpm"}, + "parallel_stream": {:hex, :parallel_stream, "1.0.5", "4c78d3e675f9eff885cbe252c89a8fc1d2fb803c0d03a914281e587834e09431", [:mix], [], "hexpm"}, + "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"}, + "postgrex": {:hex, :postgrex, "0.13.3", "c277cfb2a9c5034d445a722494c13359e361d344ef6f25d604c2353185682bfc", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"}} diff --git a/test/query_test.exs b/test/query_test.exs new file mode 100644 index 0000000..77fa08a --- /dev/null +++ b/test/query_test.exs @@ -0,0 +1,130 @@ +defmodule Test.Sonata.Query do + use Test.Sonata + + test "should find all results" do + [ + seed(), + + select() + |> from("my_first_table") + ] + |> assert_snapshot() + end + + test "should find foo row" do + [ + seed(), + + select() + |> from("my_first_table") + |> where(:first_column, :=, "foo") + ] + |> assert_snapshot() + end + + test "should find rows with value < 3 row" do + [ + seed(), + select() + |> from("my_first_table") + |> where(:second_column, :<, 3) + ] + |> assert_snapshot() + end + + test "should reverse order" do + [ + seed(), + + select() + |> from("my_first_table") + |> Sonata.Query.order_by(:second_column, :desc) + ] + |> assert_snapshot() + end + + test "should return count of all rows" do + [ + seed([{"foo", 1}, {"bar", 1}, {"baz", 2}]), + + select( + count(:second_column) + ) + |> from("my_first_table") + ] + |> assert_snapshot() + end + + test "should return count based on a where clause" do + [ + seed([{"foo", 1}, {"bar", 1}, {"baz", 2}]), + + select( + count(:second_column, :label) #SELECT second_column as label + ) + |> from("my_first_table") + |> where([{:second_column, 1}]) + ] + |> assert_snapshot() + end + + test "should return count from group by clause" do + [ + seed([{"foo", 1}, {"bar", 1}, {"baz", 2}]), + + select([ + count(:first_column), + :first_column + ]) + |> from("my_first_table") + |> group_by(:second_column) + ] + |> assert_snapshot() + end + + test "should return limited result" do + [ + seed([{"foo", 1}, {"bar", 1}, {"baz", 2}]), + + select() + |> from("my_first_table") + |> where([{:first_column, 1}]) + |> limit(1) + ] + |> assert_snapshot() + end + + test "should return joined tables" do + [ + seed(), + create_table("my_second_table") + |> add_column(:label, "text") + |> add_column(:id, "integer"), + + insert_into("my_second_table") + |> values([{"label 1", 1}, {"label 2", 2}]), + + select() + |> from("my_first_table") + |> join("my_second_table", {{"my_first_table", :second_column}, :=, {"my_second_table", :id}}) + |> where({{"my_second_table", :id}, :=, 1}) + ] + |> assert_snapshot() + end + + def seed() do + seed([{"foo", 1}, {"bar", 2}, {"baz", 3}]) + end + + def seed(values) do + [ + create_table("my_first_table") + |> add_column(:first_column, "text") + |> add_column(:second_column, "integer"), + + insert_into("my_first_table") + |> fields([:first_column, :second_column]) + |> values(values), + ] + end +end From 21dc357482cf8f1def29e6ab20929f086e6a6971 Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Thu, 27 Jul 2017 16:34:37 -0600 Subject: [PATCH 22/43] improve between call --- lib/sonata/expr.ex | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/sonata/expr.ex b/lib/sonata/expr.ex index 3e2d8fb..93d0eba 100644 --- a/lib/sonata/expr.ex +++ b/lib/sonata/expr.ex @@ -48,7 +48,6 @@ defmodule Sonata.Expr do keywords = [ :and, - :between, :is_distinct_from, :is_not_distinct_from, :is_null, @@ -74,6 +73,22 @@ defmodule Sonata.Expr do end end + def between(column, lower, upper) do + %Operator{ + operator: "BETWEEN", + lhs: column, + rhs: __MODULE__.and(lower, upper), + } + end + + def not_between(column, lower, upper) do + %Operator{ + operator: "NOT BETWEEN", + lhs: column, + rhs: __MODULE__.and(lower, upper), + } + end + def not(rhs) do %Sonata.Expr.UnaryOperator{operator: "NOT", rhs: rhs} end From d1c7c28e735229b2a7819d30a94b474024ab1385 Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Thu, 27 Jul 2017 17:00:23 -0600 Subject: [PATCH 23/43] fix unary operators --- lib/sonata/expr.ex | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/lib/sonata/expr.ex b/lib/sonata/expr.ex index 93d0eba..436acf0 100644 --- a/lib/sonata/expr.ex +++ b/lib/sonata/expr.ex @@ -44,20 +44,15 @@ defmodule Sonata.Expr do end end - alias Sonata.Expr.Operator + alias Sonata.Expr.{ + Operator, + UnaryOperator, + } keywords = [ :and, :is_distinct_from, :is_not_distinct_from, - :is_null, - :is_not_null, - :is_true, - :is_not_true, - :is_false, - :is_not_false, - :is_unknown, - :is_not_unknown, :like, :not_like, :ilike, @@ -89,7 +84,22 @@ defmodule Sonata.Expr do } end - def not(rhs) do - %Sonata.Expr.UnaryOperator{operator: "NOT", rhs: rhs} + unary = [ + :not, + :is_null, + :is_not_null, + :is_true, + :is_not_true, + :is_false, + :is_not_false, + :is_unknown, + :is_not_unknown, + ] + + for keyword <- unary do + keyword_s = keyword |> to_string() |> String.upcase() |> String.replace("_", " ") + def unquote(keyword)(rhs) do + %UnaryOperator{operator: unquote(keyword_s), rhs: rhs} + end end end From c2912fe40a8c802b889b056134d81f63abee4ee5 Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Thu, 27 Jul 2017 17:01:01 -0600 Subject: [PATCH 24/43] expr tests --- test/expr_test.exs | 238 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 test/expr_test.exs diff --git a/test/expr_test.exs b/test/expr_test.exs new file mode 100644 index 0000000..8f2c889 --- /dev/null +++ b/test/expr_test.exs @@ -0,0 +1,238 @@ +defmodule Test.Sonata.Expr do + use Test.Sonata + + # test "AND" do + # [ + # seed([{"foo", 1}, {"foo", 2}, {"foo", 3}]), + # select() + # |> from("my_first_table") + # |> where(Expr.and({:first_column, :=, "foo"}, {:second_column, :>, 1})) + # ] + # end + + test "BETWEEN" do + [ + seed([{"foo", 2}, {"bar", 3}, {"baz", 4}]), + select() + |> from("my_first_table") + |> where(:second_column |> between(2, 4)) + ] + |> assert_snapshot() + end + + test "IS_DISTINCT_FROM" do + [ + create_table("my_first_table") + |> add_column(:first_column, "text") + |> add_column(:second_column, "text"), + + insert_into("my_first_table") + |> fields([:first_column, :second_column]) + |> values([{"foo", "foo"}, {"bar", "foo"}, {"bar", "bar"}]), + + select() + |> from("my_first_table") + |> where(is_distinct_from(:first_column, :second_column)) + ] + |> assert_snapshot() + end + + test "IS_NOT_DISTINCT_FROM" do + [ + create_table("my_first_table") + |> add_column(:first_column, "text") + |> add_column(:second_column, "text"), + + insert_into("my_first_table") + |> fields([:first_column, :second_column]) + |> values([{"foo", "foo"}, {"bar", "foo"}, {"bar", "bar"}]), + + select() + |> from("my_first_table") + |> where(is_not_distinct_from(:first_column, :second_column)) + ] + |> assert_snapshot() + end + + test "IS_NULL" do + [ + seed([{"foo", 1}, {"bar", nil}]), + select() + |> from("my_first_table") + |> where(is_null(:second_column)) + ] + |> assert_snapshot() + end + + test "IS_NOT_NULL" do + [ + seed([{"foo", 1}, {"bar", nil}]), + select() + |> from("my_first_table") + |> where(is_not_null(:second_column)) + ] + |> assert_snapshot() + end + + test "IS_TRUE" do + [ + create_table("my_first_table") + |> add_column(:first_column, "text") + |> add_column(:second_column, "bool"), + + insert_into("my_first_table") + |> fields([:first_column, :second_column]) + |> values([{"foo", true}, {"bar", false}, {"baz", nil}]), + + select() + |> from("my_first_table") + |> where(is_true(:second_column)) + ] + |> assert_snapshot() + end + + test "IS_NOT_TRUE" do + [ + create_table("my_first_table") + |> add_column(:first_column, "text") + |> add_column(:second_column, "bool"), + + insert_into("my_first_table") + |> fields([:first_column, :second_column]) + |> values([{"foo", true}, {"bar", false}, {"baz", nil}]), + + select() + |> from("my_first_table") + |> where(is_not_true(:second_column)) + ] + |> assert_snapshot() + end + + test "IS_FALSE" do + [ + create_table("my_first_table") + |> add_column(:first_column, "text") + |> add_column(:second_column, "bool"), + + insert_into("my_first_table") + |> fields([:first_column, :second_column]) + |> values([{"foo", true}, {"bar", false}, {"baz", nil}]), + + select() + |> from("my_first_table") + |> where(is_false(:second_column)) + ] + |> assert_snapshot() + end + + test "IS_NOT_FALSE" do + [ + create_table("my_first_table") + |> add_column(:first_column, "text") + |> add_column(:second_column, "bool"), + + insert_into("my_first_table") + |> fields([:first_column, :second_column]) + |> values([{"foo", true}, {"bar", false}, {"baz", nil}]), + + select() + |> from("my_first_table") + |> where(is_not_false(:second_column)) + ] + |> assert_snapshot() + end + + # test "IS_UNKNOWN" do + # [ + # seed(), + # select() + # |> from("my_first_table") + # |> where(is_unknown()) + # ] + # end + + # test "IS_NOT_UNKNOWN" do + # [ + # seed(), + # select() + # |> from("my_first_table") + # |> where(is_not_unknown()) + # ] + # end + + test "LIKE" do + [ + seed([{"foo", 1}, {"foobar", 2}, {"FOOBAR", 3}]), + select() + |> from("my_first_table") + |> where(Expr.like(:first_column, "foo")) + ] + |> assert_snapshot() + end + + test "NOT_LIKE" do + [ + seed([{"foo", 1}, {"foobar", 2}, {"FOOBAR", 3}]), + select() + |> from("my_first_table") + |> where(not_like(:first_column, "foo")) + ] + |> assert_snapshot() + end + + test "ILIKE" do + [ + seed([{"foo", 1}, {"foobar", 2}, {"FOOBAR", 3}]), + select() + |> from("my_first_table") + |> where(ilike(:first_column, "foo")) + ] + |> assert_snapshot() + end + + test "NOT_ILIKE" do + [ + seed([{"foobar", 1}, {"FOOBAR", 2}, {"BAZ", 3}]), + select() + |> from("my_first_table") + |> where(not_ilike(:first_column, "foo")) + ] + |> assert_snapshot() + end + + test "SIMILAR_TO" do + [ + seed([{"foobar", 1}, {"FOOBAR", 2}, {"BAZ", 3}]), + select() + |> from("my_first_table") + |> where(similar_to(:first_column, "f")) + ] + |> assert_snapshot() + end + + test "NOT_SIMILAR_TO" do + [ + seed([{"foobar", 1}, {"FOOBAR", 2}, {"BAZ", 3}]), + select() + |> from("my_first_table") + |> where(not_similar_to(:first_column, "b")) + ] + |> assert_snapshot() + end + + def seed() do + seed([{"foo", 1}, {"bar", 2}, {"baz", 3}]) + end + + def seed(values) do + [ + create_table("my_first_table") + |> add_column(:first_column, "text") + |> add_column(:second_column, "integer"), + + insert_into("my_first_table") + |> fields([:first_column, :second_column]) + |> values(values), + ] + end +end From fe9dffdefcc512edd993f432b1cc7be43337f825 Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Thu, 27 Jul 2017 17:46:53 -0600 Subject: [PATCH 25/43] fix a bunch of query tests --- _snapshots/Test.Sonata.Expr.snapshot | 26 ++++++++++++++++++++ _snapshots/Test.Sonata.Query.snapshot | 10 +++++++- bin/gen_functions.exs | 35 +++++++++++++++------------ lib/sonata.ex | 8 +++++- lib/sonata/expr.ex | 9 ++++--- lib/sonata/expr/operator.ex | 9 ++++++- lib/sonata/expr/unary_operator.ex | 14 ++++++++--- lib/sonata/function.ex | 6 +---- lib/sonata/manipulation.ex | 4 +-- lib/sonata/manipulation/insertion.ex | 1 + lib/sonata/query.ex | 14 ++++++++--- test/expr_test.exs | 28 ++++++++++----------- test/manipulation_test.exs | 18 +++++++------- test/query_test.exs | 5 ++-- 14 files changed, 127 insertions(+), 60 deletions(-) create mode 100644 _snapshots/Test.Sonata.Expr.snapshot diff --git a/_snapshots/Test.Sonata.Expr.snapshot b/_snapshots/Test.Sonata.Expr.snapshot new file mode 100644 index 0000000..d639046 --- /dev/null +++ b/_snapshots/Test.Sonata.Expr.snapshot @@ -0,0 +1,26 @@ +%{"test BETWEEN": [%{"first_column" => "foo", "second_column" => 2}, + %{"first_column" => "bar", "second_column" => 3}, + %{"first_column" => "baz", "second_column" => 4}], + "test ILIKE": [%{"first_column" => "foo", "second_column" => 1}], + "test IS_DISTINCT_FROM": [%{"first_column" => "bar", + "second_column" => "foo"}], + "test IS_FALSE": [%{"first_column" => "bar", "second_column" => false}], + "test IS_NOT_DISTINCT_FROM": [%{"first_column" => "foo", + "second_column" => "foo"}, + %{"first_column" => "bar", "second_column" => "bar"}], + "test IS_NOT_FALSE": [%{"first_column" => "foo", "second_column" => true}, + %{"first_column" => "baz", "second_column" => nil}], + "test IS_NOT_NULL": [%{"first_column" => "foo", "second_column" => 1}], + "test IS_NOT_TRUE": [%{"first_column" => "bar", "second_column" => false}, + %{"first_column" => "baz", "second_column" => nil}], + "test IS_NULL": [%{"first_column" => "bar", "second_column" => nil}], + "test IS_TRUE": [%{"first_column" => "foo", "second_column" => true}], + "test LIKE": [%{"first_column" => "foo", "second_column" => 1}], + "test NOT_ILIKE": [%{"first_column" => "foobar", "second_column" => 1}, + %{"first_column" => "FOOBAR", "second_column" => 2}, + %{"first_column" => "BAZ", "second_column" => 3}], + "test NOT_LIKE": [%{"first_column" => "foobar", "second_column" => 2}, + %{"first_column" => "FOOBAR", "second_column" => 3}], + "test NOT_SIMILAR_TO": [%{"first_column" => "foobar", "second_column" => 1}, + %{"first_column" => "FOOBAR", "second_column" => 2}, + %{"first_column" => "BAZ", "second_column" => 3}], "test SIMILAR_TO": []} \ No newline at end of file diff --git a/_snapshots/Test.Sonata.Query.snapshot b/_snapshots/Test.Sonata.Query.snapshot index 2c55f3b..d38531c 100644 --- a/_snapshots/Test.Sonata.Query.snapshot +++ b/_snapshots/Test.Sonata.Query.snapshot @@ -1 +1,9 @@ -%{} \ No newline at end of file +%{"test should find all results": [%{"first_column" => "foo", + "second_column" => 1}, %{"first_column" => "bar", "second_column" => 2}, + %{"first_column" => "baz", "second_column" => 3}], + "test should find foo row": [%{"first_column" => "foo", + "second_column" => 1}], + "test should find rows with value < 3 row": [%{"first_column" => "foo", + "second_column" => 1}, %{"first_column" => "bar", "second_column" => 2}], + "test should return count based on a where clause": [%{"label" => 2}], + "test should return count of all rows": [%{"count" => 3}]} \ No newline at end of file diff --git a/bin/gen_functions.exs b/bin/gen_functions.exs index 00dfba8..6924cb9 100644 --- a/bin/gen_functions.exs +++ b/bin/gen_functions.exs @@ -4,22 +4,27 @@ functions = "functions.csv" str = quote do defmodule Sonata.Function do - unquote_splicing(Enum.flat_map(functions, fn(%{ - "name" => name, - "arity" => arity, - "description" => description, - }) -> - arity = String.to_integer(arity) - fun = String.to_atom(name) - args = Macro.generate_arguments(arity, nil) - quote do - @doc unquote(description) - def unquote(fun)(unquote_splicing(args)) do - %Sonata.Expr.Call{name: unquote(name), arguments: unquote(args)} + unquote_splicing(Enum.flat_map(functions, fn + (%{ + "name" => name + }) when name in ["like"] -> + [] + (%{ + "name" => name, + "arity" => arity, + "description" => description, + }) -> + arity = String.to_integer(arity) + fun = String.to_atom(name) + args = Macro.generate_arguments(arity, nil) + quote do + @doc unquote(description) + def unquote(fun)(unquote_splicing(args)) do + %Sonata.Expr.Call{name: unquote(name), arguments: unquote(args)} + end end - end - |> elem(2) - end)) + |> elem(2) + end)) end end |> Macro.to_string() diff --git a/lib/sonata.ex b/lib/sonata.ex index 97970de..d8558b2 100644 --- a/lib/sonata.ex +++ b/lib/sonata.ex @@ -11,7 +11,6 @@ defmodule Sonata do Expr, Function, Manipulation, - OrderBy, Query, Transaction, } @@ -24,4 +23,11 @@ defmodule Sonata do on_row = Sonata.Postgres.on_row(statement, opts) {sql, Enum.to_list(params), on_row} end + + defmacro sonata(struct) do + quote do + use Sonata + unquote(struct) + end + end end diff --git a/lib/sonata/expr.ex b/lib/sonata/expr.ex index 436acf0..0f1bb63 100644 --- a/lib/sonata/expr.ex +++ b/lib/sonata/expr.ex @@ -85,7 +85,6 @@ defmodule Sonata.Expr do end unary = [ - :not, :is_null, :is_not_null, :is_true, @@ -98,8 +97,12 @@ defmodule Sonata.Expr do for keyword <- unary do keyword_s = keyword |> to_string() |> String.upcase() |> String.replace("_", " ") - def unquote(keyword)(rhs) do - %UnaryOperator{operator: unquote(keyword_s), rhs: rhs} + def unquote(keyword)(subject) do + %UnaryOperator{operator: unquote(keyword_s), subject: subject} end end + + def not(subject) do + %UnaryOperator{operator: "NOT", subject: subject, inverted: false} + end end diff --git a/lib/sonata/expr/operator.ex b/lib/sonata/expr/operator.ex index 88639b5..713ac6c 100644 --- a/lib/sonata/expr/operator.ex +++ b/lib/sonata/expr/operator.ex @@ -6,7 +6,14 @@ defimpl Sonata.Postgres, for: Sonata.Expr.Operator do alias Sonata.Postgres, as: PG def to_sql(%{operator: operator, rhs: rhs, lhs: lhs}, opts, idx) do - {parens, opts} = Map.pop(opts, :parens) + {parens, opts} = + case operator do + op when op in ["BETWEEN", "NOT BETWEEN"] -> + {Map.get(opts, :parens), Map.put(opts, :parens, false)} + _ -> + Map.pop(opts, :parens) + end + {lhs, lhs_params, idx} = PG.to_sql(lhs, opts, idx) {rhs, rhs_params, idx} = PG.to_sql(rhs, opts, idx) sql = [lhs, " ", operator, " ", rhs] diff --git a/lib/sonata/expr/unary_operator.ex b/lib/sonata/expr/unary_operator.ex index 8b203a7..c92037a 100644 --- a/lib/sonata/expr/unary_operator.ex +++ b/lib/sonata/expr/unary_operator.ex @@ -1,13 +1,19 @@ defmodule Sonata.Expr.UnaryOperator do - defstruct [:operator, :rhs] + defstruct [:operator, :subject, :inverted] end defimpl Sonata.Postgres, for: Sonata.Expr.UnaryOperator do alias Sonata.Postgres, as: PG - def to_sql(%{operator: operator, rhs: rhs}, opts, idx) do - {rhs, rhs_params, idx} = PG.to_sql(rhs, opts, idx) - {["(", operator, " ", rhs, ")"], rhs_params, idx} + def to_sql(%{operator: operator, subject: subject, inverted: inverted}, opts, idx) do + {subject, params, idx} = PG.to_sql(subject, opts, idx) + sql = + if inverted do + [operator, " ", subject] + else + [subject, " ", operator] + end + {["(", sql, ")"], params, idx} end def on_row(_, _) do diff --git a/lib/sonata/function.ex b/lib/sonata/function.ex index 71b5bdb..1440661 100644 --- a/lib/sonata/function.ex +++ b/lib/sonata/function.ex @@ -4515,10 +4515,6 @@ defmodule(Sonata.Function) do def(length(var1)) do %Sonata.Expr.Call{name: "length", arguments: [var1]} end - @doc("matches LIKE expression") - def(like(var1, var2)) do - %Sonata.Expr.Call{name: "like", arguments: [var1, var2]} - end @doc("convert LIKE pattern to use backslash escapes") def(like_escape(var1, var2)) do %Sonata.Expr.Call{name: "like_escape", arguments: [var1, var2]} @@ -9231,4 +9227,4 @@ defmodule(Sonata.Function) do def(xpath_exists(var1, var2, var3)) do %Sonata.Expr.Call{name: "xpath_exists", arguments: [var1, var2, var3]} end -end +end \ No newline at end of file diff --git a/lib/sonata/manipulation.ex b/lib/sonata/manipulation.ex index 8e5b39b..c62c0be 100644 --- a/lib/sonata/manipulation.ex +++ b/lib/sonata/manipulation.ex @@ -18,10 +18,10 @@ defmodule Sonata.Manipulation do end # TODO: support `INSERT INTO foo (valA, valB) VALUES (SELECT ...)` - def values(insertion = %{rows: rows}, [first | _ ] = values) when is_list(first) do + def values(insertion = %{rows: rows}, [first | _ ] = values) when is_tuple(first) do %{insertion | rows: rows ++ values} end - def values(insertion, values) when is_list(values) do + def values(insertion, values) when is_tuple(values) do values(insertion, [values]) end diff --git a/lib/sonata/manipulation/insertion.ex b/lib/sonata/manipulation/insertion.ex index e29679f..e3d14bb 100644 --- a/lib/sonata/manipulation/insertion.ex +++ b/lib/sonata/manipulation/insertion.ex @@ -67,6 +67,7 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do end def rows(rows, opts, idx) do {rows, params, idx} = Utils.list_to_sql(rows, opts, idx, &(&1), fn(row, opts, idx) -> + row = :erlang.tuple_to_list(row) {row, params, idx} = Utils.list_to_sql(row, opts, idx) {Utils.join(row, ", "), params, idx} end) diff --git a/lib/sonata/query.ex b/lib/sonata/query.ex index b2723cb..dae39ce 100644 --- a/lib/sonata/query.ex +++ b/lib/sonata/query.ex @@ -56,8 +56,8 @@ defmodule Sonata.Query do %{q | from: {from, alias}} end - # TODO - def count(q, {column, alias}) do + def as(field, alias) do + {field, alias} end ## TODO add support for join @@ -76,7 +76,7 @@ defmodule Sonata.Query do def where(q, field, operator, value) do where(q, [{field, operator, value}]) end - def where(q = %{where: where}, [kv | _] = kvs) when is_tuple(kv) do + def where(%{where: where} = q, kvs) when is_list(kvs) do where = Enum.reduce(kvs, where, fn ({k, v}, nil) -> Sonata.Expr.column(k) @@ -84,6 +84,8 @@ defmodule Sonata.Query do ({k, op, v}, nil) -> col = Sonata.Expr.column(k) apply(Sonata.Operator, op, [col, v]) + (clause, nil) -> + clause ({k, v}, acc) -> k = Sonata.Expr.column(k) Sonata.Expr.and(Sonata.Operator.=(k, v), acc) @@ -91,9 +93,15 @@ defmodule Sonata.Query do col = Sonata.Expr.column(k) apply(Sonata.Operator, op, [col, v]) |> Sonata.Expr.and(acc) + (clause, acc) -> + clause + |> Sonata.Expr.and(acc) end) %{q | where: where} end + def where(%{where: _} = q, clause) do + where(q, [clause]) + end def group_by(%{group_by: group_by} = q, c) when is_list(c) do %{q | group_by: group_by ++ c} diff --git a/test/expr_test.exs b/test/expr_test.exs index 8f2c889..08014b8 100644 --- a/test/expr_test.exs +++ b/test/expr_test.exs @@ -32,7 +32,7 @@ defmodule Test.Sonata.Expr do select() |> from("my_first_table") - |> where(is_distinct_from(:first_column, :second_column)) + |> where(:first_column |> is_distinct_from(:second_column)) ] |> assert_snapshot() end @@ -49,7 +49,7 @@ defmodule Test.Sonata.Expr do select() |> from("my_first_table") - |> where(is_not_distinct_from(:first_column, :second_column)) + |> where(:first_column |> is_not_distinct_from(:second_column)) ] |> assert_snapshot() end @@ -59,7 +59,7 @@ defmodule Test.Sonata.Expr do seed([{"foo", 1}, {"bar", nil}]), select() |> from("my_first_table") - |> where(is_null(:second_column)) + |> where(:second_column |> is_null) ] |> assert_snapshot() end @@ -69,7 +69,7 @@ defmodule Test.Sonata.Expr do seed([{"foo", 1}, {"bar", nil}]), select() |> from("my_first_table") - |> where(is_not_null(:second_column)) + |> where(:second_column |> is_not_null) ] |> assert_snapshot() end @@ -86,7 +86,7 @@ defmodule Test.Sonata.Expr do select() |> from("my_first_table") - |> where(is_true(:second_column)) + |> where(:second_column |> is_true) ] |> assert_snapshot() end @@ -103,7 +103,7 @@ defmodule Test.Sonata.Expr do select() |> from("my_first_table") - |> where(is_not_true(:second_column)) + |> where(:second_column |> is_not_true) ] |> assert_snapshot() end @@ -120,7 +120,7 @@ defmodule Test.Sonata.Expr do select() |> from("my_first_table") - |> where(is_false(:second_column)) + |> where(:second_column |> is_false) ] |> assert_snapshot() end @@ -137,7 +137,7 @@ defmodule Test.Sonata.Expr do select() |> from("my_first_table") - |> where(is_not_false(:second_column)) + |> where(:second_column |> is_not_false) ] |> assert_snapshot() end @@ -165,7 +165,7 @@ defmodule Test.Sonata.Expr do seed([{"foo", 1}, {"foobar", 2}, {"FOOBAR", 3}]), select() |> from("my_first_table") - |> where(Expr.like(:first_column, "foo")) + |> where(:first_column |> like("foo")) ] |> assert_snapshot() end @@ -175,7 +175,7 @@ defmodule Test.Sonata.Expr do seed([{"foo", 1}, {"foobar", 2}, {"FOOBAR", 3}]), select() |> from("my_first_table") - |> where(not_like(:first_column, "foo")) + |> where(:first_column |> not_like("foo")) ] |> assert_snapshot() end @@ -185,7 +185,7 @@ defmodule Test.Sonata.Expr do seed([{"foo", 1}, {"foobar", 2}, {"FOOBAR", 3}]), select() |> from("my_first_table") - |> where(ilike(:first_column, "foo")) + |> where(:first_column |> ilike("foo")) ] |> assert_snapshot() end @@ -195,7 +195,7 @@ defmodule Test.Sonata.Expr do seed([{"foobar", 1}, {"FOOBAR", 2}, {"BAZ", 3}]), select() |> from("my_first_table") - |> where(not_ilike(:first_column, "foo")) + |> where(:first_column |> not_ilike("foo")) ] |> assert_snapshot() end @@ -205,7 +205,7 @@ defmodule Test.Sonata.Expr do seed([{"foobar", 1}, {"FOOBAR", 2}, {"BAZ", 3}]), select() |> from("my_first_table") - |> where(similar_to(:first_column, "f")) + |> where(:first_column |> similar_to("f")) ] |> assert_snapshot() end @@ -215,7 +215,7 @@ defmodule Test.Sonata.Expr do seed([{"foobar", 1}, {"FOOBAR", 2}, {"BAZ", 3}]), select() |> from("my_first_table") - |> where(not_similar_to(:first_column, "b")) + |> where(:first_column |> not_similar_to("b")) ] |> assert_snapshot() end diff --git a/test/manipulation_test.exs b/test/manipulation_test.exs index bac6c95..d0ddb0d 100644 --- a/test/manipulation_test.exs +++ b/test/manipulation_test.exs @@ -9,7 +9,7 @@ defmodule Test.Sonata.Manipulation do insert_into("my_first_table") |> fields([:second_column]) - |> values([1]) + |> values({1}) ] |> assert_sql(""" SELECT * FROM my_first_table @@ -23,7 +23,7 @@ defmodule Test.Sonata.Manipulation do |> add_column(:second_column, "integer"), insert_into("my_first_table") - |> values(["foo", 345]) + |> values({"foo", 345}) ] |> assert_sql(""" SELECT * FROM my_first_table @@ -41,7 +41,7 @@ defmodule Test.Sonata.Manipulation do insert_into("my_first_table") |> fields([:first_column, :second_column]) - |> values(["foo", default()]) + |> values({"foo", default()}) ] |> assert_sql(""" SELECT * FROM my_first_table where second_column = 123; @@ -58,7 +58,7 @@ defmodule Test.Sonata.Manipulation do ]), insert_into("my_first_table") - |> values(["foo", 456]) + |> values({"foo", 456}) ] |> assert_sql(""" SELECT * FROM my_first_table where second_column = 456; @@ -72,7 +72,7 @@ defmodule Test.Sonata.Manipulation do |> add_column(:second_column, "integer"), insert_into("my_first_table") - |> values(["foo", 789]) + |> values({"foo", 789}) |> returning([:first_column, {:second_column, :as_this_label}]) ] |> assert_snapshot() @@ -88,10 +88,10 @@ defmodule Test.Sonata.Manipulation do ]), insert_into("my_first_table") - |> values([1, 123]), + |> values({1, 123}), insert_into("my_first_table") - |> values([1, 456]) + |> values({1, 456}) |> on_conflict( :id, do_nothing() @@ -112,10 +112,10 @@ defmodule Test.Sonata.Manipulation do ]), insert_into("my_first_table") - |> values([1, 123]), + |> values({1, 123}), insert_into("my_first_table") - |> values([1, 456]) + |> values({1, 456}) |> on_conflict( :id, do_update() diff --git a/test/query_test.exs b/test/query_test.exs index 77fa08a..437f124 100644 --- a/test/query_test.exs +++ b/test/query_test.exs @@ -38,7 +38,7 @@ defmodule Test.Sonata.Query do select() |> from("my_first_table") - |> Sonata.Query.order_by(:second_column, :desc) + |> order_by(:second_column, :desc) ] |> assert_snapshot() end @@ -60,7 +60,8 @@ defmodule Test.Sonata.Query do seed([{"foo", 1}, {"bar", 1}, {"baz", 2}]), select( - count(:second_column, :label) #SELECT second_column as label + count(:second_column) + |> as(:label) ) |> from("my_first_table") |> where([{:second_column, 1}]) From 789ae451dc7e040454ed23c31d062ab2107be16a Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Thu, 27 Jul 2017 18:24:20 -0600 Subject: [PATCH 26/43] add coveralls --- .travis.yml | 10 ++++++ _snapshots/Test.Sonata.Query.snapshot | 9 +++++- coveralls.json | 6 ++++ lib/sonata/order_by.ex | 8 ++++- lib/sonata/query.ex | 15 +++++++-- mix.exs | 8 +++++ mix.lock | 14 +++++++-- test/query_test.exs | 44 +++++++++++++-------------- test/test_helper.exs | 3 +- 9 files changed, 87 insertions(+), 30 deletions(-) create mode 100644 coveralls.json diff --git a/.travis.yml b/.travis.yml index 26177d8..534d0d9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,27 @@ language: elixir + elixir: - 1.5.0 + otp_release: - 20.0 + env: global: - DATABASE_URL=postgres://postgres:@localhost:5432/sonata + - MIX_ENV=test + services: - postgresql + addons: postgresql: "9.6" + before_script: - psql -c 'create database sonata;' -U postgres + +script: mix coveralls.travis + cache: directories: - _build diff --git a/_snapshots/Test.Sonata.Query.snapshot b/_snapshots/Test.Sonata.Query.snapshot index d38531c..3583237 100644 --- a/_snapshots/Test.Sonata.Query.snapshot +++ b/_snapshots/Test.Sonata.Query.snapshot @@ -6,4 +6,11 @@ "test should find rows with value < 3 row": [%{"first_column" => "foo", "second_column" => 1}, %{"first_column" => "bar", "second_column" => 2}], "test should return count based on a where clause": [%{"label" => 2}], - "test should return count of all rows": [%{"count" => 3}]} \ No newline at end of file + "test should return count from group by clause": [%{"count" => 2, + "second_column" => 1}, %{"count" => 1, "second_column" => 2}], + "test should return count of all rows": [%{"count" => 3}], + "test should return limited result": [%{"first_column" => "foo", + "second_column" => 1}], + "test should reverse order": [%{"first_column" => "baz", + "second_column" => 3}, %{"first_column" => "bar", "second_column" => 2}, + %{"first_column" => "foo", "second_column" => 1}]} \ No newline at end of file diff --git a/coveralls.json b/coveralls.json new file mode 100644 index 0000000..fc3e11b --- /dev/null +++ b/coveralls.json @@ -0,0 +1,6 @@ +{ + "skip_files": [ + "lib/sonata/function.ex", + "lib/sonata/operator.ex" + ] +} diff --git a/lib/sonata/order_by.ex b/lib/sonata/order_by.ex index 4deae11..7a22d99 100644 --- a/lib/sonata/order_by.ex +++ b/lib/sonata/order_by.ex @@ -22,7 +22,13 @@ defimpl Sonata.Postgres, for: Sonata.OrderBy do def to_sql(%{query: query, order_by: e}, opts, idx) do {query, query_params, idx} = PG.to_sql(query, opts, idx) - {e, e_params, idx} = Utils.columns(e, opts, idx) + + {e, e_params, idx} = Utils.list_to_sql(e, opts, idx, &(&1), fn + ({expr, order}, opts, idx) -> + PG.to_sql(expr, opts, idx) + (expr, opts, idx) -> + PG.to_sql(expr, opts, idx) + end) { [query, " ORDER BY ", e], diff --git a/lib/sonata/query.ex b/lib/sonata/query.ex index dae39ce..d706868 100644 --- a/lib/sonata/query.ex +++ b/lib/sonata/query.ex @@ -233,7 +233,7 @@ defimpl Sonata.Postgres, for: Sonata.Query do {nil, [], idx} end defp group_by(columns, opts, idx) do - {columns, params} = Utils.columns(columns, opts, idx) + {columns, params, idx} = Utils.columns(columns, opts, idx) {["GROUP BY ", columns], params, idx} end @@ -249,10 +249,19 @@ defimpl Sonata.Postgres, for: Sonata.Query do {nil, [], idx} end defp order_by(columns, opts, idx) do - {columns, params, idx} = Utils.columns(columns, opts, idx) - {["ORDER BY ", columns], params, idx} + {columns, params, idx} = Utils.list_to_sql(columns, opts, idx, &(&1), fn + ({expr, order}, opts, idx) -> + {sql, params, idx} = PG.to_sql(expr, opts, idx) + {[sql, order_by_op(order)], params, idx} + (expr, opts, idx) -> + PG.to_sql(expr, opts, idx) + end) + {["ORDER BY ", Utils.join(columns, ", ")], params, idx} end + defp order_by_op(:asc), do: " ASC" + defp order_by_op(:desc), do: " DESC" + defp limit(limit, _, idx) when limit in [:all, nil] do {nil, [], idx} end diff --git a/mix.exs b/mix.exs index 6c8b723..1fcee6d 100644 --- a/mix.exs +++ b/mix.exs @@ -7,6 +7,13 @@ defmodule Sonata.Mixfile do elixir: "~> 1.2", build_embedded: Mix.env == :prod, start_permanent: Mix.env == :prod, + test_coverage: [tool: ExCoveralls], + preferred_cli_env: [ + "coveralls": :test, + "coveralls.detail": :test, + "coveralls.post": :test, + "coveralls.html": :test, + ], deps: deps()] end @@ -17,6 +24,7 @@ defmodule Sonata.Mixfile do defp deps do [{:csv, "~> 2.0", only: :dev}, {:ecto, "~> 2.1.4", only: :test}, + {:excoveralls, "~> 0.7.1"}, {:mix_test_watch, "~> 0.4.1", only: :dev}, {:postgrex, "~> 0.13.3", only: :test},] end diff --git a/mix.lock b/mix.lock index d6436d7..79e7dca 100644 --- a/mix.lock +++ b/mix.lock @@ -1,11 +1,21 @@ -%{"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"}, +%{"certifi": {:hex, :certifi, "1.2.1", "c3904f192bd5284e5b13f20db3ceac9626e14eeacfbb492e19583cf0e37b22be", [], [], "hexpm"}, + "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"}, "csv": {:hex, :csv, "2.0.0", "c66fea89ba7862b94901baf0871285e9b73cad89c5fdb57a6386d2adcf29593e", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm"}, "db_connection": {:hex, :db_connection, "1.1.2", "2865c2a4bae0714e2213a0ce60a1b12d76a6efba0c51fbda59c9ab8d1accc7a8", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, "decimal": {:hex, :decimal, "1.4.0", "fac965ce71a46aab53d3a6ce45662806bdd708a4a95a65cde8a12eb0124a1333", [:mix], [], "hexpm"}, "ecto": {:hex, :ecto, "2.1.4", "d1ba932813ec0e0d9db481ef2c17777f1cefb11fc90fa7c142ff354972dfba7e", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, "epgsql": {:hex, :epgsql, "3.3.0", "974a578340e52012cbab820ce756e7ed1df1baf0110c59a6753d8337a2cf9454", [], [], "hexpm"}, + "excoveralls": {:hex, :excoveralls, "0.7.1", "3dd659db19c290692b5e2c4a2365ae6d4488091a1ba58f62dcbdaa0c03da5491", [], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, + "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, "fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], [], "hexpm"}, + "hackney": {:hex, :hackney, "1.8.6", "21a725db3569b3fb11a6af17d5c5f654052ce9624219f1317e8639183de4a423", [], [{:certifi, "1.2.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.0.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, + "idna": {:hex, :idna, "5.0.2", "ac203208ada855d95dc591a764b6e87259cb0e2a364218f215ad662daa8cd6b4", [], [{:unicode_util_compat, "0.2.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, + "jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [], [], "hexpm"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [], [], "hexpm"}, + "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [], [], "hexpm"}, "mix_test_watch": {:hex, :mix_test_watch, "0.4.1", "a98a84c795623f1ba020324f4354cf30e7120ba4dab65f9c2ae300f830a25f75", [:mix], [{:fs, "~> 0.9.1", [hex: :fs, repo: "hexpm", optional: false]}], "hexpm"}, "parallel_stream": {:hex, :parallel_stream, "1.0.5", "4c78d3e675f9eff885cbe252c89a8fc1d2fb803c0d03a914281e587834e09431", [:mix], [], "hexpm"}, "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"}, - "postgrex": {:hex, :postgrex, "0.13.3", "c277cfb2a9c5034d445a722494c13359e361d344ef6f25d604c2353185682bfc", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"}} + "postgrex": {:hex, :postgrex, "0.13.3", "c277cfb2a9c5034d445a722494c13359e361d344ef6f25d604c2353185682bfc", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [], [], "hexpm"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.2.0", "dbbccf6781821b1c0701845eaf966c9b6d83d7c3bfc65ca2b78b88b8678bfa35", [], [], "hexpm"}} diff --git a/test/query_test.exs b/test/query_test.exs index 437f124..2e3c2c5 100644 --- a/test/query_test.exs +++ b/test/query_test.exs @@ -17,7 +17,7 @@ defmodule Test.Sonata.Query do select() |> from("my_first_table") - |> where(:first_column, :=, "foo") + |> where(op(:first_column = "foo")) ] |> assert_snapshot() end @@ -27,7 +27,7 @@ defmodule Test.Sonata.Query do seed(), select() |> from("my_first_table") - |> where(:second_column, :<, 3) + |> where(op(:second_column < 3)) ] |> assert_snapshot() end @@ -64,7 +64,7 @@ defmodule Test.Sonata.Query do |> as(:label) ) |> from("my_first_table") - |> where([{:second_column, 1}]) + |> where(second_column: 1) ] |> assert_snapshot() end @@ -75,7 +75,7 @@ defmodule Test.Sonata.Query do select([ count(:first_column), - :first_column + :second_column ]) |> from("my_first_table") |> group_by(:second_column) @@ -89,29 +89,29 @@ defmodule Test.Sonata.Query do select() |> from("my_first_table") - |> where([{:first_column, 1}]) + |> where(second_column: 1) |> limit(1) ] |> assert_snapshot() end - test "should return joined tables" do - [ - seed(), - create_table("my_second_table") - |> add_column(:label, "text") - |> add_column(:id, "integer"), - - insert_into("my_second_table") - |> values([{"label 1", 1}, {"label 2", 2}]), - - select() - |> from("my_first_table") - |> join("my_second_table", {{"my_first_table", :second_column}, :=, {"my_second_table", :id}}) - |> where({{"my_second_table", :id}, :=, 1}) - ] - |> assert_snapshot() - end + # test "should return joined tables" do + # [ + # seed(), + # create_table("my_second_table") + # |> add_column(:label, "text") + # |> add_column(:id, "integer"), + + # insert_into("my_second_table") + # |> values([{"label 1", 1}, {"label 2", 2}]), + + # select() + # |> from("my_first_table") + # |> join("my_second_table", {{"my_first_table", :second_column}, :=, {"my_second_table", :id}}) + # |> where({{"my_second_table", :id}, :=, 1}) + # ] + # |> assert_snapshot() + # end def seed() do seed([{"foo", 1}, {"bar", 2}, {"baz", 3}]) diff --git a/test/test_helper.exs b/test/test_helper.exs index 67a6895..501e15d 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -134,6 +134,7 @@ defmodule Test.Sonata do end def query!(struct) do {sql, params, on_row} = Sonata.to_sql(struct) + sql = :erlang.iolist_to_binary(sql) Logger.debug(sql) @@ -149,7 +150,7 @@ defmodule Test.Sonata do nil -> :ok snapshot -> - assert result == snapshot + assert snapshot == result end send(module, {:add_snapshot, {test_name, result}}) From 43b4337b6711fd372f6bd7170d047f6dbff20ad2 Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Thu, 27 Jul 2017 18:37:03 -0600 Subject: [PATCH 27/43] fix some warnings --- lib/sonata/definition/do_nothing.ex | 2 -- lib/sonata/definition/do_update.ex | 4 ++++ lib/sonata/definition/on_conflict.ex | 4 ++++ lib/sonata/drop_table.ex | 2 +- lib/sonata/expr/default.ex | 4 ++++ lib/sonata/expr/value.ex | 4 ++++ lib/sonata/manipulation/insertion.ex | 2 +- 7 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/sonata/definition/do_nothing.ex b/lib/sonata/definition/do_nothing.ex index 9736391..ced0680 100644 --- a/lib/sonata/definition/do_nothing.ex +++ b/lib/sonata/definition/do_nothing.ex @@ -3,8 +3,6 @@ defmodule Sonata.Manipulation.DoNothing do end defimpl Sonata.Postgres, for: Sonata.Manipulation.DoNothing do - alias Sonata.Postgres.Utils - def to_sql(_, _, idx) do {"DO NOTHING", [], idx} end diff --git a/lib/sonata/definition/do_update.ex b/lib/sonata/definition/do_update.ex index 7ec0d8d..e62fa0a 100644 --- a/lib/sonata/definition/do_update.ex +++ b/lib/sonata/definition/do_update.ex @@ -21,6 +21,10 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.DoUpdate do } end + def on_row(_, _) do + nil + end + defp sets([], _, idx) do {nil, [], idx} end diff --git a/lib/sonata/definition/on_conflict.ex b/lib/sonata/definition/on_conflict.ex index 164205e..20d3226 100644 --- a/lib/sonata/definition/on_conflict.ex +++ b/lib/sonata/definition/on_conflict.ex @@ -15,4 +15,8 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.OnConflict do action, ], Stream.concat(t_params, a_params), idx} end + + def on_row(_, _) do + nil + end end diff --git a/lib/sonata/drop_table.ex b/lib/sonata/drop_table.ex index 0996bb5..dec183d 100644 --- a/lib/sonata/drop_table.ex +++ b/lib/sonata/drop_table.ex @@ -15,7 +15,7 @@ defimpl Sonata.Postgres, for: Sonata.DropTable do alias Sonata.Postgres, as: PG alias PG.Utils - def to_sql(%{table: table, if_exists: if_exists}, opts, idx) do + def to_sql(%{table: table, if_exists: if_exists}, _, idx) do if_exists = if_exists(if_exists) { ["DROP TABLE ", if_exists, Utils.escape(table), ";"], diff --git a/lib/sonata/expr/default.ex b/lib/sonata/expr/default.ex index 35b76a9..37d2cc0 100644 --- a/lib/sonata/expr/default.ex +++ b/lib/sonata/expr/default.ex @@ -6,4 +6,8 @@ defimpl Sonata.Postgres, for: Sonata.Expr.Default do def to_sql(_, _, idx) do {"DEFAULT", [], idx} end + + def on_row(_, _) do + nil + end end diff --git a/lib/sonata/expr/value.ex b/lib/sonata/expr/value.ex index ef94308..5e8057d 100644 --- a/lib/sonata/expr/value.ex +++ b/lib/sonata/expr/value.ex @@ -6,4 +6,8 @@ defimpl Sonata.Postgres, for: Sonata.Expr.Value do def to_sql(%{value: value}, _, idx) do {"$#{idx}", [value], idx + 1} end + + def on_row(_, _) do + nil + end end diff --git a/lib/sonata/manipulation/insertion.ex b/lib/sonata/manipulation/insertion.ex index e3d14bb..e101851 100644 --- a/lib/sonata/manipulation/insertion.ex +++ b/lib/sonata/manipulation/insertion.ex @@ -55,7 +55,7 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do {["(", Utils.join(fields, ", "), ")"], params, idx} end - def default_values(true, opts, idx) do + def default_values(true, _, idx) do {"DEFAULT VALUES", [], idx} end def default_values(_, _, idx) do From 4fb5edd172677acb8619eeb52ba0cbe50beb50bf Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Fri, 28 Jul 2017 13:41:12 -0600 Subject: [PATCH 28/43] alter table tests 1st pass --- lib/sonata/alter_table.ex | 41 ++++++++ test/alter_table_test.exs | 212 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 253 insertions(+) create mode 100644 test/alter_table_test.exs diff --git a/lib/sonata/alter_table.ex b/lib/sonata/alter_table.ex index 080588c..dad2830 100644 --- a/lib/sonata/alter_table.ex +++ b/lib/sonata/alter_table.ex @@ -4,4 +4,45 @@ defmodule Sonata.AlterTable do def alter_table(table) do %__MODULE__{table: table} end + + def rename_column(q, old_name, new_name) do + + end + + def rename_to(q, new_table_name) do + + end + + def drop_table(q, table) do + + end + + def drop_column(q, column_name) do + + end + + def alter_column(q, column) do + + end + + # COLUMN FUNCTIONS + def set_default(column, default) do + + end + + def drop_default(column) do + + end + + def set_data_type(column, data_type) do + + end + + def set_not_null(column) do + + end + + def drop_not_null(column) do + + end end diff --git a/test/alter_table_test.exs b/test/alter_table_test.exs new file mode 100644 index 0000000..d9d1b1b --- /dev/null +++ b/test/alter_table_test.exs @@ -0,0 +1,212 @@ +defmodule Test.Sonata.AlterTable do + use Test.Sonata + + test "rename column" do + [ + seed(), + + alter_table(:my_first_table) + |> rename_column(:first_column, :new_first_column) + ] + |> assert_snapshot() + end + + test "rename table" do + [ + seed(), + alter_table(:my_first_table) + |> rename_to(:my_new_first_table) + ] + |> assert_snapshot() + end + + # test "alter schema" do + # [ + # seed(), + # raw_sql("CREATE SCHEMA new_schema;"), + # alter_table(:my_first_table) + # |> set_schema(:new_schema) + # ] + # |> assert_snapshot() # does this check the table's schema? + # end + + test "add column" do + [ + seed(), + alter_table(:my_first_table) + |> add_column(:third_column, "text") + ] + |> assert_snapshot() + end + + test "drop column that exists" do + [ + seed(), + alter_table(:my_first_table) + |> drop_column(:first_column) + ] + |> assert_snapshot() + end + + test "fail to drop column that doesn't exist" do + [ + seed(), + alter_table(:my_first_table) + |> drop_column(:third_column) + ] + |> assert_snapshot() + end + + test "success drop column that exists with `IF EXISTS`" do + [ + seed(), + alter_table(:my_first_table) + |> drop_column(:first_column) + |> if_exists() + ] + |> assert_snapshot() + end + + test "success drop column that doesn't exist with `IF EXISTS`" do + [ + seed(), + alter_table(:my_first_table) + |> drop_column(:third_column) + |> if_exists() + ] + |> assert_snapshot() + end + + # test "drop column and dependent objects (`CASCADE`)" do + # [ + # seed(), + # create_view("child") + # |> add_column( + # column(:child_column, "text") + # |> as( + # select(:first_column) + # from(:my_first_table) + # ) + # ), + + # alter_table(:my_first_table) + # |> drop_column(:first_column) + # |> cascade() + # ] + # |> assert_snapshot() + # end + + # test "restrict drop column with dependent objects (`RESTRICT`)" + # [ + # seed(), + # create_view("child") + # |> add_column( + # column(:child_column, "text") + # |> as( + # select(:first_column) + # from(:my_first_table) + # ) + # ), + + # alter_table(:my_first_table) + # |> drop_column(:first_column) + # |> restrict() + # ] + # |> assert_snapshot() + # end + + test "alter column data type" do + [ + seed(), + alter_table(:my_first_table) + |> alter_column( + column(:first_column) + |> set_data_type("varchar") + ) + ] + |> assert_snapshot() + end + + test "alter column default" do + [ + seed(), + alter_table(:my_first_table) + |> alter_column( + column(:first_column) + |> set_default("foobar") + ) + ] + |> assert_snapshot() + end + + test "remove column default" do + [ + create_table(:my_first_table) + |> add_column([ + column(:first_column, "text") + |> default("foobar") + ]), + + alter_table(:my_first_table) + |> alter_column( + column(:first_column) + |> drop_default() + ) + ] + |> assert_snapshot() + end + + test "set column not_null" do + [ + seed(), + alter_table(:my_first_table) + |> alter_column( + column(:first_column) + |> set_not_null() + ) + ] + |> assert_snapshot() + end + + test "drop column not_null" do + [ + create_table(:my_first_table) + |> add_column([ + column(:first_column, "text") + |> not_null() + ]), + + alter_table(:my_first_table) + |> alter_column( + column(:first_column) + |> drop_not_null() + ) + ] + |> assert_snapshot() + end + + # test "ALTER COLUMN column SET STATISTICS integer" do + # end + + # test "ALTER [ COLUMN ] column SET ( attribute_option = value [, ... ] )" do + # end + + # test "ALTER [ COLUMN ] column RESET ( attribute_option [, ... ] )" do + # end + + # test "ALTER [ COLUMN ] column SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }" do + # end + + + + + + def seed() do + [ + create_table(:my_first_table) + |> add_column(:first_column, "text") + |> add_column(:second_column, "integer") + ] + |> assert_snapshot() + end +end From c39c1c92d165f8def9f174f4ca3d1e70eeb2d2d7 Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Fri, 28 Jul 2017 13:55:30 -0600 Subject: [PATCH 29/43] implement join --- _snapshots/Test.Sonata.AlterTable.snapshot | 9 +++ _snapshots/Test.Sonata.Query.snapshot | 2 + lib/sonata/alter_table.ex | 34 ++++++------ lib/sonata/manipulation/insertion.ex | 2 +- lib/sonata/postgres.ex | 17 ++++++ lib/sonata/query.ex | 43 +++++++++++---- lib/sonata/query/join.ex | 25 +++++++++ test/alter_table_test.exs | 9 +-- test/drop_table_test.exs | 12 ++-- test/expr_test.exs | 64 +++++++++++----------- test/manipulation_test.exs | 32 +++++------ test/query_test.exs | 51 ++++++++--------- 12 files changed, 186 insertions(+), 114 deletions(-) create mode 100644 _snapshots/Test.Sonata.AlterTable.snapshot create mode 100644 lib/sonata/query/join.ex diff --git a/_snapshots/Test.Sonata.AlterTable.snapshot b/_snapshots/Test.Sonata.AlterTable.snapshot new file mode 100644 index 0000000..5bdfbde --- /dev/null +++ b/_snapshots/Test.Sonata.AlterTable.snapshot @@ -0,0 +1,9 @@ +%{"test add column": :create_table, + "test alter column data type": :create_table, + "test alter column default": :create_table, + "test drop column that exists": :create_table, + "test fail to drop column that doesn't exist": :create_table, + "test rename column": :create_table, "test rename table": :create_table, + "test set column not_null": :create_table, + "test success drop column that doesn't exist with `IF EXISTS`": :create_table, + "test success drop column that exists with `IF EXISTS`": :create_table} \ No newline at end of file diff --git a/_snapshots/Test.Sonata.Query.snapshot b/_snapshots/Test.Sonata.Query.snapshot index 3583237..826e0d6 100644 --- a/_snapshots/Test.Sonata.Query.snapshot +++ b/_snapshots/Test.Sonata.Query.snapshot @@ -9,6 +9,8 @@ "test should return count from group by clause": [%{"count" => 2, "second_column" => 1}, %{"count" => 1, "second_column" => 2}], "test should return count of all rows": [%{"count" => 3}], + "test should return joined tables": [%{"first_column" => "foo", "id" => 1, + "label" => "label 1", "second_column" => 1}], "test should return limited result": [%{"first_column" => "foo", "second_column" => 1}], "test should reverse order": [%{"first_column" => "baz", diff --git a/lib/sonata/alter_table.ex b/lib/sonata/alter_table.ex index dad2830..75e22e2 100644 --- a/lib/sonata/alter_table.ex +++ b/lib/sonata/alter_table.ex @@ -1,48 +1,50 @@ defmodule Sonata.AlterTable do - defstruct [table: nil] + defstruct [table: nil, + add_columns: [], + drop_columns: []] def alter_table(table) do %__MODULE__{table: table} end - def rename_column(q, old_name, new_name) do - + def rename_column(alter, old_name, new_name) do + alter end - def rename_to(q, new_table_name) do - + def rename_to(alter, new_table_name) do + alter end - def drop_table(q, table) do - + def drop_table(alter, table) do + alter end - def drop_column(q, column_name) do - + def drop_column(alter, column_name) do + alter end - def alter_column(q, column) do - + def alter_column(alter, column) do + alter end # COLUMN FUNCTIONS def set_default(column, default) do - + column end def drop_default(column) do - + column end def set_data_type(column, data_type) do - + column end def set_not_null(column) do - + column end def drop_not_null(column) do - + column end end diff --git a/lib/sonata/manipulation/insertion.ex b/lib/sonata/manipulation/insertion.ex index e101851..c06d502 100644 --- a/lib/sonata/manipulation/insertion.ex +++ b/lib/sonata/manipulation/insertion.ex @@ -43,7 +43,7 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do defp table(table, _, idx) when table in [nil, false, ""] do {nil, [], idx} end - defp table(table, opts, idx) when is_binary(table) do + defp table(table, opts, idx) when is_binary(table) or is_atom(table) do {Utils.escape(table), opts, idx} end diff --git a/lib/sonata/postgres.ex b/lib/sonata/postgres.ex index 001f8d0..7cea339 100644 --- a/lib/sonata/postgres.ex +++ b/lib/sonata/postgres.ex @@ -39,3 +39,20 @@ defimpl Sonata.Postgres, for: [Integer, Float, Atom, BitString] do nil end end + +defimpl Sonata.Postgres, for: Tuple do + alias Sonata.Postgres, as: PG + alias PG.Utils + + def to_sql(value, opts, idx) do + {sql, params, idx} = + value + |> :erlang.tuple_to_list() + |> Utils.list_to_sql(opts, idx) + {Utils.join(sql, "."), params, idx} + end + + def on_row(_, _) do + nil + end +end diff --git a/lib/sonata/query.ex b/lib/sonata/query.ex index d706868..aac3ee6 100644 --- a/lib/sonata/query.ex +++ b/lib/sonata/query.ex @@ -60,19 +60,28 @@ defmodule Sonata.Query do {field, alias} end - ## TODO add support for join - def join(q, table, on) do - + joins = [ + :join, + :inner_join, + :left_outer_join, + :right_outer_join, + :full_outer_join, + :cross_join, + :natural_join, + ] + + for join <- joins do + command = join |> to_string() |> String.upcase() |> String.replace("_", " ") + def unquote(join)(%{joins: joins} = q, table, on) do + join = %__MODULE__.Join{ + command: unquote(command), + table: table, + on: on, + } + %{q | joins: [join | joins]} + end end - #def join() -> inner_join() - #def inner_join() - #def left_outer_join() - #def right_outer_join() - #def full_outer_join() - #def cross_join() - #def natural_join() - def where(q, field, operator, value) do where(q, [{field, operator, value}]) end @@ -151,6 +160,7 @@ defimpl Sonata.Postgres, for: Sonata.Query do {distinct, distinct_params, idx} = distinct(query.distinct, opts, idx) {columns, column_params, idx} = Utils.columns(query.columns, opts, idx) {from, from_params, idx} = from(query.from, opts, idx) + {joins, joins_params, idx} = joins(query.joins, opts, idx) {where, where_params, idx} = where(query.where, opts, idx) {group_by, group_by_params, idx} = group_by(query.group_by, opts, idx) {having, having_params, idx} = having(query.having, opts, idx) @@ -164,6 +174,7 @@ defimpl Sonata.Postgres, for: Sonata.Query do distinct, columns, from, + joins, where, group_by, having, @@ -176,6 +187,7 @@ defimpl Sonata.Postgres, for: Sonata.Query do distinct_params, column_params, from_params, + joins_params, where_params, group_by_params, having_params, @@ -209,7 +221,7 @@ defimpl Sonata.Postgres, for: Sonata.Query do defp from(nil, _, idx) do {nil, [], idx} end - defp from(from, _, idx) when is_binary(from) do + defp from(from, _, idx) when is_binary(from) or is_atom(from) do {["FROM ", Utils.escape(from)], [], idx} end defp from({from, alias}, opts, idx) do @@ -221,6 +233,13 @@ defimpl Sonata.Postgres, for: Sonata.Query do {["FROM (", from, ")"], params, idx} end + defp joins([], _, idx) do + {nil, [], idx} + end + defp joins(joins, opts, idx) do + Utils.list_to_sql(joins, opts, idx) + end + defp where(nil, _, idx) do {nil, [], idx} end diff --git a/lib/sonata/query/join.ex b/lib/sonata/query/join.ex new file mode 100644 index 0000000..3da0f09 --- /dev/null +++ b/lib/sonata/query/join.ex @@ -0,0 +1,25 @@ +defmodule Sonata.Query.Join do + defstruct [:command, :table, :on,] +end + +defimpl Sonata.Postgres, for: Sonata.Query.Join do + alias Sonata.Postgres, as: PG + alias PG.Utils + + def to_sql(%{command: command, table: table, on: on}, opts, idx) do + {on, params, idx} = PG.to_sql(on, opts, idx) + + { + Utils.join([ + command, + Utils.escape(table), + "ON", + on + ], " "), + + params, + + idx + } + end +end diff --git a/test/alter_table_test.exs b/test/alter_table_test.exs index d9d1b1b..d2ef8a1 100644 --- a/test/alter_table_test.exs +++ b/test/alter_table_test.exs @@ -202,11 +202,8 @@ defmodule Test.Sonata.AlterTable do def seed() do - [ - create_table(:my_first_table) - |> add_column(:first_column, "text") - |> add_column(:second_column, "integer") - ] - |> assert_snapshot() + create_table(:my_first_table) + |> add_column(:first_column, "text") + |> add_column(:second_column, "integer") end end diff --git a/test/drop_table_test.exs b/test/drop_table_test.exs index e06239a..76def24 100644 --- a/test/drop_table_test.exs +++ b/test/drop_table_test.exs @@ -3,11 +3,11 @@ defmodule Test.Sonata.DropTable do test "should drop table" do [ - create_table("my_first_table") + create_table(:my_first_table) |> add_column(:first_column, "text") |> add_column(:second_column, "integer"), - drop_table("my_first_table"), + drop_table(:my_first_table), ] |> assert_sql_error(""" SELECT * FROM my_first_table @@ -15,24 +15,24 @@ defmodule Test.Sonata.DropTable do end test "should successfully drop table, whether it exists or not, pt.1" do - drop_table("doesnt_exist") + drop_table(:doesnt_exist) |> if_exists() |> assert_snapshot() end test "should successfully drop table, whether it exists or not, pt.2" do [ - create_table("exists") + create_table(:exists) |> add_column(:first_column, "text"), - drop_table("exists") + drop_table(:exists) |> if_exists() ] |> assert_snapshot() end test "should fail to drop table" do - drop_table("doesnt_exist") + drop_table(:doesnt_exist) |> assert_sql_error(:undefined_table) end diff --git a/test/expr_test.exs b/test/expr_test.exs index 08014b8..f274497 100644 --- a/test/expr_test.exs +++ b/test/expr_test.exs @@ -5,7 +5,7 @@ defmodule Test.Sonata.Expr do # [ # seed([{"foo", 1}, {"foo", 2}, {"foo", 3}]), # select() - # |> from("my_first_table") + # |> from(:my_first_table) # |> where(Expr.and({:first_column, :=, "foo"}, {:second_column, :>, 1})) # ] # end @@ -14,7 +14,7 @@ defmodule Test.Sonata.Expr do [ seed([{"foo", 2}, {"bar", 3}, {"baz", 4}]), select() - |> from("my_first_table") + |> from(:my_first_table) |> where(:second_column |> between(2, 4)) ] |> assert_snapshot() @@ -22,16 +22,16 @@ defmodule Test.Sonata.Expr do test "IS_DISTINCT_FROM" do [ - create_table("my_first_table") + create_table(:my_first_table) |> add_column(:first_column, "text") |> add_column(:second_column, "text"), - insert_into("my_first_table") + insert_into(:my_first_table) |> fields([:first_column, :second_column]) |> values([{"foo", "foo"}, {"bar", "foo"}, {"bar", "bar"}]), select() - |> from("my_first_table") + |> from(:my_first_table) |> where(:first_column |> is_distinct_from(:second_column)) ] |> assert_snapshot() @@ -39,16 +39,16 @@ defmodule Test.Sonata.Expr do test "IS_NOT_DISTINCT_FROM" do [ - create_table("my_first_table") + create_table(:my_first_table) |> add_column(:first_column, "text") |> add_column(:second_column, "text"), - insert_into("my_first_table") + insert_into(:my_first_table) |> fields([:first_column, :second_column]) |> values([{"foo", "foo"}, {"bar", "foo"}, {"bar", "bar"}]), select() - |> from("my_first_table") + |> from(:my_first_table) |> where(:first_column |> is_not_distinct_from(:second_column)) ] |> assert_snapshot() @@ -58,7 +58,7 @@ defmodule Test.Sonata.Expr do [ seed([{"foo", 1}, {"bar", nil}]), select() - |> from("my_first_table") + |> from(:my_first_table) |> where(:second_column |> is_null) ] |> assert_snapshot() @@ -68,7 +68,7 @@ defmodule Test.Sonata.Expr do [ seed([{"foo", 1}, {"bar", nil}]), select() - |> from("my_first_table") + |> from(:my_first_table) |> where(:second_column |> is_not_null) ] |> assert_snapshot() @@ -76,16 +76,16 @@ defmodule Test.Sonata.Expr do test "IS_TRUE" do [ - create_table("my_first_table") + create_table(:my_first_table) |> add_column(:first_column, "text") |> add_column(:second_column, "bool"), - insert_into("my_first_table") + insert_into(:my_first_table) |> fields([:first_column, :second_column]) |> values([{"foo", true}, {"bar", false}, {"baz", nil}]), select() - |> from("my_first_table") + |> from(:my_first_table) |> where(:second_column |> is_true) ] |> assert_snapshot() @@ -93,16 +93,16 @@ defmodule Test.Sonata.Expr do test "IS_NOT_TRUE" do [ - create_table("my_first_table") + create_table(:my_first_table) |> add_column(:first_column, "text") |> add_column(:second_column, "bool"), - insert_into("my_first_table") + insert_into(:my_first_table) |> fields([:first_column, :second_column]) |> values([{"foo", true}, {"bar", false}, {"baz", nil}]), select() - |> from("my_first_table") + |> from(:my_first_table) |> where(:second_column |> is_not_true) ] |> assert_snapshot() @@ -110,16 +110,16 @@ defmodule Test.Sonata.Expr do test "IS_FALSE" do [ - create_table("my_first_table") + create_table(:my_first_table) |> add_column(:first_column, "text") |> add_column(:second_column, "bool"), - insert_into("my_first_table") + insert_into(:my_first_table) |> fields([:first_column, :second_column]) |> values([{"foo", true}, {"bar", false}, {"baz", nil}]), select() - |> from("my_first_table") + |> from(:my_first_table) |> where(:second_column |> is_false) ] |> assert_snapshot() @@ -127,16 +127,16 @@ defmodule Test.Sonata.Expr do test "IS_NOT_FALSE" do [ - create_table("my_first_table") + create_table(:my_first_table) |> add_column(:first_column, "text") |> add_column(:second_column, "bool"), - insert_into("my_first_table") + insert_into(:my_first_table) |> fields([:first_column, :second_column]) |> values([{"foo", true}, {"bar", false}, {"baz", nil}]), select() - |> from("my_first_table") + |> from(:my_first_table) |> where(:second_column |> is_not_false) ] |> assert_snapshot() @@ -146,7 +146,7 @@ defmodule Test.Sonata.Expr do # [ # seed(), # select() - # |> from("my_first_table") + # |> from(:my_first_table) # |> where(is_unknown()) # ] # end @@ -155,7 +155,7 @@ defmodule Test.Sonata.Expr do # [ # seed(), # select() - # |> from("my_first_table") + # |> from(:my_first_table) # |> where(is_not_unknown()) # ] # end @@ -164,7 +164,7 @@ defmodule Test.Sonata.Expr do [ seed([{"foo", 1}, {"foobar", 2}, {"FOOBAR", 3}]), select() - |> from("my_first_table") + |> from(:my_first_table) |> where(:first_column |> like("foo")) ] |> assert_snapshot() @@ -174,7 +174,7 @@ defmodule Test.Sonata.Expr do [ seed([{"foo", 1}, {"foobar", 2}, {"FOOBAR", 3}]), select() - |> from("my_first_table") + |> from(:my_first_table) |> where(:first_column |> not_like("foo")) ] |> assert_snapshot() @@ -184,7 +184,7 @@ defmodule Test.Sonata.Expr do [ seed([{"foo", 1}, {"foobar", 2}, {"FOOBAR", 3}]), select() - |> from("my_first_table") + |> from(:my_first_table) |> where(:first_column |> ilike("foo")) ] |> assert_snapshot() @@ -194,7 +194,7 @@ defmodule Test.Sonata.Expr do [ seed([{"foobar", 1}, {"FOOBAR", 2}, {"BAZ", 3}]), select() - |> from("my_first_table") + |> from(:my_first_table) |> where(:first_column |> not_ilike("foo")) ] |> assert_snapshot() @@ -204,7 +204,7 @@ defmodule Test.Sonata.Expr do [ seed([{"foobar", 1}, {"FOOBAR", 2}, {"BAZ", 3}]), select() - |> from("my_first_table") + |> from(:my_first_table) |> where(:first_column |> similar_to("f")) ] |> assert_snapshot() @@ -214,7 +214,7 @@ defmodule Test.Sonata.Expr do [ seed([{"foobar", 1}, {"FOOBAR", 2}, {"BAZ", 3}]), select() - |> from("my_first_table") + |> from(:my_first_table) |> where(:first_column |> not_similar_to("b")) ] |> assert_snapshot() @@ -226,11 +226,11 @@ defmodule Test.Sonata.Expr do def seed(values) do [ - create_table("my_first_table") + create_table(:my_first_table) |> add_column(:first_column, "text") |> add_column(:second_column, "integer"), - insert_into("my_first_table") + insert_into(:my_first_table) |> fields([:first_column, :second_column]) |> values(values), ] diff --git a/test/manipulation_test.exs b/test/manipulation_test.exs index d0ddb0d..c26b9fe 100644 --- a/test/manipulation_test.exs +++ b/test/manipulation_test.exs @@ -3,11 +3,11 @@ defmodule Test.Sonata.Manipulation do test "should insert row" do [ - create_table("my_first_table") + create_table(:my_first_table) |> add_column(:first_column, "text") |> add_column(:second_column, "integer"), - insert_into("my_first_table") + insert_into(:my_first_table) |> fields([:second_column]) |> values({1}) ] @@ -18,11 +18,11 @@ defmodule Test.Sonata.Manipulation do test "should insert row without specifying columns" do [ - create_table("my_first_table") + create_table(:my_first_table) |> add_column(:first_column, "text") |> add_column(:second_column, "integer"), - insert_into("my_first_table") + insert_into(:my_first_table) |> values({"foo", 345}) ] |> assert_sql(""" @@ -32,14 +32,14 @@ defmodule Test.Sonata.Manipulation do test "should insert with defaults" do [ - create_table("my_first_table") + create_table(:my_first_table) |> add_column([ column(:first_column, "text"), column(:second_column, "integer") |> default(123) ]), - insert_into("my_first_table") + insert_into(:my_first_table) |> fields([:first_column, :second_column]) |> values({"foo", default()}) ] @@ -50,14 +50,14 @@ defmodule Test.Sonata.Manipulation do test "should insert value other than default" do [ - create_table("my_first_table") + create_table(:my_first_table) |> add_column([ column(:first_column, "text"), column(:second_column, "integer") |> default(123) ]), - insert_into("my_first_table") + insert_into(:my_first_table) |> values({"foo", 456}) ] |> assert_sql(""" @@ -67,11 +67,11 @@ defmodule Test.Sonata.Manipulation do test "should return value after insert" do [ - create_table("my_first_table") + create_table(:my_first_table) |> add_column(:first_column, "text") |> add_column(:second_column, "integer"), - insert_into("my_first_table") + insert_into(:my_first_table) |> values({"foo", 789}) |> returning([:first_column, {:second_column, :as_this_label}]) ] @@ -80,17 +80,17 @@ defmodule Test.Sonata.Manipulation do test "should do nothing on conflict" do [ - create_table("my_first_table") + create_table(:my_first_table) |> add_column([ column(:id, "serial") |> unique(), column(:value, "integer") ]), - insert_into("my_first_table") + insert_into(:my_first_table) |> values({1, 123}), - insert_into("my_first_table") + insert_into(:my_first_table) |> values({1, 456}) |> on_conflict( :id, @@ -104,17 +104,17 @@ defmodule Test.Sonata.Manipulation do test "should update on conflict" do [ - create_table("my_first_table") + create_table(:my_first_table) |> add_column([ column(:id, "serial") |> unique(), column(:value, "integer") ]), - insert_into("my_first_table") + insert_into(:my_first_table) |> values({1, 123}), - insert_into("my_first_table") + insert_into(:my_first_table) |> values({1, 456}) |> on_conflict( :id, diff --git a/test/query_test.exs b/test/query_test.exs index 2e3c2c5..4ce34c3 100644 --- a/test/query_test.exs +++ b/test/query_test.exs @@ -6,7 +6,7 @@ defmodule Test.Sonata.Query do seed(), select() - |> from("my_first_table") + |> from(:my_first_table) ] |> assert_snapshot() end @@ -16,7 +16,7 @@ defmodule Test.Sonata.Query do seed(), select() - |> from("my_first_table") + |> from(:my_first_table) |> where(op(:first_column = "foo")) ] |> assert_snapshot() @@ -26,7 +26,7 @@ defmodule Test.Sonata.Query do [ seed(), select() - |> from("my_first_table") + |> from(:my_first_table) |> where(op(:second_column < 3)) ] |> assert_snapshot() @@ -37,7 +37,7 @@ defmodule Test.Sonata.Query do seed(), select() - |> from("my_first_table") + |> from(:my_first_table) |> order_by(:second_column, :desc) ] |> assert_snapshot() @@ -50,7 +50,7 @@ defmodule Test.Sonata.Query do select( count(:second_column) ) - |> from("my_first_table") + |> from(:my_first_table) ] |> assert_snapshot() end @@ -63,7 +63,7 @@ defmodule Test.Sonata.Query do count(:second_column) |> as(:label) ) - |> from("my_first_table") + |> from(:my_first_table) |> where(second_column: 1) ] |> assert_snapshot() @@ -77,7 +77,7 @@ defmodule Test.Sonata.Query do count(:first_column), :second_column ]) - |> from("my_first_table") + |> from(:my_first_table) |> group_by(:second_column) ] |> assert_snapshot() @@ -88,30 +88,31 @@ defmodule Test.Sonata.Query do seed([{"foo", 1}, {"bar", 1}, {"baz", 2}]), select() - |> from("my_first_table") + |> from(:my_first_table) |> where(second_column: 1) |> limit(1) ] |> assert_snapshot() end - # test "should return joined tables" do - # [ - # seed(), - # create_table("my_second_table") - # |> add_column(:label, "text") - # |> add_column(:id, "integer"), + test "should return joined tables" do + [ + seed(), - # insert_into("my_second_table") - # |> values([{"label 1", 1}, {"label 2", 2}]), + create_table(:my_second_table) + |> add_column(:label, "text") + |> add_column(:id, "integer"), - # select() - # |> from("my_first_table") - # |> join("my_second_table", {{"my_first_table", :second_column}, :=, {"my_second_table", :id}}) - # |> where({{"my_second_table", :id}, :=, 1}) - # ] - # |> assert_snapshot() - # end + insert_into(:my_second_table) + |> values([{"label 1", 1}, {"label 2", 2}]), + + select() + |> from(:my_first_table) + |> join(:my_second_table, op({:my_first_table, :second_column} = {:my_second_table, :id})) + |> where(op({:my_second_table, :id} = 1)) + ] + |> assert_snapshot() + end def seed() do seed([{"foo", 1}, {"bar", 2}, {"baz", 3}]) @@ -119,11 +120,11 @@ defmodule Test.Sonata.Query do def seed(values) do [ - create_table("my_first_table") + create_table(:my_first_table) |> add_column(:first_column, "text") |> add_column(:second_column, "integer"), - insert_into("my_first_table") + insert_into(:my_first_table) |> fields([:first_column, :second_column]) |> values(values), ] From 42bfe920ede768aa12876d481dfe81fca43ce1f9 Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Fri, 28 Jul 2017 14:15:45 -0600 Subject: [PATCH 30/43] cleanup --- lib/sonata/alter_table.ex | 1 + lib/sonata/order_by.ex | 43 --------------------------------------- lib/sonata/query.ex | 25 +++++++---------------- lib/sonata/query/join.ex | 4 ++++ lib/sonata/query/value.ex | 16 --------------- 5 files changed, 12 insertions(+), 77 deletions(-) delete mode 100644 lib/sonata/order_by.ex delete mode 100644 lib/sonata/query/value.ex diff --git a/lib/sonata/alter_table.ex b/lib/sonata/alter_table.ex index 75e22e2..b5af5db 100644 --- a/lib/sonata/alter_table.ex +++ b/lib/sonata/alter_table.ex @@ -1,5 +1,6 @@ defmodule Sonata.AlterTable do defstruct [table: nil, + if_exists: nil, add_columns: [], drop_columns: []] diff --git a/lib/sonata/order_by.ex b/lib/sonata/order_by.ex deleted file mode 100644 index 7a22d99..0000000 --- a/lib/sonata/order_by.ex +++ /dev/null @@ -1,43 +0,0 @@ -defmodule Sonata.OrderBy do - defstruct [query: nil, - order_by: []] - - def order_by(%{order_by: expressions} = q, e) when is_list(e) do - %{q | order_by: expressions ++ e} - end - def order_by(query, e) when is_list(e) do - order_by(%Sonata.OrderBy{query: query}, e) - end - def order_by(order_by, e) do - order_by(order_by, [e]) - end - def order_by(order_by, e, order) when order in [:asc, :desc] do - order_by(order_by, [{e, order}]) - end -end - -defimpl Sonata.Postgres, for: Sonata.OrderBy do - alias Sonata.Postgres, as: PG - alias PG.Utils - - def to_sql(%{query: query, order_by: e}, opts, idx) do - {query, query_params, idx} = PG.to_sql(query, opts, idx) - - {e, e_params, idx} = Utils.list_to_sql(e, opts, idx, &(&1), fn - ({expr, order}, opts, idx) -> - PG.to_sql(expr, opts, idx) - (expr, opts, idx) -> - PG.to_sql(expr, opts, idx) - end) - - { - [query, " ORDER BY ", e], - Stream.concat(query_params, e_params), - idx - } - end - - def on_row(_, _) do - nil - end -end diff --git a/lib/sonata/query.ex b/lib/sonata/query.ex index aac3ee6..8bcc9eb 100644 --- a/lib/sonata/query.ex +++ b/lib/sonata/query.ex @@ -22,10 +22,6 @@ defmodule Sonata.Query do |> Column.column(columns) end - def column(q, c, alias) do - Column.column(q, [{c, alias}]) - end - def distinct(q) do %{q | distinct: true} end @@ -39,16 +35,6 @@ defmodule Sonata.Query do distinct(q, [d]) end - def value(q, value, as \\ nil) do - value = %__MODULE__.Value{value: value} - cond do - is_nil(as) -> - Column.column(q, value) - true -> - column(q, value, as) - end - end - def from(q, from) do %{q | from: from} end @@ -123,11 +109,14 @@ defmodule Sonata.Query do %{q | having: expr} end - def order_by(q, expr) do - Sonata.OrderBy.order_by(q, expr) + def order_by(%{order_by: expressions} = q, e) when is_list(e) do + %{q | order_by: expressions ++ e} + end + def order_by(order_by, e) do + order_by(order_by, [e]) end - def order_by(q, expr, order) do - Sonata.OrderBy.order_by(q, expr, order) + def order_by(order_by, e, order) when order in [:asc, :desc] do + order_by(order_by, [{e, order}]) end def limit(q, limit) do diff --git a/lib/sonata/query/join.ex b/lib/sonata/query/join.ex index 3da0f09..bc37d25 100644 --- a/lib/sonata/query/join.ex +++ b/lib/sonata/query/join.ex @@ -22,4 +22,8 @@ defimpl Sonata.Postgres, for: Sonata.Query.Join do idx } end + + def on_row(_, _) do + nil + end end diff --git a/lib/sonata/query/value.ex b/lib/sonata/query/value.ex deleted file mode 100644 index cfaa4de..0000000 --- a/lib/sonata/query/value.ex +++ /dev/null @@ -1,16 +0,0 @@ -defmodule Sonata.Query.Value do - defstruct [:value, :as] -end - -defimpl Sonata.Postgres, for: Sonata.Query.Value do - def to_sql(%{value: value, as: nil}, _, idx) do - {"$#{idx}", [value], idx + 1} - end - def to_sql(%{value: value, as: as}, _, idx) do - {"$#{idx} #{as}", [value], idx + 1} - end - - def on_row(_, _) do - nil - end -end From 0d2c4dbcc594a0e5271c1a01d9ba23b7cff1e020 Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Fri, 28 Jul 2017 14:22:02 -0600 Subject: [PATCH 31/43] more cleanup --- lib/sonata/expr.ex | 6 +----- lib/sonata/expr/value.ex | 13 ------------- lib/sonata/postgres.ex | 17 +++++++++++++++++ lib/sonata/postgres/utils.ex | 5 +---- 4 files changed, 19 insertions(+), 22 deletions(-) delete mode 100644 lib/sonata/expr/value.ex diff --git a/lib/sonata/expr.ex b/lib/sonata/expr.ex index 0f1bb63..15c817a 100644 --- a/lib/sonata/expr.ex +++ b/lib/sonata/expr.ex @@ -19,10 +19,6 @@ defmodule Sonata.Expr do %__MODULE__.Reference{name: name} end - def value(value) do - %__MODULE__.Value{value: value} - end - def default() do %__MODULE__.Default{} end @@ -103,6 +99,6 @@ defmodule Sonata.Expr do end def not(subject) do - %UnaryOperator{operator: "NOT", subject: subject, inverted: false} + %UnaryOperator{operator: "NOT", subject: subject, inverted: true} end end diff --git a/lib/sonata/expr/value.ex b/lib/sonata/expr/value.ex deleted file mode 100644 index 5e8057d..0000000 --- a/lib/sonata/expr/value.ex +++ /dev/null @@ -1,13 +0,0 @@ -defmodule Sonata.Expr.Value do - defstruct [:value] -end - -defimpl Sonata.Postgres, for: Sonata.Expr.Value do - def to_sql(%{value: value}, _, idx) do - {"$#{idx}", [value], idx + 1} - end - - def on_row(_, _) do - nil - end -end diff --git a/lib/sonata/postgres.ex b/lib/sonata/postgres.ex index 7cea339..25b2fc2 100644 --- a/lib/sonata/postgres.ex +++ b/lib/sonata/postgres.ex @@ -1,4 +1,6 @@ defprotocol Sonata.Postgres do + @fallback_to_any true + def to_sql(statement, opts, idx) def on_row(statement, opts) end @@ -56,3 +58,18 @@ defimpl Sonata.Postgres, for: Tuple do nil end end + +defimpl Sonata.Postgres, for: Any do + def to_sql(value, %{params: false}, idx) do + raise Protocol.UndefinedError, + protocol: @protocol, + value: value + end + def to_sql(value, _, idx) do + {"$#{idx}", [value], idx + 1} + end + + def on_row(_, _) do + nil + end +end diff --git a/lib/sonata/postgres/utils.ex b/lib/sonata/postgres/utils.ex index 5b2fe4f..5668a8a 100644 --- a/lib/sonata/postgres/utils.ex +++ b/lib/sonata/postgres/utils.ex @@ -12,12 +12,9 @@ defmodule Sonata.Postgres.Utils do {pop_comma(sql), params, idx} end - def column(column, _, idx) when is_binary(column) do + def column(column, _, idx) when is_binary(column) or is_atom(column) do {escape(column), [], idx} end - def column(column, _, idx) when is_atom(column) do - {escape(Atom.to_string(column)), [], idx} - end def column({column, alias}, opts, idx) do {column, params, idx} = column(column, opts, idx) {[column, " AS ", escape(alias)], params, idx} From d07a8278a02872a6fc995d16c3dd8737528a0cf8 Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Mon, 31 Jul 2017 13:16:12 -0600 Subject: [PATCH 32/43] udate row tests --- _snapshots/Test.Sonata.Insertion.snapshot | 1 + lib/sonata/manipulation.ex | 4 + test/alter_table_test.exs | 4 - ...nipulation_test.exs => insertion_test.exs} | 0 test/update_test.exs | 96 +++++++++++++++++++ 5 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 _snapshots/Test.Sonata.Insertion.snapshot rename test/{manipulation_test.exs => insertion_test.exs} (100%) create mode 100644 test/update_test.exs diff --git a/_snapshots/Test.Sonata.Insertion.snapshot b/_snapshots/Test.Sonata.Insertion.snapshot new file mode 100644 index 0000000..2c55f3b --- /dev/null +++ b/_snapshots/Test.Sonata.Insertion.snapshot @@ -0,0 +1 @@ +%{} \ No newline at end of file diff --git a/lib/sonata/manipulation.ex b/lib/sonata/manipulation.ex index c62c0be..5bafa7c 100644 --- a/lib/sonata/manipulation.ex +++ b/lib/sonata/manipulation.ex @@ -74,4 +74,8 @@ defmodule Sonata.Manipulation do def do_nothing() do %__MODULE__.DoNothing{} end + + def where(q, k, v) do + + end end diff --git a/test/alter_table_test.exs b/test/alter_table_test.exs index d2ef8a1..60d6a04 100644 --- a/test/alter_table_test.exs +++ b/test/alter_table_test.exs @@ -197,10 +197,6 @@ defmodule Test.Sonata.AlterTable do # test "ALTER [ COLUMN ] column SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }" do # end - - - - def seed() do create_table(:my_first_table) |> add_column(:first_column, "text") diff --git a/test/manipulation_test.exs b/test/insertion_test.exs similarity index 100% rename from test/manipulation_test.exs rename to test/insertion_test.exs diff --git a/test/update_test.exs b/test/update_test.exs new file mode 100644 index 0000000..50c4025 --- /dev/null +++ b/test/update_test.exs @@ -0,0 +1,96 @@ +defmodule Test.Sonata.Insertion do + use Test.Sonata + + test "should update one value in row" do + [ + seed(), + update(:table1) + |> set(:label, "new store") + |> where(:id, 1) + ] + |> assert_snapshot() + end + + test "should update multiple cols in a row" do + [ + seed(), + update(:table1) + |> set(%{label: "new store", description: "new awesome store"}) + |> where(:id, 1) + ] + |> assert_snapshot() + end + + test "should update multiple rows, one col each" do + [ + seed(), + update(:table1) + |> set(%{description: "foobar"}) + ] + |> assert_snapshot() + end + + test "should update multiple rows, multiple values" do + [ + seed(), + update(:table1) + |> set(%{label: "foobar", description: "new description"}) + ] + |> assert_snapshot() + end + + test "one row, multiple values again (different interface)" do + [ + seed(), + update(:table1) + |> set(:label, "foobar") + |> set(:description, "new description") + ] + |> assert_snapshot() + end + + test "update returning" do + [ + seed(), + update(:table1) + |> set(:label, "foobar") + |> returning(:label) + |> as("label") + ] + |> assert_snapshot() + end + + test "update where" do + [ + seed(), + update(:table1) + |> as(:t1) + |> set({{:t1, :label}, "new store label"}) + |> from(:table2) + |> as(:t2) + |> where({:t2, :id}, :=, 3) + |> where({:t2, :table1_id}, :=, {:t1, :id}) + ] + |> assert_snapshot() + end + + def seed() do + [ + create_table(:table1) + |> add_column(:id, "integer") + |> add_column(:label, "text") + |> add_column(:description, "text"), + + create_table(:table2) + |> add_column(:id, "integer") + |> add_column(:table1_id, "integer") + |> add_column(:some_data, "text"), + + insert_into(:table1) + |> values([{1, "store", "awesome store"}, {2, "bridge", "tall bridge"}]), + + insert_into(:table2) + |> values([{3, 1, "references store"}, {4, 2, "references bridge"}]) + ] + end +end From 0296f02fd0cef3ddfff1904f8b207d283993044e Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Thu, 2 Nov 2017 16:36:46 -0600 Subject: [PATCH 33/43] fix struct --- lib/sonata/struct.ex | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/sonata/struct.ex b/lib/sonata/struct.ex index 0645932..7644d33 100644 --- a/lib/sonata/struct.ex +++ b/lib/sonata/struct.ex @@ -3,11 +3,9 @@ defmodule Sonata.StructBuilder do defmacro __using__(_) do quote do - import Sonata.Combination.Builder - import Sonata.Manipulation.Builder - import Sonata.Misc.Builder - import Sonata.Query.Builder - alias Sonata.Query.Builder, as: Query + import Sonata.Combination + import Sonata.Manipulation + import Sonata.Query import unquote(__MODULE__), only: unquote(@root_macros) @table nil @@ -36,14 +34,14 @@ defmodule Sonata.StructBuilder do end def create_table do - Sonata.CreateTable.Builder.create_table(unquote(name_s)) + Sonata.CreateTable.create_table(unquote(name_s)) end defoverridable [create_table: 0] - import Sonata.Query.Builder, only: [] + import Sonata.Query, only: [] import unquote(__MODULE__), only: [column: 2] unquote(block) - import Sonata.Query.Builder + import Sonata.Query import unquote(__MODULE__), only: unquote(@root_macros) end end @@ -59,7 +57,7 @@ defmodule Sonata.StructBuilder do @columns unquote(name_a) def column(query, name) when name in [unquote(name_a), unquote(name_s)] do query - |> Sonata.Query.Builder.column(unquote(name_s)) + |> Sonata.Builder.column(unquote(name_s)) end defp unquote(define_column(name_s))() do @@ -74,7 +72,7 @@ defmodule Sonata.StructBuilder do def create_table do tab = super() - Sonata.CreateTable.Builder.add_column(tab, unquote(define_column(name_s))()) + Sonata.CreateTable.add_column(tab, unquote(define_column(name_s))()) end defoverridable [create_table: 0] end From ffb69db90903fd731dbf647ae7fcdfb5ef6fd3a7 Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Fri, 10 Nov 2017 17:34:15 -0700 Subject: [PATCH 34/43] fix update and insert --- lib/sonata/manipulation.ex | 4 ++-- lib/sonata/manipulation/insertion.ex | 3 +-- lib/sonata/manipulation/update.ex | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/sonata/manipulation.ex b/lib/sonata/manipulation.ex index 5bafa7c..045282d 100644 --- a/lib/sonata/manipulation.ex +++ b/lib/sonata/manipulation.ex @@ -37,8 +37,8 @@ defmodule Sonata.Manipulation do %Update{table: table, table_alias: table_alias} end - def set(insertion = %{sets: sets}, kvs) do - %{insertion | sets: sets ++ Enum.map(kvs, fn + def set(insertion = %{fields: fields}, kvs) do + %{insertion | fields: fields ++ Enum.map(kvs, fn ({fields, value}) when is_list(fields) -> Expr.op(Sonata.Expr.column_list(fields) = value) ({fields, _value}) when is_tuple(fields) -> diff --git a/lib/sonata/manipulation/insertion.ex b/lib/sonata/manipulation/insertion.ex index c06d502..0bd5fcc 100644 --- a/lib/sonata/manipulation/insertion.ex +++ b/lib/sonata/manipulation/insertion.ex @@ -51,8 +51,7 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do {nil, [], idx} end def fields(fields, opts, idx) do - {fields, params, idx} = Utils.list_to_sql(fields, opts, idx) - {["(", Utils.join(fields, ", "), ")"], params, idx} + {["(", Utils.join(fields, ", "), ")"], opts, idx} end def default_values(true, _, idx) do diff --git a/lib/sonata/manipulation/update.ex b/lib/sonata/manipulation/update.ex index 385bbc0..64dcacd 100644 --- a/lib/sonata/manipulation/update.ex +++ b/lib/sonata/manipulation/update.ex @@ -61,10 +61,10 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Update do {nil, [], idx} end defp sets(sets, opts, idx) do - {sets, {params, idx}} = Enum.map_reduce(sets, {[], idx}, fn({field, value}, {params, idx}) -> + {sets, {params, idx}} = Enum.map_reduce(sets, {[], idx}, fn(%{lhs: field, operator: operator, rhs: value}, {params, idx}) -> {field, p, idx} = Sonata.Postgres.to_sql(field, opts, idx) {value, p, idx} = Sonata.Postgres.to_sql(value, opts, idx) - {[field, " = (", value, ")"], {Stream.concat(params, p), idx}} + {[field, operator, " (", value, ")"], {Stream.concat(params, p), idx}} end) {["SET ", Sonata.Postgres.Utils.join(sets, ", ")], params, idx} end From 34a432d4023af3ffc61d2653ceb84faeeb5a2dba Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Fri, 10 Nov 2017 17:40:19 -0700 Subject: [PATCH 35/43] fix update after breaking it --- lib/sonata/manipulation.ex | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/sonata/manipulation.ex b/lib/sonata/manipulation.ex index 045282d..667efbc 100644 --- a/lib/sonata/manipulation.ex +++ b/lib/sonata/manipulation.ex @@ -37,7 +37,7 @@ defmodule Sonata.Manipulation do %Update{table: table, table_alias: table_alias} end - def set(insertion = %{fields: fields}, kvs) do + def fields(insertion = %{fields: fields}, kvs) do %{insertion | fields: fields ++ Enum.map(kvs, fn ({fields, value}) when is_list(fields) -> Expr.op(Sonata.Expr.column_list(fields) = value) @@ -50,6 +50,19 @@ defmodule Sonata.Manipulation do end)} end + def set(insertion = %{sets: sets}, kvs) do + %{insertion | sets: sets ++ Enum.map(kvs, fn + ({sets, value}) when is_list(sets) -> + Expr.op(Sonata.Expr.column_list(sets) = value) + ({sets, _value}) when is_tuple(sets) -> + sets + |> :erlang.tuple_to_list() + |> Sonata.Expr.column_list() + ({field, value}) -> + Expr.op(Sonata.Expr.column(field) = value) + end)} + end + def set(insertion, field, value) do set(insertion, [{field, value}]) end From b312cecf4fd57c7109d78d27b5228dbdc59fc06b Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Mon, 13 Nov 2017 15:28:53 -0700 Subject: [PATCH 36/43] fix comments, add delete --- lib/sonata/delete.ex | 98 ++++++++++++++++++++++++++++ lib/sonata/manipulation.ex | 18 +---- lib/sonata/manipulation/insertion.ex | 8 +-- lib/sonata/manipulation/update.ex | 8 +-- 4 files changed, 109 insertions(+), 23 deletions(-) create mode 100644 lib/sonata/delete.ex diff --git a/lib/sonata/delete.ex b/lib/sonata/delete.ex new file mode 100644 index 0000000..040b1f1 --- /dev/null +++ b/lib/sonata/delete.ex @@ -0,0 +1,98 @@ +defmodule Sonata.Delete do + defstruct [from: nil, + where: nil] + + def delete() do + %__MODULE__{} + end + + def from(q, from) do + %{q | from: from} + end + def from(q, from, alias) do + %{q | from: {from, alias}} + end + + def where(q, field, operator, value) do + where(q, [{field, operator, value}]) + end + def where(%{where: where} = q, kvs) when is_list(kvs) do + where = Enum.reduce(kvs, where, fn + ({k, v}, nil) -> + Sonata.Expr.column(k) + |> Sonata.Operator.=(v) + ({k, op, v}, nil) -> + col = Sonata.Expr.column(k) + apply(Sonata.Operator, op, [col, v]) + (clause, nil) -> + clause + ({k, v}, acc) -> + k = Sonata.Expr.column(k) + Sonata.Operator.=(k, v) + |> Sonata.Expr.and(acc) + ({k, op, v}, acc) -> + col = Sonata.Expr.column(k) + apply(Sonata.Operator, op, [col, v]) + |> Sonata.Expr.and(acc) + (clause, acc) -> + clause + |> Sonata.Expr.and(acc) + end) + %{q | where: where} + end + def where(%{where: _} = q, clause) do + where(q, [clause]) + end +end + +defimpl Sonata.Postgres, for: Sonata.Delete do + alias Sonata.Postgres, as: PG + alias PG.Utils + + def to_sql(query, opts, idx) do + {from, from_params, idx} = from(query.from, opts, idx) + {where, where_params, idx} = where(query.where, opts, idx) + + { + Utils.join([ + "DELETE", + from, + where + ], " "), + + Stream.concat([ + from_params, + where_params, + ]), + + idx + } + end + + def on_row(_, _) do + nil + end + + defp from(nil, _, idx) do + {nil, [], idx} + end + defp from(from, _, idx) when is_binary(from) or is_atom(from) do + {["FROM ", Utils.escape(from)], [], idx} + end + defp from({from, alias}, opts, idx) do + {from, params, idx} = from(from, opts, idx) + {[from, " AS ", alias], params, idx} + end + defp from(from, opts, idx) do + {from, params, idx} = PG.to_sql(from, opts, idx) + {["FROM (", from, ")"], params, idx} + end + + defp where(nil, _, idx) do + {nil, [], idx} + end + defp where(expr, opts, idx) do + {where, params, idx} = PG.to_sql(expr, opts, idx) + {["WHERE ", where], params, idx} + end +end diff --git a/lib/sonata/manipulation.ex b/lib/sonata/manipulation.ex index 667efbc..fd5345b 100644 --- a/lib/sonata/manipulation.ex +++ b/lib/sonata/manipulation.ex @@ -37,19 +37,6 @@ defmodule Sonata.Manipulation do %Update{table: table, table_alias: table_alias} end - def fields(insertion = %{fields: fields}, kvs) do - %{insertion | fields: fields ++ Enum.map(kvs, fn - ({fields, value}) when is_list(fields) -> - Expr.op(Sonata.Expr.column_list(fields) = value) - ({fields, _value}) when is_tuple(fields) -> - fields - |> :erlang.tuple_to_list() - |> Sonata.Expr.column_list() - ({field, value}) -> - Expr.op(Sonata.Expr.column(field) = value) - end)} - end - def set(insertion = %{sets: sets}, kvs) do %{insertion | sets: sets ++ Enum.map(kvs, fn ({sets, value}) when is_list(sets) -> @@ -88,7 +75,8 @@ defmodule Sonata.Manipulation do %__MODULE__.DoNothing{} end - def where(q, k, v) do + # TODO + # def where(q, k, v) do - end + # end end diff --git a/lib/sonata/manipulation/insertion.ex b/lib/sonata/manipulation/insertion.ex index 0bd5fcc..60c5e45 100644 --- a/lib/sonata/manipulation/insertion.ex +++ b/lib/sonata/manipulation/insertion.ex @@ -43,15 +43,15 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do defp table(table, _, idx) when table in [nil, false, ""] do {nil, [], idx} end - defp table(table, opts, idx) when is_binary(table) or is_atom(table) do - {Utils.escape(table), opts, idx} + defp table(table, _, idx) when is_binary(table) or is_atom(table) do + {Utils.escape(table), [], idx} end def fields([], _, idx) do {nil, [], idx} end - def fields(fields, opts, idx) do - {["(", Utils.join(fields, ", "), ")"], opts, idx} + def fields(fields, _, idx) do + {["(", Utils.join(fields, ", "), ")"], [], idx} end def default_values(true, _, idx) do diff --git a/lib/sonata/manipulation/update.ex b/lib/sonata/manipulation/update.ex index 64dcacd..e59f214 100644 --- a/lib/sonata/manipulation/update.ex +++ b/lib/sonata/manipulation/update.ex @@ -46,15 +46,15 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Update do defp table(table, _, idx) when table in [nil, false, ""] do {nil, [], idx} end - defp table(table, opts, idx) when is_binary(table) do - {Utils.escape(table), opts, idx} + defp table(table, _, idx) when is_binary(table) do + {Utils.escape(table), [], idx} end defp table_alias(nil, _, idx) do {nil, [], idx} end - defp table_alias(alias, opts, idx) do - {[" AS ", Utils.escape(alias)], opts, idx} + defp table_alias(alias, _, idx) do + {[" AS ", Utils.escape(alias)], [], idx} end defp sets(sets, _, idx) when sets in [nil, false, "", []] do From fbbd02caf845fa9f7068160479ae2f85b45bcf1d Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Mon, 13 Nov 2017 17:03:49 -0700 Subject: [PATCH 37/43] fix some tests, comment out tests for functionality that isn't yet implemented --- _snapshots/Test.Sonata.Insertion.snapshot | 6 +- lib/sonata/manipulation/insertion.ex | 2 +- lib/sonata/manipulation/update.ex | 2 +- test/alter_table_test.exs | 338 +++++++++++----------- test/insertion_test.exs | 6 +- test/update_test.exs | 50 ++-- 6 files changed, 203 insertions(+), 201 deletions(-) diff --git a/_snapshots/Test.Sonata.Insertion.snapshot b/_snapshots/Test.Sonata.Insertion.snapshot index 2c55f3b..6b8aada 100644 --- a/_snapshots/Test.Sonata.Insertion.snapshot +++ b/_snapshots/Test.Sonata.Insertion.snapshot @@ -1 +1,5 @@ -%{} \ No newline at end of file +%{"test one row, multiple values again (different interface)": :update, + "test should update multiple cols in a row": :update, + "test should update multiple rows, multiple values": :update, + "test should update multiple rows, one col each": :update, + "test should update one value in row": :update} \ No newline at end of file diff --git a/lib/sonata/manipulation/insertion.ex b/lib/sonata/manipulation/insertion.ex index 60c5e45..03973f5 100644 --- a/lib/sonata/manipulation/insertion.ex +++ b/lib/sonata/manipulation/insertion.ex @@ -51,7 +51,7 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do {nil, [], idx} end def fields(fields, _, idx) do - {["(", Utils.join(fields, ", "), ")"], [], idx} + {["(", Utils.join(fields |> Enum.map(&Utils.escape/1), ", "), ")"], [], idx} end def default_values(true, _, idx) do diff --git a/lib/sonata/manipulation/update.ex b/lib/sonata/manipulation/update.ex index e59f214..581901a 100644 --- a/lib/sonata/manipulation/update.ex +++ b/lib/sonata/manipulation/update.ex @@ -46,7 +46,7 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Update do defp table(table, _, idx) when table in [nil, false, ""] do {nil, [], idx} end - defp table(table, _, idx) when is_binary(table) do + defp table(table, _, idx) when is_binary(table) or is_atom(table) do {Utils.escape(table), [], idx} end diff --git a/test/alter_table_test.exs b/test/alter_table_test.exs index 60d6a04..4c243e0 100644 --- a/test/alter_table_test.exs +++ b/test/alter_table_test.exs @@ -1,205 +1,205 @@ defmodule Test.Sonata.AlterTable do use Test.Sonata - test "rename column" do - [ - seed(), - - alter_table(:my_first_table) - |> rename_column(:first_column, :new_first_column) - ] - |> assert_snapshot() - end - - test "rename table" do - [ - seed(), - alter_table(:my_first_table) - |> rename_to(:my_new_first_table) - ] - |> assert_snapshot() - end - - # test "alter schema" do + # test "rename column" do # [ # seed(), - # raw_sql("CREATE SCHEMA new_schema;"), + # alter_table(:my_first_table) - # |> set_schema(:new_schema) + # |> rename_column(:first_column, :new_first_column) # ] - # |> assert_snapshot() # does this check the table's schema? + # |> assert_snapshot() # end - test "add column" do - [ - seed(), - alter_table(:my_first_table) - |> add_column(:third_column, "text") - ] - |> assert_snapshot() - end - - test "drop column that exists" do - [ - seed(), - alter_table(:my_first_table) - |> drop_column(:first_column) - ] - |> assert_snapshot() - end - - test "fail to drop column that doesn't exist" do - [ - seed(), - alter_table(:my_first_table) - |> drop_column(:third_column) - ] - |> assert_snapshot() - end - - test "success drop column that exists with `IF EXISTS`" do - [ - seed(), - alter_table(:my_first_table) - |> drop_column(:first_column) - |> if_exists() - ] - |> assert_snapshot() - end - - test "success drop column that doesn't exist with `IF EXISTS`" do - [ - seed(), - alter_table(:my_first_table) - |> drop_column(:third_column) - |> if_exists() - ] - |> assert_snapshot() - end - - # test "drop column and dependent objects (`CASCADE`)" do + # test "rename table" do # [ # seed(), - # create_view("child") - # |> add_column( - # column(:child_column, "text") - # |> as( - # select(:first_column) - # from(:my_first_table) - # ) - # ), + # alter_table(:my_first_table) + # |> rename_to(:my_new_first_table) + # ] + # |> assert_snapshot() + # end + # # test "alter schema" do + # # [ + # # seed(), + # # raw_sql("CREATE SCHEMA new_schema;"), + # # alter_table(:my_first_table) + # # |> set_schema(:new_schema) + # # ] + # # |> assert_snapshot() # does this check the table's schema? + # # end + + # test "add column" do + # [ + # seed(), + # alter_table(:my_first_table) + # |> add_column(:third_column, "text") + # ] + # |> assert_snapshot() + # end + + # test "drop column that exists" do + # [ + # seed(), # alter_table(:my_first_table) # |> drop_column(:first_column) - # |> cascade() # ] # |> assert_snapshot() # end - # test "restrict drop column with dependent objects (`RESTRICT`)" + # test "fail to drop column that doesn't exist" do # [ # seed(), - # create_view("child") - # |> add_column( - # column(:child_column, "text") - # |> as( - # select(:first_column) - # from(:my_first_table) - # ) - # ), + # alter_table(:my_first_table) + # |> drop_column(:third_column) + # ] + # |> assert_snapshot() + # end + # test "success drop column that exists with `IF EXISTS`" do + # [ + # seed(), # alter_table(:my_first_table) # |> drop_column(:first_column) - # |> restrict() + # |> if_exists() + # ] + # |> assert_snapshot() + # end + + # test "success drop column that doesn't exist with `IF EXISTS`" do + # [ + # seed(), + # alter_table(:my_first_table) + # |> drop_column(:third_column) + # |> if_exists() + # ] + # |> assert_snapshot() + # end + + # # test "drop column and dependent objects (`CASCADE`)" do + # # [ + # # seed(), + # # create_view("child") + # # |> add_column( + # # column(:child_column, "text") + # # |> as( + # # select(:first_column) + # # from(:my_first_table) + # # ) + # # ), + + # # alter_table(:my_first_table) + # # |> drop_column(:first_column) + # # |> cascade() + # # ] + # # |> assert_snapshot() + # # end + + # # test "restrict drop column with dependent objects (`RESTRICT`)" + # # [ + # # seed(), + # # create_view("child") + # # |> add_column( + # # column(:child_column, "text") + # # |> as( + # # select(:first_column) + # # from(:my_first_table) + # # ) + # # ), + + # # alter_table(:my_first_table) + # # |> drop_column(:first_column) + # # |> restrict() + # # ] + # # |> assert_snapshot() + # # end + + # test "alter column data type" do + # [ + # seed(), + # alter_table(:my_first_table) + # |> alter_column( + # column(:first_column) + # |> set_data_type("varchar") + # ) # ] # |> assert_snapshot() # end - test "alter column data type" do - [ - seed(), - alter_table(:my_first_table) - |> alter_column( - column(:first_column) - |> set_data_type("varchar") - ) - ] - |> assert_snapshot() - end - - test "alter column default" do - [ - seed(), - alter_table(:my_first_table) - |> alter_column( - column(:first_column) - |> set_default("foobar") - ) - ] - |> assert_snapshot() - end - - test "remove column default" do - [ - create_table(:my_first_table) - |> add_column([ - column(:first_column, "text") - |> default("foobar") - ]), - - alter_table(:my_first_table) - |> alter_column( - column(:first_column) - |> drop_default() - ) - ] - |> assert_snapshot() - end - - test "set column not_null" do - [ - seed(), - alter_table(:my_first_table) - |> alter_column( - column(:first_column) - |> set_not_null() - ) - ] - |> assert_snapshot() - end - - test "drop column not_null" do - [ - create_table(:my_first_table) - |> add_column([ - column(:first_column, "text") - |> not_null() - ]), - - alter_table(:my_first_table) - |> alter_column( - column(:first_column) - |> drop_not_null() - ) - ] - |> assert_snapshot() - end - - # test "ALTER COLUMN column SET STATISTICS integer" do + # test "alter column default" do + # [ + # seed(), + # alter_table(:my_first_table) + # |> alter_column( + # column(:first_column) + # |> set_default("foobar") + # ) + # ] + # |> assert_snapshot() # end - # test "ALTER [ COLUMN ] column SET ( attribute_option = value [, ... ] )" do + # test "remove column default" do + # [ + # create_table(:my_first_table) + # |> add_column([ + # column(:first_column, "text") + # |> default("foobar") + # ]), + + # alter_table(:my_first_table) + # |> alter_column( + # column(:first_column) + # |> drop_default() + # ) + # ] + # |> assert_snapshot() # end - # test "ALTER [ COLUMN ] column RESET ( attribute_option [, ... ] )" do + # test "set column not_null" do + # [ + # seed(), + # alter_table(:my_first_table) + # |> alter_column( + # column(:first_column) + # |> set_not_null() + # ) + # ] + # |> assert_snapshot() # end - # test "ALTER [ COLUMN ] column SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }" do + # test "drop column not_null" do + # [ + # create_table(:my_first_table) + # |> add_column([ + # column(:first_column, "text") + # |> not_null() + # ]), + + # alter_table(:my_first_table) + # |> alter_column( + # column(:first_column) + # |> drop_not_null() + # ) + # ] + # |> assert_snapshot() # end - def seed() do - create_table(:my_first_table) - |> add_column(:first_column, "text") - |> add_column(:second_column, "integer") - end + # # test "ALTER COLUMN column SET STATISTICS integer" do + # # end + + # # test "ALTER [ COLUMN ] column SET ( attribute_option = value [, ... ] )" do + # # end + + # # test "ALTER [ COLUMN ] column RESET ( attribute_option [, ... ] )" do + # # end + + # # test "ALTER [ COLUMN ] column SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }" do + # # end + + # def seed() do + # create_table(:my_first_table) + # |> add_column(:first_column, "text") + # |> add_column(:second_column, "integer") + # end end diff --git a/test/insertion_test.exs b/test/insertion_test.exs index c26b9fe..1808b5e 100644 --- a/test/insertion_test.exs +++ b/test/insertion_test.exs @@ -8,12 +8,10 @@ defmodule Test.Sonata.Manipulation do |> add_column(:second_column, "integer"), insert_into(:my_first_table) - |> fields([:second_column]) + |> fields(["second_column"]) |> values({1}) ] - |> assert_sql(""" - SELECT * FROM my_first_table - """) + |> assert_sql("SELECT * FROM my_first_table") end test "should insert row without specifying columns" do diff --git a/test/update_test.exs b/test/update_test.exs index 50c4025..2357e93 100644 --- a/test/update_test.exs +++ b/test/update_test.exs @@ -6,7 +6,7 @@ defmodule Test.Sonata.Insertion do seed(), update(:table1) |> set(:label, "new store") - |> where(:id, 1) + |> where(id: 1) ] |> assert_snapshot() end @@ -16,7 +16,7 @@ defmodule Test.Sonata.Insertion do seed(), update(:table1) |> set(%{label: "new store", description: "new awesome store"}) - |> where(:id, 1) + |> where(id: 1) ] |> assert_snapshot() end @@ -49,30 +49,30 @@ defmodule Test.Sonata.Insertion do |> assert_snapshot() end - test "update returning" do - [ - seed(), - update(:table1) - |> set(:label, "foobar") - |> returning(:label) - |> as("label") - ] - |> assert_snapshot() - end + # test "update returning" do + # [ + # seed(), + # update(:table1) + # |> set(:label, "foobar") + # |> returning(:label) + # |> as("label") + # ] + # |> assert_snapshot() + # end - test "update where" do - [ - seed(), - update(:table1) - |> as(:t1) - |> set({{:t1, :label}, "new store label"}) - |> from(:table2) - |> as(:t2) - |> where({:t2, :id}, :=, 3) - |> where({:t2, :table1_id}, :=, {:t1, :id}) - ] - |> assert_snapshot() - end + # test "update where" do + # [ + # seed(), + # update(:table1) + # |> as(:t1) + # |> set({{:t1, :label}, "new store label"}) + # |> from(:table2) + # |> as(:t2) + # |> where({:t2, :id}, :=, 3) + # |> where({:t2, :table1_id}, :=, {:t1, :id}) + # ] + # |> assert_snapshot() + # end def seed() do [ From 44640061116bd2f6c3338f92188630ecca944ee2 Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Mon, 13 Nov 2017 17:24:34 -0700 Subject: [PATCH 38/43] tag pending tests --- test/alter_table_test.exs | 403 ++++++++++++++++++++------------------ test/drop_table_test.exs | 60 +++--- test/expr_test.exs | 19 +- test/test_helper.exs | 4 +- test/update_test.exs | 48 ++--- 5 files changed, 281 insertions(+), 253 deletions(-) diff --git a/test/alter_table_test.exs b/test/alter_table_test.exs index 4c243e0..af7ea56 100644 --- a/test/alter_table_test.exs +++ b/test/alter_table_test.exs @@ -1,205 +1,224 @@ defmodule Test.Sonata.AlterTable do use Test.Sonata - # test "rename column" do + @tag :pending + test "rename column" do + [ + seed(), + + alter_table(:my_first_table) + |> rename_column(:first_column, :new_first_column) + ] + |> assert_snapshot() + end + + @tag :pending + test "rename table" do + [ + seed(), + alter_table(:my_first_table) + |> rename_to(:my_new_first_table) + ] + |> assert_snapshot() + end + + @tag :pending + test "alter schema" do + [ + seed(), + # raw_sql("CREATE SCHEMA new_schema;"), + alter_table(:my_first_table) + # |> set_schema(:new_schema) + ] + |> assert_snapshot() # does this check the table's schema? + end + + @tag :pending + test "add column" do + [ + seed(), + alter_table(:my_first_table) + |> add_column(:third_column, "text") + ] + |> assert_snapshot() + end + + @tag :pending + test "drop column that exists" do + [ + seed(), + alter_table(:my_first_table) + |> drop_column(:first_column) + ] + |> assert_snapshot() + end + + @tag :pending + test "fail to drop column that doesn't exist" do + [ + seed(), + alter_table(:my_first_table) + |> drop_column(:third_column) + ] + |> assert_snapshot() + end + + @tag :pending + test "success drop column that exists with `IF EXISTS`" do + [ + seed(), + alter_table(:my_first_table) + |> drop_column(:first_column) + |> if_exists() + ] + |> assert_snapshot() + end + + @tag :pending + test "success drop column that doesn't exist with `IF EXISTS`" do + [ + seed(), + alter_table(:my_first_table) + |> drop_column(:third_column) + |> if_exists() + ] + |> assert_snapshot() + end + + @tag :pending + test "drop column and dependent objects (`CASCADE`)" do + [ + seed(), + # create_view("child") + # |> add_column( + # column(:child_column, "text") + # |> as( + # select(:first_column) + # from(:my_first_table) + # ) + # ), + + alter_table(:my_first_table) + |> drop_column(:first_column) + # |> cascade() + ] + |> assert_snapshot() + end + + # @tag :pending + # test "restrict drop column with dependent objects (`RESTRICT`)" # [ # seed(), + # create_view("child") + # |> add_column( + # column(:child_column, "text") + # |> as( + # select(:first_column) + # from(:my_first_table) + # ) + # ), - # alter_table(:my_first_table) - # |> rename_column(:first_column, :new_first_column) - # ] - # |> assert_snapshot() - # end - - # test "rename table" do - # [ - # seed(), - # alter_table(:my_first_table) - # |> rename_to(:my_new_first_table) - # ] - # |> assert_snapshot() - # end - - # # test "alter schema" do - # # [ - # # seed(), - # # raw_sql("CREATE SCHEMA new_schema;"), - # # alter_table(:my_first_table) - # # |> set_schema(:new_schema) - # # ] - # # |> assert_snapshot() # does this check the table's schema? - # # end - - # test "add column" do - # [ - # seed(), - # alter_table(:my_first_table) - # |> add_column(:third_column, "text") - # ] - # |> assert_snapshot() - # end - - # test "drop column that exists" do - # [ - # seed(), # alter_table(:my_first_table) # |> drop_column(:first_column) + # |> restrict() # ] # |> assert_snapshot() # end - # test "fail to drop column that doesn't exist" do - # [ - # seed(), - # alter_table(:my_first_table) - # |> drop_column(:third_column) - # ] - # |> assert_snapshot() - # end - - # test "success drop column that exists with `IF EXISTS`" do - # [ - # seed(), - # alter_table(:my_first_table) - # |> drop_column(:first_column) - # |> if_exists() - # ] - # |> assert_snapshot() - # end - - # test "success drop column that doesn't exist with `IF EXISTS`" do - # [ - # seed(), - # alter_table(:my_first_table) - # |> drop_column(:third_column) - # |> if_exists() - # ] - # |> assert_snapshot() - # end - - # # test "drop column and dependent objects (`CASCADE`)" do - # # [ - # # seed(), - # # create_view("child") - # # |> add_column( - # # column(:child_column, "text") - # # |> as( - # # select(:first_column) - # # from(:my_first_table) - # # ) - # # ), - - # # alter_table(:my_first_table) - # # |> drop_column(:first_column) - # # |> cascade() - # # ] - # # |> assert_snapshot() - # # end - - # # test "restrict drop column with dependent objects (`RESTRICT`)" - # # [ - # # seed(), - # # create_view("child") - # # |> add_column( - # # column(:child_column, "text") - # # |> as( - # # select(:first_column) - # # from(:my_first_table) - # # ) - # # ), - - # # alter_table(:my_first_table) - # # |> drop_column(:first_column) - # # |> restrict() - # # ] - # # |> assert_snapshot() - # # end - - # test "alter column data type" do - # [ - # seed(), - # alter_table(:my_first_table) - # |> alter_column( - # column(:first_column) - # |> set_data_type("varchar") - # ) - # ] - # |> assert_snapshot() - # end - - # test "alter column default" do - # [ - # seed(), - # alter_table(:my_first_table) - # |> alter_column( - # column(:first_column) - # |> set_default("foobar") - # ) - # ] - # |> assert_snapshot() - # end - - # test "remove column default" do - # [ - # create_table(:my_first_table) - # |> add_column([ - # column(:first_column, "text") - # |> default("foobar") - # ]), - - # alter_table(:my_first_table) - # |> alter_column( - # column(:first_column) - # |> drop_default() - # ) - # ] - # |> assert_snapshot() - # end - - # test "set column not_null" do - # [ - # seed(), - # alter_table(:my_first_table) - # |> alter_column( - # column(:first_column) - # |> set_not_null() - # ) - # ] - # |> assert_snapshot() - # end - - # test "drop column not_null" do - # [ - # create_table(:my_first_table) - # |> add_column([ - # column(:first_column, "text") - # |> not_null() - # ]), - - # alter_table(:my_first_table) - # |> alter_column( - # column(:first_column) - # |> drop_not_null() - # ) - # ] - # |> assert_snapshot() - # end - - # # test "ALTER COLUMN column SET STATISTICS integer" do - # # end - - # # test "ALTER [ COLUMN ] column SET ( attribute_option = value [, ... ] )" do - # # end - - # # test "ALTER [ COLUMN ] column RESET ( attribute_option [, ... ] )" do - # # end - - # # test "ALTER [ COLUMN ] column SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }" do - # # end - - # def seed() do - # create_table(:my_first_table) - # |> add_column(:first_column, "text") - # |> add_column(:second_column, "integer") - # end + @tag :pending + test "alter column data type" do + [ + seed(), + alter_table(:my_first_table) + |> alter_column( + column(:first_column) + |> set_data_type("varchar") + ) + ] + |> assert_snapshot() + end + + @tag :pending + test "alter column default" do + [ + seed(), + alter_table(:my_first_table) + |> alter_column( + column(:first_column) + |> set_default("foobar") + ) + ] + |> assert_snapshot() + end + + @tag :pending + test "remove column default" do + [ + create_table(:my_first_table) + |> add_column([ + column(:first_column, "text") + |> default("foobar") + ]), + + alter_table(:my_first_table) + |> alter_column( + column(:first_column) + |> drop_default() + ) + ] + |> assert_snapshot() + end + + @tag :pending + test "set column not_null" do + [ + seed(), + alter_table(:my_first_table) + |> alter_column( + column(:first_column) + |> set_not_null() + ) + ] + |> assert_snapshot() + end + + @tag :pending + test "drop column not_null" do + [ + create_table(:my_first_table) + |> add_column([ + column(:first_column, "text") + |> not_null() + ]), + + alter_table(:my_first_table) + |> alter_column( + column(:first_column) + |> drop_not_null() + ) + ] + |> assert_snapshot() + end + + @tag :pending + test "ALTER COLUMN column SET STATISTICS integer" do + end + + @tag :pending + test "ALTER [ COLUMN ] column SET ( attribute_option = value [, ... ] )" do + end + + @tag :pending + test "ALTER [ COLUMN ] column RESET ( attribute_option [, ... ] )" do + end + + @tag :pending + test "ALTER [ COLUMN ] column SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }" do + end + + def seed() do + create_table(:my_first_table) + |> add_column(:first_column, "text") + |> add_column(:second_column, "integer") + end end diff --git a/test/drop_table_test.exs b/test/drop_table_test.exs index 76def24..7e988a7 100644 --- a/test/drop_table_test.exs +++ b/test/drop_table_test.exs @@ -1,41 +1,42 @@ defmodule Test.Sonata.DropTable do use Test.Sonata - test "should drop table" do - [ - create_table(:my_first_table) - |> add_column(:first_column, "text") - |> add_column(:second_column, "integer"), + # test "should drop table" do + # [ + # create_table(:my_first_table) + # |> add_column(:first_column, "text") + # |> add_column(:second_column, "integer"), - drop_table(:my_first_table), - ] - |> assert_sql_error(""" - SELECT * FROM my_first_table - """, :undefined_table) - end + # drop_table(:my_first_table), + # ] + # |> assert_sql_error(""" + # SELECT * FROM my_first_table + # """, :undefined_table) + # end - test "should successfully drop table, whether it exists or not, pt.1" do - drop_table(:doesnt_exist) - |> if_exists() - |> assert_snapshot() - end + # test "should successfully drop table, whether it exists or not, pt.1" do + # drop_table(:doesnt_exist) + # |> if_exists() + # |> assert_snapshot() + # end - test "should successfully drop table, whether it exists or not, pt.2" do - [ - create_table(:exists) - |> add_column(:first_column, "text"), + # test "should successfully drop table, whether it exists or not, pt.2" do + # [ + # create_table(:exists) + # |> add_column(:first_column, "text"), - drop_table(:exists) - |> if_exists() - ] - |> assert_snapshot() - end + # drop_table(:exists) + # |> if_exists() + # ] + # |> assert_snapshot() + # end - test "should fail to drop table" do - drop_table(:doesnt_exist) - |> assert_sql_error(:undefined_table) - end + # test "should fail to drop table" do + # drop_table(:doesnt_exist) + # |> assert_sql_error(:undefined_table) + # end + # @tag :pending # test "should drop table, and dependent objects (view)" do # [ # create_table("parent") @@ -58,6 +59,7 @@ defmodule Test.Sonata.DropTable do # """, :reference_error) # end + # @tag :pending # test "`restrict()` should prevent the drop because of dependent object" do # [ # create_table("parent") diff --git a/test/expr_test.exs b/test/expr_test.exs index f274497..108d282 100644 --- a/test/expr_test.exs +++ b/test/expr_test.exs @@ -1,14 +1,15 @@ defmodule Test.Sonata.Expr do use Test.Sonata - # test "AND" do - # [ - # seed([{"foo", 1}, {"foo", 2}, {"foo", 3}]), - # select() - # |> from(:my_first_table) - # |> where(Expr.and({:first_column, :=, "foo"}, {:second_column, :>, 1})) - # ] - # end + @tag :pending + test "AND" do + [ + seed([{"foo", 1}, {"foo", 2}, {"foo", 3}]), + select() + |> from(:my_first_table) + |> where(Expr.and({:first_column, :=, "foo"}, {:second_column, :>, 1})) + ] + end test "BETWEEN" do [ @@ -142,6 +143,7 @@ defmodule Test.Sonata.Expr do |> assert_snapshot() end + # @tag :pending # test "IS_UNKNOWN" do # [ # seed(), @@ -151,6 +153,7 @@ defmodule Test.Sonata.Expr do # ] # end + # @tag :pending # test "IS_NOT_UNKNOWN" do # [ # seed(), diff --git a/test/test_helper.exs b/test/test_helper.exs index 501e15d..ce90faf 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -174,4 +174,6 @@ defmodule Test.Sonata do end end -ExUnit.start() +ExUnit.start([ + exclude: [:pending] +]) diff --git a/test/update_test.exs b/test/update_test.exs index 2357e93..6d2f0be 100644 --- a/test/update_test.exs +++ b/test/update_test.exs @@ -49,30 +49,32 @@ defmodule Test.Sonata.Insertion do |> assert_snapshot() end - # test "update returning" do - # [ - # seed(), - # update(:table1) - # |> set(:label, "foobar") - # |> returning(:label) - # |> as("label") - # ] - # |> assert_snapshot() - # end + @tag :pending + test "update returning" do + [ + seed(), + update(:table1) + |> set(:label, "foobar") + |> returning(:label) + |> as("label") + ] + |> assert_snapshot() + end - # test "update where" do - # [ - # seed(), - # update(:table1) - # |> as(:t1) - # |> set({{:t1, :label}, "new store label"}) - # |> from(:table2) - # |> as(:t2) - # |> where({:t2, :id}, :=, 3) - # |> where({:t2, :table1_id}, :=, {:t1, :id}) - # ] - # |> assert_snapshot() - # end + @tag :pending + test "update where" do + [ + seed(), + update(:table1) + |> as(:t1) + |> set({{:t1, :label}, "new store label"}) + |> from(:table2) + |> as(:t2) + |> where({:t2, :id}, :=, 3) + |> where({:t2, :table1_id}, :=, {:t1, :id}) + ] + |> assert_snapshot() + end def seed() do [ From 0bbea165a66514326d3d107d8ccbf359b7eb4c05 Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Thu, 16 Nov 2017 15:50:48 -0700 Subject: [PATCH 39/43] alter table --- _snapshots/Test.Sonata.AlterTable.snapshot | 20 +- lib/sonata/alter_table.ex | 379 +++++++++++++++++++-- lib/sonata/utils.ex | 12 + test/alter_table_test.exs | 159 ++++----- 4 files changed, 450 insertions(+), 120 deletions(-) create mode 100644 lib/sonata/utils.ex diff --git a/_snapshots/Test.Sonata.AlterTable.snapshot b/_snapshots/Test.Sonata.AlterTable.snapshot index 5bdfbde..1f46ce8 100644 --- a/_snapshots/Test.Sonata.AlterTable.snapshot +++ b/_snapshots/Test.Sonata.AlterTable.snapshot @@ -1,9 +1,11 @@ -%{"test add column": :create_table, - "test alter column data type": :create_table, - "test alter column default": :create_table, - "test drop column that exists": :create_table, - "test fail to drop column that doesn't exist": :create_table, - "test rename column": :create_table, "test rename table": :create_table, - "test set column not_null": :create_table, - "test success drop column that doesn't exist with `IF EXISTS`": :create_table, - "test success drop column that exists with `IF EXISTS`": :create_table} \ No newline at end of file +%{"test add column": :alter_table, "test alter column data type": :alter_table, + "test drop column that exists": :alter_table, + "test fail to drop column that doesn't exist": %Postgrex.Error{connection_id: nil, + message: nil, + postgres: %{code: :undefined_column, file: "tablecmds.c", line: "5725", + message: "column \"third_column\" of relation \"my_first_table\" does not exist", + pg_code: "42703", routine: "ATExecDropColumn", severity: "ERROR", + unknown: "ERROR"}}, "test rename column": :alter_table, + "test rename table": :alter_table, + "test success drop column that doesn't exist with `IF EXISTS`": :alter_table, + "test success drop column that exists with `IF EXISTS`": :alter_table} \ No newline at end of file diff --git a/lib/sonata/alter_table.ex b/lib/sonata/alter_table.ex index b5af5db..03d1ff4 100644 --- a/lib/sonata/alter_table.ex +++ b/lib/sonata/alter_table.ex @@ -1,51 +1,390 @@ defmodule Sonata.AlterTable do defstruct [table: nil, if_exists: nil, - add_columns: [], - drop_columns: []] + only: nil, + rename_to: nil, + rename_constraint: nil, + rename_column: nil, + to: nil, + set_schema: nil, + all_in_tablespace: nil, + set_tablespace: nil, + owned_by: nil, + nowait: nil, + + # actions + row_level_sec: nil, + + # colum manipulation + add_column: {}, + add_column_constraint: nil, + drop_column: nil, + drop_column_if_exists: nil, + drop_constraint: nil, + drop_constraint_if_exists: nil, + restrict: nil, + cascade: nil, + + alter_column: nil, + set_data_type: nil, + collate: nil, + using: nil, + ] def alter_table(table) do %__MODULE__{table: table} end - def rename_column(alter, old_name, new_name) do - alter + def if_exists(alter) do + %{alter | if_exists: true} + end + + def only(alter) do + %{alter | only: true} end def rename_to(alter, new_table_name) do - alter + %{alter | rename_to: new_table_name} + end + + def rename_constraint(alter, constraint_name) do + %{alter | rename_constraint: constraint_name} + end + + def rename_column(alter, column_name) do + %{alter | rename_column: column_name} + end + def rename_column(alter, column_name, to) do + %{alter | rename_column: column_name, to: to} + end + + def to(alter, new_name) do + %{alter | to: new_name} end - def drop_table(alter, table) do + def set_schema(alter, new_schema) do + %{alter | set_schema: new_schema} + end + + def all_in_tablespace(alter) do + %{alter | all_in_tablespace: true} + end + + def set_tablespace(alter, new_tablespace) do + %{alter | set_tablespace: new_tablespace} + end + + def owned_by(alter, role_name) do + %{alter | owned_by: role_name} + end + + def nowait(alter) do + %{alter | nowait: true} + end + + def enable_row_level_security(alter) do + %{alter | enable_row_level_security: true} + end + + # COLUMNS + def add_column(alter, column_name, data_type) do + %{alter | add_column: {column_name, data_type}} + end + def add_column(alter, column_name, data_type, constraint) do + add_column(alter, column_name, data_type) + add_column_constraint(alter, constraint) + end + + def add_column_constraint(alter, nil) do alter end + def add_column_constraint(alter, constraint) do + %{alter | add_column_constraint: constraint} + end def drop_column(alter, column_name) do - alter + %{alter | drop_column: column_name} end - def alter_column(alter, column) do - alter + def if_column_exists(alter) do + %{alter | drop_column_if_exists: true} + end + + def drop_column_if_exists(alter, column_name) do + %{alter | drop_column_if_exists: true} + drop_column(alter, column_name) + end + + def drop_constraint(alter, constraint_name) do + %{alter | drop_constraint: constraint_name} + end + + def if_constraint_exists(alter) do + %{alter | drop_constraint_if_exists: true} + end + + def drop_constraint_if_exists(alter, constraint_name) do + %{alter | drop_constraint_if_exists: true} + drop_constraint(alter, constraint_name) + end + + def restrict(alter) do + %{alter | restrict: true} + end + + def cascade(alter) do + %{alter | cascade: true} + end + + def alter_column(alter, column_name) do + %{alter | alter_column: column_name} + end + + def set_data_type(alter, data_type) do + %{alter | set_data_type: data_type} + end + + def collate(alter, collate) do + %{alter | collate: collate} + end + + def using(alter, using) do + %{alter | using: using} + end +end + +defimpl Sonata.Postgres, for: Sonata.AlterTable do + alias Sonata.Postgres, as: PG + alias PG.Utils + import Sonata.Utils + + def to_sql(alter, opts, idx) do + {if_exists, if_exists_params, idx} = if_exists(alter.if_exists, opts, idx) + {only, only_params, idx} = only(alter.only, opts, idx) + {all_in_tablespace, all_in_tablespace_params, idx} = all_in_tablespace(alter.all_in_tablespace, opts, idx) + {table, table_params, idx} = table(alter.table, opts, idx) + {owned_by, owned_by_params, idx} = owned_by(alter.owned_by, opts, idx) + + {rename_constraint, rename_constraint_params, idx} = rename_constraint(alter.rename_constraint, opts, idx) + {rename_column, rename_column_params, idx} = rename_column(alter.rename_column, opts, idx) + {to, to_params, idx} = to(alter.to, opts, idx) + {rename_to, rename_to_params, idx} = rename_to(alter.rename_to, opts, idx) + {set_schema, set_schema_params, idx} = set_schema(alter.set_schema, opts, idx) + {set_tablespace, set_tablespace_params, idx} = set_tablespace(alter.set_tablespace, opts, idx) + {nowait, nowait_params, idx} = nowait(alter.nowait, opts, idx) + {row_level_sec, row_level_sec_params, idx} = row_level_sec(alter.row_level_sec, opts, idx) + + {add_column, add_column_params, idx} = add_column(alter.add_column, opts, idx) + {add_column_constraint, add_column_constraint_params, idx} = add_column_constraint(alter.add_column_constraint, opts, idx) + + {drop_column, drop_column_params, idx} = drop_column(alter, opts, idx) + {drop_constraint, drop_constraint_params, idx} = drop_constraint(alter, opts, idx) + {restrict, restrict_params, idx} = restrict(alter.restrict, opts, idx) + {cascade, cascade_params, idx} = cascade(alter.cascade, opts, idx) + + {alter_column, alter_column_params, idx} = alter_column(alter.alter_column, opts, idx) + {set_data_type, set_data_type_params, idx} = set_data_type(alter.set_data_type, opts, idx) + {collate, collate_params, idx} = collate(alter.collate, opts, idx) + {using, using_params, idx} = using(alter.using, opts, idx) + + { + Utils.join([ + "ALTER TABLE", + if_exists, + only, + all_in_tablespace, + table, + owned_by, + + rename_constraint, + rename_column, + to, + rename_to, + set_schema, + set_tablespace, + nowait, + row_level_sec, + + add_column, + add_column_constraint, + drop_column, + drop_constraint, + restrict, + cascade, + + alter_column, + set_data_type, + collate, + using, + ";" + ], " "), + + Stream.concat([ + if_exists_params, + only_params, + all_in_tablespace_params, + table_params, + owned_by_params, + + rename_constraint_params, + rename_column_params, + to_params, + rename_to_params, + set_schema_params, + set_tablespace_params, + nowait_params, + row_level_sec_params, + + add_column_params, + add_column_constraint_params, + drop_column_params, + drop_constraint_params, + restrict_params, + cascade_params, + + alter_column_params, + set_data_type_params, + collate_params, + using_params, + ]), + + idx + } + end + + def on_row(_, _) do + nil + end + + defp if_exists(if_exists, _, idx) when is_falsy?(if_exists), do: no_change(idx) + defp if_exists(true, _, idx) do + {"IF EXISTS", [], idx} + end + + defp only(only, _, idx) when is_falsy?(only), do: no_change(idx) + defp only(true, _, idx) do + {"ONLY", [], idx} + end + + defp all_in_tablespace(all_in_tabelspace, _, idx) when is_falsy?(all_in_tabelspace), do: no_change(idx) + defp all_in_tablespace(true, _, idx) do + {"ALL IN TABLESPACE", [], idx} + end + + defp table(table, _, idx) when is_falsy?(table), do: no_change(idx) + defp table(table, _, idx) do + {Utils.escape(table), [], idx} + end + + defp rename_constraint(constraint_name, _, idx) when is_falsy?(constraint_name), do: no_change(idx) + defp rename_constraint(constraint_name, _, idx) do + {["RENAME CONSTRAINT ", Utils.escape(constraint_name)], [], idx} + end + + defp rename_column(column_name, _, idx) when is_falsy?(column_name), do: no_change(idx) + defp rename_column(column_name, _, idx) do + {["RENAME COLUMN ", Utils.escape(column_name)], [], idx} + end + + defp to(new_name, _, idx) when is_falsy?(new_name), do: no_change(idx) + defp to(new_name, opts, idx) do + {new_name, params, idx} = PG.to_sql(new_name, opts, idx) + {["TO ", new_name], params, idx} + end + + defp rename_to(new_name, _, idx) when is_falsy?(new_name), do: no_change(idx) + defp rename_to(new_name, opts, idx) do + {new_name, params, idx} = PG.to_sql(new_name, opts, idx) + {["RENAME TO ", new_name], params, idx} + end + + defp set_schema(new_schema, _, idx) when is_falsy?(new_schema), do: no_change(idx) + defp set_schema(new_schema, opts, idx) do + {new_schema, params, idx} = PG.to_sql(new_schema, opts, idx) + {["SET SCHEMA ", new_schema], params, idx} + end + + defp owned_by(owned_by, _, idx) when is_falsy?(owned_by), do: no_change(idx) + defp owned_by(owned_by, opts, idx) when is_binary(owned_by) do + {owned_by, params, idx} = PG.to_sql(owned_by, opts, idx) + {["OWNED BY ", owned_by], params, idx} + end + + defp set_tablespace(new_tablespace, _, idx) when is_falsy?(new_tablespace), do: no_change(idx) + defp set_tablespace(new_tablespace, opts, idx) do + {new_tablespace, params, idx} = PG.to_sql(new_tablespace, opts, idx) + {["SET TABLESPACE ", new_tablespace], params, idx} + end + + defp nowait(nowait, _, idx) when is_falsy?(nowait), do: no_change(idx) + defp nowait(true, _, idx) do + {"NOWAIT", [], idx} + end + + defp row_level_sec(row_level_sec, _, idx) when is_falsy?(row_level_sec), do: no_change(idx) + defp row_level_sec(true, _, idx) do + {"ENABLE ROW LEVEL SECURITY", [], idx} + end + + defp add_column(changes, _, idx) when is_falsy?(changes), do: no_change(idx) + defp add_column({column_name, data_type, _}, _, idx) do + {["ADD COLUMN ", Utils.escape(column_name), " ", Utils.escape(data_type)], [], idx} + end + defp add_column({column_name, data_type}, opts, idx) do + add_column({column_name, data_type, nil}, opts, idx) + end + + defp add_column_constraint(constraint, _, idx) when is_falsy?(constraint), do: no_change(idx) + defp add_column_constraint(constraint, opts, idx) do + PG.to_sql(constraint, opts, idx) + end + + defp drop_column(%{drop_column: drop_column}, _, idx) when is_falsy?(drop_column), do: no_change(idx) + defp drop_column(alter, opts, idx) do + {column_name, params, idx} = PG.to_sql(alter.drop_column, opts, idx) + {["DROP COLUMN ", if_exists(alter.drop_column_if_exists), column_name], params, idx} + end + + defp drop_constraint(%{drop_constraint: constraint_name}, _, idx) when is_falsy?(constraint_name), do: no_change(idx) + defp drop_constraint(alter, opts, idx) do + {constraint_name, params, idx} = PG.to_sql(alter.drop_constraint, opts, idx) + {["DROP CONSTRAINT ", if_exists(alter.drop_constraint_if_exists), constraint_name], params, idx} + end + + defp if_exists(if_exists) when is_falsy?(if_exists), do: "" + defp if_exists(true) do + "IF EXISTS " + end + + defp restrict(restrict, _, idx) when is_falsy?(restrict), do: no_change(idx) + defp restrict(true, _, idx) do + {"RESTRICT", [], idx} end - # COLUMN FUNCTIONS - def set_default(column, default) do - column + defp cascade(cascade, _, idx) when is_falsy?(cascade), do: no_change(idx) + defp cascade(true, _, idx) do + {"CASCADE", [], idx} end - def drop_default(column) do - column + def alter_column(column_name, _, idx) when is_falsy?(column_name), do: no_change(idx) + def alter_column(column_name, _, idx) do + {["ALTER COLUMN ", Utils.escape(column_name)], [], idx} end - def set_data_type(column, data_type) do - column + defp set_data_type(data_type, _, idx) when is_falsy?(data_type), do: no_change(idx) + defp set_data_type(data_type, _, idx) do + {["SET DATA TYPE ", Utils.escape(data_type)], [], idx} end - def set_not_null(column) do - column + defp collate(collate, _, idx) when is_falsy?(collate), do: no_change(idx) + defp collate(collate, opts, idx) do + {collate, params, idx} = PG.to_sql(collate, opts, idx) + {["COLLATE ", collate], params, idx} end - def drop_not_null(column) do - column + defp using(using, _, idx) when is_falsy?(using), do: no_change(idx) + defp using(using, opts, idx) do + {using, params, idx} = PG.to_sql(using, opts, idx) + {["USING ", using], params, idx} end end diff --git a/lib/sonata/utils.ex b/lib/sonata/utils.ex new file mode 100644 index 0000000..c41072e --- /dev/null +++ b/lib/sonata/utils.ex @@ -0,0 +1,12 @@ +defmodule Sonata.Utils do + defmacro is_falsy?(val) do + quote do + unquote(val) in [nil, false, "", {}, [], %{}] + end + end + + # HELPERS + def no_change(idx) do + {"", [], idx} + end +end diff --git a/test/alter_table_test.exs b/test/alter_table_test.exs index af7ea56..d7b2d52 100644 --- a/test/alter_table_test.exs +++ b/test/alter_table_test.exs @@ -1,18 +1,19 @@ defmodule Test.Sonata.AlterTable do use Test.Sonata + alias Sonata.CreateTable + alias Sonata.AlterTable - @tag :pending test "rename column" do [ seed(), alter_table(:my_first_table) - |> rename_column(:first_column, :new_first_column) + |> rename_column(:first_column) + |> to(:new_first_column) ] |> assert_snapshot() end - @tag :pending test "rename table" do [ seed(), @@ -33,17 +34,15 @@ defmodule Test.Sonata.AlterTable do |> assert_snapshot() # does this check the table's schema? end - @tag :pending test "add column" do [ seed(), alter_table(:my_first_table) - |> add_column(:third_column, "text") + |> Sonata.AlterTable.add_column(:third_column, "text") ] |> assert_snapshot() end - @tag :pending test "drop column that exists" do [ seed(), @@ -53,34 +52,31 @@ defmodule Test.Sonata.AlterTable do |> assert_snapshot() end - @tag :pending test "fail to drop column that doesn't exist" do [ seed(), alter_table(:my_first_table) |> drop_column(:third_column) ] - |> assert_snapshot() + |> assert_sql_error(:undefined_column) end - @tag :pending test "success drop column that exists with `IF EXISTS`" do [ seed(), alter_table(:my_first_table) |> drop_column(:first_column) - |> if_exists() + |> if_column_exists() ] |> assert_snapshot() end - @tag :pending test "success drop column that doesn't exist with `IF EXISTS`" do [ seed(), alter_table(:my_first_table) |> drop_column(:third_column) - |> if_exists() + |> if_column_exists() ] |> assert_snapshot() end @@ -125,100 +121,81 @@ defmodule Test.Sonata.AlterTable do # |> assert_snapshot() # end - @tag :pending test "alter column data type" do [ seed(), alter_table(:my_first_table) - |> alter_column( - column(:first_column) - |> set_data_type("varchar") - ) + |> alter_column(:first_column) + |> set_data_type("varchar") ] |> assert_snapshot() end - @tag :pending - test "alter column default" do - [ - seed(), - alter_table(:my_first_table) - |> alter_column( - column(:first_column) - |> set_default("foobar") - ) - ] - |> assert_snapshot() - end - - @tag :pending - test "remove column default" do - [ - create_table(:my_first_table) - |> add_column([ - column(:first_column, "text") - |> default("foobar") - ]), - - alter_table(:my_first_table) - |> alter_column( - column(:first_column) - |> drop_default() - ) - ] - |> assert_snapshot() - end - - @tag :pending - test "set column not_null" do - [ - seed(), - alter_table(:my_first_table) - |> alter_column( - column(:first_column) - |> set_not_null() - ) - ] - |> assert_snapshot() - end - - @tag :pending - test "drop column not_null" do - [ - create_table(:my_first_table) - |> add_column([ - column(:first_column, "text") - |> not_null() - ]), + # @tag :pending + # test "alter column default" do + # [ + # seed(), + # alter_table(:my_first_table) + # |> alter_column( + # column(:first_column) + # |> set_default("foobar") + # ) + # ] + # |> assert_snapshot() + # end - alter_table(:my_first_table) - |> alter_column( - column(:first_column) - |> drop_not_null() - ) - ] - |> assert_snapshot() - end + # @tag :pending + # test "remove column default" do + # [ + # create_table(:my_first_table) + # |> add_column([ + # column(:first_column, "text") + # |> default("foobar") + # ]), - @tag :pending - test "ALTER COLUMN column SET STATISTICS integer" do - end + # alter_table(:my_first_table) + # |> alter_column( + # column(:first_column) + # |> drop_default() + # ) + # ] + # |> assert_snapshot() + # end - @tag :pending - test "ALTER [ COLUMN ] column SET ( attribute_option = value [, ... ] )" do - end + # @tag :pending + # test "set column not_null" do + # [ + # seed(), + # alter_table(:my_first_table) + # |> alter_column( + # column(:first_column) + # |> set_not_null() + # ) + # ] + # |> assert_snapshot() + # end - @tag :pending - test "ALTER [ COLUMN ] column RESET ( attribute_option [, ... ] )" do - end + # @tag :pending + # test "drop column not_null" do + # [ + # create_table(:my_first_table) + # |> add_column([ + # column(:first_column, "text") + # |> not_null() + # ]), - @tag :pending - test "ALTER [ COLUMN ] column SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }" do - end + # alter_table(:my_first_table) + # |> alter_column( + # column(:first_column) + # |> drop_not_null() + # ) + # ] + # |> assert_snapshot() + # end def seed() do create_table(:my_first_table) - |> add_column(:first_column, "text") - |> add_column(:second_column, "integer") + |> CreateTable.add_column(:first_column, "text") + |> CreateTable.add_column(:second_column, "integer") end end From f1f8c6bea107d9fc6d256059e037e004780878c1 Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Tue, 12 Dec 2017 14:07:17 -0700 Subject: [PATCH 40/43] fix primary key issues --- lib/sonata/manipulation/insertion.ex | 12 +++++-- lib/sonata/struct.ex | 49 +++++++++++++++++++++++----- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/lib/sonata/manipulation/insertion.ex b/lib/sonata/manipulation/insertion.ex index 03973f5..29e7d46 100644 --- a/lib/sonata/manipulation/insertion.ex +++ b/lib/sonata/manipulation/insertion.ex @@ -17,6 +17,7 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do {default_values, default_values_params, idx} = default_values(insertion.default_values, opts, idx) {rows, rows_params, idx} = rows(insertion.rows, opts, idx) {on_conflict, on_conflict_params, idx} = on_conflict(insertion.on_conflict, opts, idx) + {returning, returning_params, idx} = returning(insertion.returning, opts, idx) { [Utils.join([ @@ -26,6 +27,7 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do default_values, rows, on_conflict, + returning, ], " "), ";"], Stream.concat([ @@ -34,6 +36,7 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do default_values_params, rows_params, on_conflict_params, + returning_params, ]), idx @@ -81,8 +84,13 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Insertion do end # TODO - # defp returning do - # end + defp returning(returning, _, idx) when returning in [nil, false, "", []] do + {nil, [], idx} + end + defp returning(returning, opts, idx) do + {sql, params, idx} = PG.Utils.columns(returning, opts, idx) + {["RETURNING ", sql], params, idx} + end def on_row(_, _) do nil diff --git a/lib/sonata/struct.ex b/lib/sonata/struct.ex index 7644d33..46d858b 100644 --- a/lib/sonata/struct.ex +++ b/lib/sonata/struct.ex @@ -11,6 +11,7 @@ defmodule Sonata.StructBuilder do @table nil Module.register_attribute(__MODULE__, :columns, accumulate: true) Module.register_attribute(__MODULE__, :relations, accumulate: true) + Module.register_attribute(__MODULE__, :primary_keys, accumulate: true) @before_compile unquote(__MODULE__) @@ -64,7 +65,7 @@ defmodule Sonata.StructBuilder do var!(column_name) = unquote(name_a) _ = var!(column_name) var!(column) = %Sonata.Definition.Column{name: unquote(name_s)} - import unquote(__MODULE__), only: [type: 1, primary_key: 0, default: 1, references: 1, not_null: 0] + import unquote(__MODULE__), only: [type: 1, primary_key: 0, default: 1, references: 1, references: 2, not_null: 0] unquote(block) import unquote(__MODULE__), only: [column: 2] var!(column) @@ -95,7 +96,7 @@ defmodule Sonata.StructBuilder do defmacro primary_key() do module = __CALLER__.module [column | _] = Module.get_attribute(module, :columns) - Module.put_attribute(module, :primary_key, column) + Module.put_attribute(module, :primary_keys, column) quote do var!(column) = %{var!(column) | primary_key: true} end @@ -117,10 +118,11 @@ defmodule Sonata.StructBuilder do defmacro not_null() do quote do - var!(column) = %{var!(column) | not_null: true} + var!(column) = %{var!(column) | null: false} end end + @doc """ """ @@ -133,9 +135,28 @@ defmodule Sonata.StructBuilder do end {:__aliases__, _, _} -> quote do - {type, column} = unquote(table).__primary_key__ + [{col, type}] = unquote(table).__primary_keys__ |> :maps.to_list table = unquote(table).table - var!(column) = %{var!(column) | type: type, reference: {column, table}} + var!(column) = %{var!(column) | type: type, reference: {table, col}} + end + end + end + + defmacro references(table, target_column) do + case table do + _ when is_binary(table) -> + quote do + var!(column) = Sonata.Definition.Column.reference(var!(column), unquote(table), unquote(to_string(target_column))) + end + {:__aliases__, _, _} -> + quote do + var!(column) = case unquote(table).__primary_keys__ do + %{unquote(to_string(target_column)) => type} -> + table = unquote(table).table + %{var!(column) | type: type, reference: {table, unquote(to_string(target_column))}} + _ -> + raise ArgumentError, unquote("Unknown target column: #{target_column}") + end end end end @@ -181,14 +202,24 @@ defmodule Sonata.StructBuilder do end defmacro __before_compile__(env) do - pk = Module.get_attribute(env.module, :primary_key) + pks = Module.get_attribute(env.module, :primary_keys) quote do if @table do defstruct @columns ++ @relations ++ [__meta__: nil] - def __primary_key__ do - %{type: type} = unquote(define_column(pk))() - {type, unquote(to_string(pk))} + def columns do + unquote(Module.get_attribute(env.module, :columns) |> Enum.map(&to_string/1) |> Enum.reverse()) + end + + if unquote(length(pks) > 0) do + def __primary_keys__ do + %{unquote_splicing(Enum.map(pks, fn(col) -> + {to_string(col), quote do + %{type: type} = unquote(define_column(col))() + type + end} + end))} + end end @__input_columns Enum.map(@columns, &{&1, &1}) ++ Enum.map(@columns, &{&1, to_string(&1)}) From 355d6d216ec6eebb06ccf9a17a9cca3141fd2ded Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Fri, 15 Dec 2017 23:18:48 -0700 Subject: [PATCH 41/43] fix joins --- lib/sonata/expr.ex | 17 ++++++++++---- lib/sonata/expr/reference.ex | 45 +++++++++++++++++++++++++++++++++--- lib/sonata/query.ex | 44 ++++++++++++++++++++++++----------- lib/sonata/query/join.ex | 42 +++++++++++++++++++++++++++++---- 4 files changed, 123 insertions(+), 25 deletions(-) diff --git a/lib/sonata/expr.ex b/lib/sonata/expr.ex index 15c817a..9803bf7 100644 --- a/lib/sonata/expr.ex +++ b/lib/sonata/expr.ex @@ -7,16 +7,25 @@ defmodule Sonata.Expr do %__MODULE__.Call{name: name, arguments: arguments} end - def column(name) do - %__MODULE__.Reference{name: name} + def column({table, column}) do + %__MODULE__.Reference{table: table, column: column} + end + def column({table, column, as}) do + %__MODULE__.Reference{table: table, column: column, as: as} + end + def column(column) do + %__MODULE__.Reference{column: column} end def column_list(columns) do %__MODULE__.ColumnList{columns: columns} end - def table(name) do - %__MODULE__.Reference{name: name} + def table({table, as}) do + %__MODULE__.Reference{table: table, as: as} + end + def table(table) do + %__MODULE__.Reference{table: table} end def default() do diff --git a/lib/sonata/expr/reference.ex b/lib/sonata/expr/reference.ex index 0a1c731..26917e3 100644 --- a/lib/sonata/expr/reference.ex +++ b/lib/sonata/expr/reference.ex @@ -1,15 +1,54 @@ defmodule Sonata.Expr.Reference do - defstruct [:name] + defstruct [:table, :column, :as] end defimpl Sonata.Postgres, for: Sonata.Expr.Reference do alias Sonata.Postgres.Utils - def to_sql(%{name: name}, _, idx) do - {Utils.escape(name), [], idx} + def to_sql(query, _, idx) do + table = table(query) + column = column(query.column) + as = as(query.as) + + {[ + table, + column, + as + ], [], idx} + end + + defp table(%{table: nil}) do + "" + end + defp table(%{table: table, column: column}) when not is_nil(column) do + [Utils.escape(table), "."] + end + defp table(%{table: table}) do + Utils.escape(table) + end + + defp column(nil) do + "" + end + defp column(column) do + Utils.escape(column) + end + + defp as(nil) do + "" + end + defp as(as) do + [" AS ", Utils.escape(as)] end def on_row(_, _) do nil end + + defp as(nil) do + "" + end + defp as(as) do + [" AS ", as |> Utils.escape()] + end end diff --git a/lib/sonata/query.ex b/lib/sonata/query.ex index 8bcc9eb..2cd74b4 100644 --- a/lib/sonata/query.ex +++ b/lib/sonata/query.ex @@ -11,15 +11,20 @@ defmodule Sonata.Query do offset: nil, struct: nil] - alias Sonata.Builder.Column - def select() do %__MODULE__{} end def select(columns) do select() - |> Column.column(columns) + |> columns(columns) + end + + def columns(q, column) when not is_list(column) do + columns(q, [column]) + end + def columns(%{columns: c} = q, columns) do + %{q | columns: c ++ columns} end def distinct(q) do @@ -130,15 +135,6 @@ defmodule Sonata.Query do def into_struct(q, struct) do %{q | struct: struct} end - - defimpl Column do - def column(%{columns: columns} = q, c) when is_list(c) do - %{q | columns: columns ++ c} - end - def column(q, c) do - column(q, [c]) - end - end end defimpl Sonata.Postgres, for: Sonata.Query do @@ -147,7 +143,7 @@ defimpl Sonata.Postgres, for: Sonata.Query do def to_sql(query, opts, idx) do {distinct, distinct_params, idx} = distinct(query.distinct, opts, idx) - {columns, column_params, idx} = Utils.columns(query.columns, opts, idx) + {columns, column_params, idx} = columns(query.columns, opts, idx) {from, from_params, idx} = from(query.from, opts, idx) {joins, joins_params, idx} = joins(query.joins, opts, idx) {where, where_params, idx} = where(query.where, opts, idx) @@ -207,6 +203,28 @@ defimpl Sonata.Postgres, for: Sonata.Query do {["DISTINCT ON (", columns, ")"], params, idx} end + defp columns([], _, idx) do + {"*", [], idx} + end + defp columns(columns, _, idx) do + { + columns + |> Enum.map(fn(column) -> + case (column) do + {table, column} -> + [Utils.escape(table), ".", Utils.escape(column)] + {table, column, as} -> + [Utils.escape(table), ".", Utils.escape(column), " AS ", Utils.escape(as)] + column -> + Utils.escape(column) + end + end) + |> Enum.join(", "), + [], + idx + } + end + defp from(nil, _, idx) do {nil, [], idx} end diff --git a/lib/sonata/query/join.ex b/lib/sonata/query/join.ex index bc37d25..2bf2eaa 100644 --- a/lib/sonata/query/join.ex +++ b/lib/sonata/query/join.ex @@ -6,18 +6,23 @@ defimpl Sonata.Postgres, for: Sonata.Query.Join do alias Sonata.Postgres, as: PG alias PG.Utils - def to_sql(%{command: command, table: table, on: on}, opts, idx) do - {on, params, idx} = PG.to_sql(on, opts, idx) + def to_sql(%{command: command, table: table, on: {column1, column2}}, _, idx) do + # {on, params, idx} = PG.to_sql(on, opts, idx) + table = table(table) + column1 = column(column1) + column2 = column(column2) { Utils.join([ command, - Utils.escape(table), + table, "ON", - on + column1, + "=", + column2 ], " "), - params, + [], idx } @@ -26,4 +31,31 @@ defimpl Sonata.Postgres, for: Sonata.Query.Join do def on_row(_, _) do nil end + + defp table(nil) do + "" + end + defp table({table, as}) do + [Utils.escape(table), " AS ", Utils.escape(as)] + end + defp table(table) do + table + |> Utils.escape() + end + + defp column({nil, column, nil}) do + Utils.escape(column) + end + defp column({nil, column, as}) do + [Utils.escape(column), " AS ", Utils.escape(as)] + end + defp column({table, column, nil}) do + [Utils.escape(table), ".", Utils.escape(column)] + end + defp column({table, column, as}) do + [Utils.escape(table), ".", Utils.escape(column), " AS ", Utils.escape(as)] + end + defp column({table, column}) do + column({table, column, nil}) + end end From f30b524248df8ccaff76e60f110ed4869eefd8c8 Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Thu, 5 Apr 2018 23:01:02 -0600 Subject: [PATCH 42/43] fix warnings, remove tool-versions, support manipulation.update --- .tool-versions | 2 -- lib/sonata/definition/check.ex | 2 +- lib/sonata/definition/column.ex | 2 +- lib/sonata/expr/reference.ex | 6 ------ lib/sonata/manipulation.ex | 33 +++++++++++++++++++++++++++---- lib/sonata/manipulation/update.ex | 2 +- lib/sonata/postgres.ex | 2 +- mix.lock | 22 +++++++++++---------- 8 files changed, 45 insertions(+), 26 deletions(-) delete mode 100644 .tool-versions diff --git a/.tool-versions b/.tool-versions deleted file mode 100644 index 7bca3e6..0000000 --- a/.tool-versions +++ /dev/null @@ -1,2 +0,0 @@ -erlang 20.0 -elixir 1.5.0-rc.0 diff --git a/lib/sonata/definition/check.ex b/lib/sonata/definition/check.ex index 8445a15..9991600 100644 --- a/lib/sonata/definition/check.ex +++ b/lib/sonata/definition/check.ex @@ -10,7 +10,7 @@ defimpl Sonata.Postgres, for: Sonata.Definition.Check do alias Sonata.Postgres, as: PG alias PG.Utils - def to_sql(%{name: name, expr: expr, inherit: inherit}, opts, idx) do + def to_sql(%{name: name, expr: expr}, opts, idx) do {expr, params, idx} = PG.to_sql(expr, opts, idx) {[name(name), "CHECK ", expr], params, idx} end diff --git a/lib/sonata/definition/column.ex b/lib/sonata/definition/column.ex index ad3cd99..7430d40 100644 --- a/lib/sonata/definition/column.ex +++ b/lib/sonata/definition/column.ex @@ -128,7 +128,7 @@ defmodule Sonata.Definition.Column do } = column, %{ inherit: i, expr: expr, - } = check) do + }) do %{column | check: %Check{ name: n, expr: Sonata.Expr.and(e, expr), diff --git a/lib/sonata/expr/reference.ex b/lib/sonata/expr/reference.ex index 26917e3..27042de 100644 --- a/lib/sonata/expr/reference.ex +++ b/lib/sonata/expr/reference.ex @@ -34,12 +34,6 @@ defimpl Sonata.Postgres, for: Sonata.Expr.Reference do Utils.escape(column) end - defp as(nil) do - "" - end - defp as(as) do - [" AS ", Utils.escape(as)] - end def on_row(_, _) do nil diff --git a/lib/sonata/manipulation.ex b/lib/sonata/manipulation.ex index fd5345b..2c48238 100644 --- a/lib/sonata/manipulation.ex +++ b/lib/sonata/manipulation.ex @@ -75,8 +75,33 @@ defmodule Sonata.Manipulation do %__MODULE__.DoNothing{} end - # TODO - # def where(q, k, v) do - - # end + def where(q, field, operator, value) do + where(q, [{field, operator, value}]) + end + def where(%{where: where} = q, kvs) when is_list(kvs) do + where = Enum.reduce(kvs, where, fn + ({k, v}, nil) -> + Sonata.Expr.column(k) + |> Sonata.Operator.=(v) + ({k, op, v}, nil) -> + col = Sonata.Expr.column(k) + apply(Sonata.Operator, op, [col, v]) + (clause, nil) -> + clause + ({k, v}, acc) -> + k = Sonata.Expr.column(k) + Sonata.Expr.and(Sonata.Operator.=(k, v), acc) + ({k, op, v}, acc) -> + col = Sonata.Expr.column(k) + apply(Sonata.Operator, op, [col, v]) + |> Sonata.Expr.and(acc) + (clause, acc) -> + clause + |> Sonata.Expr.and(acc) + end) + %{q | where: where} + end + def where(%{where: _} = q, clause) do + where(q, [clause]) + end end diff --git a/lib/sonata/manipulation/update.ex b/lib/sonata/manipulation/update.ex index 581901a..6cb026a 100644 --- a/lib/sonata/manipulation/update.ex +++ b/lib/sonata/manipulation/update.ex @@ -62,7 +62,7 @@ defimpl Sonata.Postgres, for: Sonata.Manipulation.Update do end defp sets(sets, opts, idx) do {sets, {params, idx}} = Enum.map_reduce(sets, {[], idx}, fn(%{lhs: field, operator: operator, rhs: value}, {params, idx}) -> - {field, p, idx} = Sonata.Postgres.to_sql(field, opts, idx) + {field, _p, idx} = Sonata.Postgres.to_sql(field, opts, idx) {value, p, idx} = Sonata.Postgres.to_sql(value, opts, idx) {[field, operator, " (", value, ")"], {Stream.concat(params, p), idx}} end) diff --git a/lib/sonata/postgres.ex b/lib/sonata/postgres.ex index 25b2fc2..186a551 100644 --- a/lib/sonata/postgres.ex +++ b/lib/sonata/postgres.ex @@ -60,7 +60,7 @@ defimpl Sonata.Postgres, for: Tuple do end defimpl Sonata.Postgres, for: Any do - def to_sql(value, %{params: false}, idx) do + def to_sql(value, %{params: false}, _idx) do raise Protocol.UndefinedError, protocol: @protocol, value: value diff --git a/mix.lock b/mix.lock index 79e7dca..133c08a 100644 --- a/mix.lock +++ b/mix.lock @@ -1,21 +1,23 @@ -%{"certifi": {:hex, :certifi, "1.2.1", "c3904f192bd5284e5b13f20db3ceac9626e14eeacfbb492e19583cf0e37b22be", [], [], "hexpm"}, +%{ + "certifi": {:hex, :certifi, "1.2.1", "c3904f192bd5284e5b13f20db3ceac9626e14eeacfbb492e19583cf0e37b22be", [:rebar3], [], "hexpm"}, "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"}, "csv": {:hex, :csv, "2.0.0", "c66fea89ba7862b94901baf0871285e9b73cad89c5fdb57a6386d2adcf29593e", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm"}, "db_connection": {:hex, :db_connection, "1.1.2", "2865c2a4bae0714e2213a0ce60a1b12d76a6efba0c51fbda59c9ab8d1accc7a8", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, "decimal": {:hex, :decimal, "1.4.0", "fac965ce71a46aab53d3a6ce45662806bdd708a4a95a65cde8a12eb0124a1333", [:mix], [], "hexpm"}, "ecto": {:hex, :ecto, "2.1.4", "d1ba932813ec0e0d9db481ef2c17777f1cefb11fc90fa7c142ff354972dfba7e", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, "epgsql": {:hex, :epgsql, "3.3.0", "974a578340e52012cbab820ce756e7ed1df1baf0110c59a6753d8337a2cf9454", [], [], "hexpm"}, - "excoveralls": {:hex, :excoveralls, "0.7.1", "3dd659db19c290692b5e2c4a2365ae6d4488091a1ba58f62dcbdaa0c03da5491", [], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, - "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, + "excoveralls": {:hex, :excoveralls, "0.7.1", "3dd659db19c290692b5e2c4a2365ae6d4488091a1ba58f62dcbdaa0c03da5491", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, + "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, "fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], [], "hexpm"}, - "hackney": {:hex, :hackney, "1.8.6", "21a725db3569b3fb11a6af17d5c5f654052ce9624219f1317e8639183de4a423", [], [{:certifi, "1.2.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.0.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, - "idna": {:hex, :idna, "5.0.2", "ac203208ada855d95dc591a764b6e87259cb0e2a364218f215ad662daa8cd6b4", [], [{:unicode_util_compat, "0.2.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, - "jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [], [], "hexpm"}, - "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [], [], "hexpm"}, - "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [], [], "hexpm"}, + "hackney": {:hex, :hackney, "1.8.6", "21a725db3569b3fb11a6af17d5c5f654052ce9624219f1317e8639183de4a423", [:rebar3], [{:certifi, "1.2.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.0.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, + "idna": {:hex, :idna, "5.0.2", "ac203208ada855d95dc591a764b6e87259cb0e2a364218f215ad662daa8cd6b4", [:rebar3], [{:unicode_util_compat, "0.2.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, + "jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], [], "hexpm"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, + "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, "mix_test_watch": {:hex, :mix_test_watch, "0.4.1", "a98a84c795623f1ba020324f4354cf30e7120ba4dab65f9c2ae300f830a25f75", [:mix], [{:fs, "~> 0.9.1", [hex: :fs, repo: "hexpm", optional: false]}], "hexpm"}, "parallel_stream": {:hex, :parallel_stream, "1.0.5", "4c78d3e675f9eff885cbe252c89a8fc1d2fb803c0d03a914281e587834e09431", [:mix], [], "hexpm"}, "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"}, "postgrex": {:hex, :postgrex, "0.13.3", "c277cfb2a9c5034d445a722494c13359e361d344ef6f25d604c2353185682bfc", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [], [], "hexpm"}, - "unicode_util_compat": {:hex, :unicode_util_compat, "0.2.0", "dbbccf6781821b1c0701845eaf966c9b6d83d7c3bfc65ca2b78b88b8678bfa35", [], [], "hexpm"}} + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.2.0", "dbbccf6781821b1c0701845eaf966c9b6d83d7c3bfc65ca2b78b88b8678bfa35", [:rebar3], [], "hexpm"}, +} From c0c4d12b671e39c49fde4c08122a09bdbe0f7897 Mon Sep 17 00:00:00 2001 From: Brandon Bassett Date: Wed, 11 Apr 2018 09:00:37 -0600 Subject: [PATCH 43/43] fix joins --- lib/sonata/postgres/utils.ex | 14 ++++++++++---- lib/sonata/query.ex | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/sonata/postgres/utils.ex b/lib/sonata/postgres/utils.ex index 5668a8a..e689652 100644 --- a/lib/sonata/postgres/utils.ex +++ b/lib/sonata/postgres/utils.ex @@ -53,12 +53,18 @@ defmodule Sonata.Postgres.Utils do |> join(delim) end - def list_to_sql(list, opts, idx, mapper \\ &(&1), to_sql \\ &PG.to_sql/3) do - {sql, {params, idx}} = Enum.map_reduce(list, {[], idx}, fn(item, {acc_params, idx}) -> + def list_to_sql(list, opts, idx, mapper \\ &(&1), to_sql \\ &PG.to_sql/3) do + Enum.reduce(list, {[], [], idx}, fn(item, {acc, acc_params, idx}) -> {sql, params, idx} = to_sql.(item, opts, idx) - {mapper.(sql), {Stream.concat(acc_params, params), idx}} + {[acc | mapper.(sql)], Stream.concat(acc_params, params), idx} + end) + end + + def list_rev_to_sql(list, opts, idx, mapper \\ &(&1), to_sql \\ &PG.to_sql/3) do + Enum.reduce(list, {[], [], idx}, fn(item, {acc, acc_params, idx}) -> + {sql, params, idx} = to_sql.(item, opts, idx) + {[mapper.(sql) | acc], Stream.concat(params, acc_params), idx} end) - {sql, params, idx} end def escape(value) when is_binary(value) do diff --git a/lib/sonata/query.ex b/lib/sonata/query.ex index 2cd74b4..7f3641a 100644 --- a/lib/sonata/query.ex +++ b/lib/sonata/query.ex @@ -244,7 +244,7 @@ defimpl Sonata.Postgres, for: Sonata.Query do {nil, [], idx} end defp joins(joins, opts, idx) do - Utils.list_to_sql(joins, opts, idx) + Utils.list_rev_to_sql(joins, opts, idx) end defp where(nil, _, idx) do