Packages
electric
0.7.2
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.1
1.5.0
1.4.16
1.4.16-beta-1
1.4.15
1.4.14
1.4.13
1.4.12
1.4.11
1.4.10
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.4
1.3.3
1.3.2
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.14
1.1.13
1.1.12
1.1.11
1.1.10
1.1.9
1.1.8
1.1.7
1.1.6
retired
1.1.5
retired
1.1.4
retired
1.1.3
retired
1.1.2
1.1.1
1.1.0
1.0.24
1.0.23
1.0.22
1.0.21
1.0.20
1.0.19
1.0.18
1.0.17
1.0.15
1.0.13
1.0.12
1.0.11
1.0.10
1.0.9
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
1.0.0-beta.23
1.0.0-beta.22
1.0.0-beta.20
1.0.0-beta.19
1.0.0-beta.18
1.0.0-beta.17
1.0.0-beta.16
1.0.0-beta.15
1.0.0-beta.14
1.0.0-beta.13
1.0.0-beta.12
1.0.0-beta.11
1.0.0-beta.10
1.0.0-beta.9
1.0.0-beta.8
1.0.0-beta.7
1.0.0-beta.6
1.0.0-beta.5
1.0.0-beta.4
1.0.0-beta.3
1.0.0-beta.2
1.0.0-beta.1
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.1
0.8.0
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.5.2
0.4.4
Postgres sync engine. Sync little subsets of your Postgres data into local apps and services.
Current section
Files
Jump to
Current section
Files
lib/electric/replication/eval/env/known_functions.ex
defmodule Electric.Replication.Eval.Env.KnownFunctions do
use Electric.Replication.Eval.KnownDefinition
alias PgInterop.Interval
alias Electric.Replication.PostgresInterop.Casting
alias Electric.Replication.Eval.Env.BasicTypes
## "input" functions
defpostgres("int2(text) -> int2", delegate: &Casting.parse_int2/1)
defpostgres("int4(text) -> int4", delegate: &Casting.parse_int4/1)
defpostgres("int8(text) -> int8", delegate: &Casting.parse_int8/1)
defpostgres("float4(text) -> float4", delegate: &Casting.parse_float8/1)
defpostgres("float8(text) -> float8", delegate: &Casting.parse_float8/1)
defpostgres("numeric(text) -> numeric", delegate: &Casting.parse_float8/1)
defpostgres("bool(text) -> bool", delegate: &Casting.parse_bool/1)
defpostgres("uuid(text) -> uuid", delegate: &Casting.parse_uuid/1)
defpostgres("date(text) -> date", delegate: &Casting.parse_date/1)
defpostgres("time(text) -> time", delegate: &Casting.parse_time/1)
defpostgres("timestamp(text) -> timestamp", delegate: &Casting.parse_timestamp/1)
defpostgres("timestamptz(text) -> timestamp", delegate: &Casting.parse_timestamptz/1)
defpostgres("interval(text) -> interval", delegate: &Interval.parse!/1)
## "output" functions
defpostgres("int2out(int2) -> text", delegate: &Integer.to_string/1)
defpostgres("int4out(int4) -> text", delegate: &Integer.to_string/1)
defpostgres("int8out(int8) -> text", delegate: &Integer.to_string/1)
defpostgres("float4out(float4) -> text", delegate: &Float.to_string/1)
defpostgres("float8out(float8) -> text", delegate: &Float.to_string/1)
defpostgres("numericout(numeric) -> text", delegate: &Float.to_string/1)
defpostgres("dateout(date) -> text", delegate: &Date.to_iso8601/1)
defpostgres("timeout(time) -> text", delegate: &Time.to_iso8601/1)
defpostgres("timestampout(timestamp) -> text", delegate: &NaiveDateTime.to_iso8601/1)
defpostgres("intervalout(interval) -> text", delegate: &PgInterop.Interval.format/1)
defpostgres "boolout(bool) -> text" do
def bool_out(true), do: "t"
def bool_out(false), do: "f"
end
defpostgres("uuidout(uuid) -> text", delegate: &BasicTypes.noop/1)
## Comparison functions
defcompare("*numeric_type*", using: Kernel)
defcompare("text", using: Kernel)
defcompare("uuid", using: Kernel)
defcompare("date", using: &Date.compare/2)
defcompare("time", using: &Time.compare/2)
defcompare("timestamp", using: &NaiveDateTime.compare/2)
defcompare("timestamptz", using: &DateTime.compare/2)
defpostgres("bool = bool -> bool", delegate: &Kernel.==/2)
defpostgres("bool <> bool -> bool", delegate: &Kernel.!=/2)
defpostgres("interval = interval -> bool", delegate: &Kernel.==/2)
defpostgres("interval <> interval -> bool", delegate: &Kernel.!=/2)
## Numeric functions
defpostgres("+ *numeric_type* -> *numeric_type*", delegate: &Kernel.+/1)
defpostgres("- *numeric_type* -> *numeric_type*", delegate: &Kernel.-/1)
defpostgres("*numeric_type* + *numeric_type* -> *numeric_type*", delegate: &Kernel.+/2)
defpostgres("*numeric_type* - *numeric_type* -> *numeric_type*", delegate: &Kernel.-/2)
defpostgres("*integral_type* / *integral_type* -> bool", delegate: &Kernel.div/2)
defpostgres("float8 / float8 -> bool", delegate: &Kernel.//2)
defpostgres("numeric ^ numeric -> numeric", delegate: &Float.pow/2)
defpostgres("float8 ^ float8 -> float8", delegate: &Float.pow/2)
defpostgres("|/ float8 -> float8", delegate: &:math.sqrt/1)
defpostgres("@ *numeric_type* -> *numeric_type*", delegate: &:erlang.abs/1)
defpostgres("*integral_type* & *integral_type* -> *integral_type*", delegate: &Bitwise.band/2)
defpostgres("*integral_type* | *integral_type* -> *integral_type*", delegate: &Bitwise.bor/2)
defpostgres("*integral_type* # *integral_type* -> *integral_type*", delegate: &Bitwise.bxor/2)
## String functions
defpostgres "text || text -> text" do
# Can't do `delegate: &Kernel.<>/2`, because it's a macro that gets converted to local function call
def text_concat(t1, t2) when is_binary(t1) and is_binary(t2) do
t1 <> t2
end
end
defpostgres("lower(text) -> text", delegate: &String.downcase/1)
defpostgres("upper(text) -> text", delegate: &String.upcase/1)
defpostgres("text ~~ text -> bool", delegate: &Casting.like?/2)
defpostgres("text ~~* text -> bool", delegate: &Casting.ilike?/2)
defpostgres "text !~~ text -> bool" do
def not_like?(text1, text2), do: not Casting.like?(text1, text2)
end
defpostgres "text !~~* text -> bool" do
def not_ilike?(text1, text2), do: not Casting.ilike?(text1, text2)
end
## Date functions
defpostgres("date + int8 -> date", commutative?: true, delegate: &Date.add/2)
defpostgres("date - date -> int8", delegate: &Date.diff/2)
defpostgres "date - int8 -> date" do
def date_subtract(date, int), do: Date.add(date, -int)
end
defpostgres("date + time -> timestamp", commutative?: true, delegate: &NaiveDateTime.new!/2)
defpostgres("interval + interval -> interval", delegate: &Interval.add/2)
defpostgres("date + interval -> timestamp",
commutative?: true,
delegate: &Interval.add_to_date/2
)
defpostgres("timestamp + interval -> timestamp",
commutative?: true,
delegate: &Interval.add_to_date/2
)
defpostgres("timestamptz + interval -> timestamptz",
commutative?: true,
delegate: &Interval.add_to_date/2
)
defpostgres("time + interval -> time", commutative?: true, delegate: &Interval.add_to_time/2)
defpostgres("date - interval -> timestamp", delegate: &Interval.subtract_from_date/2)
defpostgres("timestamp - interval -> timestamp", delegate: &Interval.subtract_from_date/2)
defpostgres("timestamptz - interval -> timestamptz", delegate: &Interval.subtract_from_date/2)
defpostgres("interval - interval -> interval", delegate: &Interval.subtract/2)
defpostgres("timestamp - timestamp -> interval", delegate: &Interval.datetime_diff/2)
defpostgres("timestamptz - timestamptz -> interval", delegate: &Interval.datetime_diff/2)
defpostgres("interval * float8 -> interval", commutative?: true, delegate: &Interval.scale/2)
defpostgres("justify_days(interval) -> interval", delegate: &Interval.justify_days/1)
defpostgres("justify_hours(interval) -> interval", delegate: &Interval.justify_hours/1)
defpostgres("justify_interval(interval) -> interval", delegate: &Interval.justify_interval/1)
defpostgres "timezone(text, timestamp) -> timestamptz" do
def timestamptz_from_naive(tz, datetime), do: DateTime.from_naive!(datetime, tz)
end
defpostgres "timezone(text, timestamptz) -> timestamp" do
def naive_from_timestamptz(tz, datetime),
do: datetime |> DateTime.shift_zone!(tz) |> DateTime.to_naive()
end
end