From 1d0437a675b883ae10298d72b758a8b5b67356cc Mon Sep 17 00:00:00 2001 From: Zach Daniel <zach@zachdaniel.dev> Date: Mon, 13 Jan 2025 16:12:19 -0500 Subject: [PATCH] improvement: mark ash_raise_error as STABLE --- lib/migration_generator/ash_functions.ex | 25 +++++++- .../test_no_sandbox_repo/extensions.json | 2 +- .../test_repo/extensions.json | 2 +- ...3205301_migrate_resources_extensions_1.exs | 60 +++++++++++++++++++ ...3205259_migrate_resources_extensions_1.exs | 60 +++++++++++++++++++ 5 files changed, 145 insertions(+), 4 deletions(-) create mode 100644 priv/test_no_sandbox_repo/migrations/20250113205301_migrate_resources_extensions_1.exs create mode 100644 priv/test_repo/migrations/20250113205259_migrate_resources_extensions_1.exs diff --git a/lib/migration_generator/ash_functions.ex b/lib/migration_generator/ash_functions.ex index 53b29ac9..a9c4659c 100644 --- a/lib/migration_generator/ash_functions.ex +++ b/lib/migration_generator/ash_functions.ex @@ -1,5 +1,5 @@ defmodule AshPostgres.MigrationGenerator.AshFunctions do - @latest_version 4 + @latest_version 5 def latest_version, do: @latest_version @@ -143,7 +143,26 @@ defmodule AshPostgres.MigrationGenerator.AshFunctions do end def install(3) do - uuid_generate_v7() + """ + execute("ALTER FUNCTION ash_raise_error(jsonb) STABLE;") + execute("ALTER FUNCTION ash_raise_error(jsonb, ANYCOMPATIBLE) STABLE") + #{uuid_generate_v7()} + """ + end + + def install(4) do + """ + execute("ALTER FUNCTION ash_raise_error(jsonb) STABLE;") + execute("ALTER FUNCTION ash_raise_error(jsonb, ANYCOMPATIBLE) STABLE") + #{uuid_generate_v7()} + """ + end + + def drop(4) do + """ + execute("ALTER FUNCTION ash_raise_error(jsonb) VOLATILE;") + execute("ALTER FUNCTION ash_raise_error(jsonb, ANYCOMPATIBLE) VOLATILE") + """ end def drop(3) do @@ -184,6 +203,7 @@ defmodule AshPostgres.MigrationGenerator.AshFunctions do RETURN NULL; END; $$ LANGUAGE plpgsql + STABLE SET search_path = ''; \"\"\") @@ -197,6 +217,7 @@ defmodule AshPostgres.MigrationGenerator.AshFunctions do RETURN NULL; END; $$ LANGUAGE plpgsql + STABLE SET search_path = ''; \"\"\") """ diff --git a/priv/resource_snapshots/test_no_sandbox_repo/extensions.json b/priv/resource_snapshots/test_no_sandbox_repo/extensions.json index 40d20b77..4430c306 100644 --- a/priv/resource_snapshots/test_no_sandbox_repo/extensions.json +++ b/priv/resource_snapshots/test_no_sandbox_repo/extensions.json @@ -1,5 +1,5 @@ { - "ash_functions_version": 4, + "ash_functions_version": 5, "installed": [ "ash-functions", "uuid-ossp", diff --git a/priv/resource_snapshots/test_repo/extensions.json b/priv/resource_snapshots/test_repo/extensions.json index 557d0ea8..d1c5a122 100644 --- a/priv/resource_snapshots/test_repo/extensions.json +++ b/priv/resource_snapshots/test_repo/extensions.json @@ -1,5 +1,5 @@ { - "ash_functions_version": 4, + "ash_functions_version": 5, "installed": [ "ash-functions", "uuid-ossp", diff --git a/priv/test_no_sandbox_repo/migrations/20250113205301_migrate_resources_extensions_1.exs b/priv/test_no_sandbox_repo/migrations/20250113205301_migrate_resources_extensions_1.exs new file mode 100644 index 00000000..9794c3be --- /dev/null +++ b/priv/test_no_sandbox_repo/migrations/20250113205301_migrate_resources_extensions_1.exs @@ -0,0 +1,60 @@ +defmodule AshPostgres.TestNoSandboxRepo.Migrations.MigrateResourcesExtensions1 do + @moduledoc """ + Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + execute("ALTER FUNCTION ash_raise_error(jsonb) STABLE;") + execute("ALTER FUNCTION ash_raise_error(jsonb, ANYCOMPATIBLE) STABLE") + + execute(""" + CREATE OR REPLACE FUNCTION uuid_generate_v7() + RETURNS UUID + AS $$ + DECLARE + timestamp TIMESTAMPTZ; + microseconds INT; + BEGIN + timestamp = clock_timestamp(); + microseconds = (cast(extract(microseconds FROM timestamp)::INT - (floor(extract(milliseconds FROM timestamp))::INT * 1000) AS DOUBLE PRECISION) * 4.096)::INT; + + RETURN encode( + set_byte( + set_byte( + overlay(uuid_send(gen_random_uuid()) placing substring(int8send(floor(extract(epoch FROM timestamp) * 1000)::BIGINT) FROM 3) FROM 1 FOR 6 + ), + 6, (b'0111' || (microseconds >> 8)::bit(4))::bit(8)::int + ), + 7, microseconds::bit(8)::int + ), + 'hex')::UUID; + END + $$ + LANGUAGE PLPGSQL + SET search_path = '' + VOLATILE; + """) + + execute(""" + CREATE OR REPLACE FUNCTION timestamp_from_uuid_v7(_uuid uuid) + RETURNS TIMESTAMP WITHOUT TIME ZONE + AS $$ + SELECT to_timestamp(('x0000' || substr(_uuid::TEXT, 1, 8) || substr(_uuid::TEXT, 10, 4))::BIT(64)::BIGINT::NUMERIC / 1000); + $$ + LANGUAGE SQL + SET search_path = '' + IMMUTABLE PARALLEL SAFE STRICT; + """) + end + + def down do + # Uncomment this if you actually want to uninstall the extensions + # when this migration is rolled back: + execute("ALTER FUNCTION ash_raise_error(jsonb) VOLATILE;") + execute("ALTER FUNCTION ash_raise_error(jsonb, ANYCOMPATIBLE) VOLATILE") + end +end diff --git a/priv/test_repo/migrations/20250113205259_migrate_resources_extensions_1.exs b/priv/test_repo/migrations/20250113205259_migrate_resources_extensions_1.exs new file mode 100644 index 00000000..e6efdcb9 --- /dev/null +++ b/priv/test_repo/migrations/20250113205259_migrate_resources_extensions_1.exs @@ -0,0 +1,60 @@ +defmodule AshPostgres.TestRepo.Migrations.MigrateResourcesExtensions1 do + @moduledoc """ + Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + execute("ALTER FUNCTION ash_raise_error(jsonb) STABLE;") + execute("ALTER FUNCTION ash_raise_error(jsonb, ANYCOMPATIBLE) STABLE") + + execute(""" + CREATE OR REPLACE FUNCTION uuid_generate_v7() + RETURNS UUID + AS $$ + DECLARE + timestamp TIMESTAMPTZ; + microseconds INT; + BEGIN + timestamp = clock_timestamp(); + microseconds = (cast(extract(microseconds FROM timestamp)::INT - (floor(extract(milliseconds FROM timestamp))::INT * 1000) AS DOUBLE PRECISION) * 4.096)::INT; + + RETURN encode( + set_byte( + set_byte( + overlay(uuid_send(gen_random_uuid()) placing substring(int8send(floor(extract(epoch FROM timestamp) * 1000)::BIGINT) FROM 3) FROM 1 FOR 6 + ), + 6, (b'0111' || (microseconds >> 8)::bit(4))::bit(8)::int + ), + 7, microseconds::bit(8)::int + ), + 'hex')::UUID; + END + $$ + LANGUAGE PLPGSQL + SET search_path = '' + VOLATILE; + """) + + execute(""" + CREATE OR REPLACE FUNCTION timestamp_from_uuid_v7(_uuid uuid) + RETURNS TIMESTAMP WITHOUT TIME ZONE + AS $$ + SELECT to_timestamp(('x0000' || substr(_uuid::TEXT, 1, 8) || substr(_uuid::TEXT, 10, 4))::BIT(64)::BIGINT::NUMERIC / 1000); + $$ + LANGUAGE SQL + SET search_path = '' + IMMUTABLE PARALLEL SAFE STRICT; + """) + end + + def down do + # Uncomment this if you actually want to uninstall the extensions + # when this migration is rolled back: + execute("ALTER FUNCTION ash_raise_error(jsonb) VOLATILE;") + execute("ALTER FUNCTION ash_raise_error(jsonb, ANYCOMPATIBLE) VOLATILE") + end +end