if Code.ensure_loaded?(Ecto.Migration) do defmodule Pointers.ULID.Migration do import Ecto.Migration # Based on answers to this SO thread, tweaked. # https://stackoverflow.com/questions/49227572/function-minuuid-does-not-exist-in-postgresql defp create_agg(op) do """ create aggregate #{op}(uuid) ( sfunc = #{op}_uuid, stype = uuid, combinefunc = #{op}_uuid, sortop = operator (<), parallel = safe ) """ end defp drop_agg(name), do: "drop aggregate if exists #{name}(uuid)" @min_uuid """ create or replace function min_uuid(uuid, uuid) returns uuid as $$ begin if $1 is null then return $2; end if; if $2 is null then return $1; end if; if $2 > $1 then return $1; end if; return $2; end; $$ LANGUAGE plpgsql """ @max_uuid """ create or replace function max_uuid(uuid, uuid) returns uuid as $$ begin if $1 is null then return $2; end if; if $2 is null then return $1; end if; if $1 > $2 then return $1; end if; return $2; end; $$ LANGUAGE plpgsql """ defp drop_fun(name), do: "drop function if exists #{name}(uuid, uuid)" defp min_uuid(), do: execute(@min_uuid, drop_fun("min_uuid")) defp max_uuid(), do: execute(@max_uuid, drop_fun("max_uuid")) defp min(), do: execute(create_agg("min"), drop_agg("min")) defp max(), do: execute(create_agg("max"), drop_agg("max")) def init_pointers_ulid_extra() do init_pointers_ulid_extra(direction()) end defp functions() do min_uuid() max_uuid() end defp aggregates() do min() max() end def init_pointers_ulid_extra(:up) do functions() aggregates() end def init_pointers_ulid_extra(:down) do aggregates() functions() end end end