From 860d08538659657db0b08049c06506de2fee73ac Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 18 Jun 2024 07:50:54 -0400 Subject: [PATCH] fix: update ash_sql to fix query generation issues --- mix.exs | 2 +- mix.lock | 4 +- .../test_repo/posts/20240618102809.json | 427 ++++++++++++++++++ .../20240618102809_migrate_resources29.exs | 31 ++ test/atomics_test.exs | 16 +- test/migration_generator_test.exs | 2 +- test/support/resources/post.ex | 2 +- 7 files changed, 477 insertions(+), 7 deletions(-) create mode 100644 priv/resource_snapshots/test_repo/posts/20240618102809.json create mode 100644 priv/test_repo/migrations/20240618102809_migrate_resources29.exs diff --git a/mix.exs b/mix.exs index 11369d9..47f8977 100644 --- a/mix.exs +++ b/mix.exs @@ -163,7 +163,7 @@ defmodule AshPostgres.MixProject do defp deps do [ {:ash, ash_version("~> 3.0 and >= 3.0.13")}, - {:ash_sql, ash_sql_version("~> 0.2 and >= 0.2.4")}, + {:ash_sql, ash_sql_version("~> 0.2 and >= 0.2.6")}, {:ecto_sql, "~> 3.9"}, {:ecto, "~> 3.9"}, {:jason, "~> 1.0"}, diff --git a/mix.lock b/mix.lock index 7011367..21d65d6 100644 --- a/mix.lock +++ b/mix.lock @@ -1,5 +1,5 @@ %{ - "ash": {:hex, :ash, "3.0.12", "c5b8f8884dab1ab140f11ff6e5a5a3889eae6c5083cabc1952d65fb2a6d13b89", [:mix], [{:comparable, "~> 1.0", [hex: :comparable, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, ">= 0.8.1 and < 1.0.0-0", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.1.18 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b8c9b56784f71debda4fc23960ecb6645b39eaa26376ba0423b94c550632c07b"}, + "ash": {:hex, :ash, "3.0.13", "9111fa58362f82fd6687635c12ea96ce1958d24772e3c773fbc8b0893a7e7d47", [:mix], [{:comparable, "~> 1.0", [hex: :comparable, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, ">= 0.8.1 and < 1.0.0-0", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.1.18 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b5c1a9c428eac939a313bfea5e4509e8ac39beaa4707bd0deb5f7f310b1022c3"}, "ash_sql": {:hex, :ash_sql, "0.2.5", "8b50c3178776263b912e1b60e161e2bcf08a907a38abf703edf8a8a0a51b3fe2", [:mix], [{:ash, "~> 3.0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "0d5d8606738a17c4e8c0be4244623df721abee5072cee69d31c2711c36d0548f"}, "benchee": {:hex, :benchee, "1.3.1", "c786e6a76321121a44229dde3988fc772bca73ea75170a73fd5f4ddf1af95ccf", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "76224c58ea1d0391c8309a8ecbfe27d71062878f59bd41a390266bf4ac1cc56d"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, @@ -42,7 +42,7 @@ "simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"}, "sobelow": {:hex, :sobelow, "0.13.0", "218afe9075904793f5c64b8837cc356e493d88fddde126a463839351870b8d1e", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "cd6e9026b85fc35d7529da14f95e85a078d9dd1907a9097b3ba6ac7ebbe34a0d"}, "sourceror": {:hex, :sourceror, "1.3.0", "70ab9e8bf6df085a1effba4b49ad621b7153b065f69ef6cdb82e6088f2026029", [:mix], [], "hexpm", "1794c3ceeca4eb3f9437261721e4d9cbf846d7c64c7aee4f64062b18d5ce1eac"}, - "spark": {:hex, :spark, "2.2.1", "b4ec56c99b3a750f7db0d2651fc59dc59c4002a5e0d658dde968fc69bd451136", [:mix], [{:igniter, ">= 0.1.7 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "a6052f08ebe1ef152f86489151401210755bd81a9f0cbd737dd50819c65a0fc1"}, + "spark": {:hex, :spark, "2.2.3", "d41c45f0d7e8289499bf104173543be41ee1d8d213cb7503e9328b30751f2f13", [:mix], [{:igniter, ">= 0.1.7 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "401dec157c8b88634c27f241f4e374476081c577f51d2b08512f2c681c25a852"}, "spitfire": {:hex, :spitfire, "0.1.2", "49b85d59c170d671e7e49649f62f6fe0771743a61bc42bd7a203f98f322d99e2", [:mix], [], "hexpm", "21f04cf02df601d75e1551e393ee5c927e3986fbb7598f3e59f71d4ca544fd9b"}, "splode": {:hex, :splode, "0.2.4", "71046334c39605095ca4bed5d008372e56454060997da14f9868534c17b84b53", [:mix], [], "hexpm", "ca3b95f0d8d4b482b5357954fec857abd0fa3ea509d623334c1328e7382044c2"}, "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, diff --git a/priv/resource_snapshots/test_repo/posts/20240618102809.json b/priv/resource_snapshots/test_repo/posts/20240618102809.json new file mode 100644 index 0000000..9ea7711 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20240618102809.json @@ -0,0 +1,427 @@ +{ + "attributes": [ + { + "default": "fragment(\"gen_random_uuid()\")", + "size": null, + "type": "uuid", + "source": "id", + "references": null, + "allow_nil?": false, + "generated?": false, + "primary_key?": true + }, + { + "default": "nil", + "size": null, + "type": "text", + "source": "title_column", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": "timestamptz(6)", + "source": "datetime", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": "bigint", + "source": "score", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": "boolean", + "source": "public", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": "citext", + "source": "category", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "\"sponsored\"", + "size": null, + "type": "text", + "source": "type", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": "bigint", + "source": "price", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "\"0\"", + "size": null, + "type": "decimal", + "source": "decimal", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": "text", + "source": "status", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": "status", + "source": "status_enum", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": [ + "array", + "float" + ], + "source": "point", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": "custom_point", + "source": "composite_point", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": "map", + "source": "stuff", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": [ + "array", + "map" + ], + "source": "list_of_stuff", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": "text", + "source": "uniq_one", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": "text", + "source": "uniq_two", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": "text", + "source": "uniq_custom_one", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": "text", + "source": "uniq_custom_two", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": "text", + "source": "uniq_on_upper", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": "text", + "source": "uniq_if_contains_foo", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": [ + "array", + "text" + ], + "source": "list_containing_nils", + "references": null, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "fragment(\"(now() AT TIME ZONE 'utc')\")", + "size": null, + "type": "utc_datetime_usec", + "source": "created_at", + "references": null, + "allow_nil?": false, + "generated?": false, + "primary_key?": false + }, + { + "default": "fragment(\"(now() AT TIME ZONE 'utc')\")", + "size": null, + "type": "timestamptz(6)", + "source": "updated_at", + "references": null, + "allow_nil?": false, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": "uuid", + "source": "organization_id", + "references": { + "name": "posts_organization_id_fkey", + "table": "orgs", + "schema": "public", + "on_delete": null, + "multitenancy": { + "global": null, + "strategy": null, + "attribute": null + }, + "primary_key?": true, + "destination_attribute": "id", + "on_update": null, + "deferrable": false, + "index?": false, + "match_type": null, + "match_with": null, + "destination_attribute_default": null, + "destination_attribute_generated": null + }, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": "uuid", + "source": "parent_post_id", + "references": { + "name": "posts_parent_post_id_fkey", + "table": "posts", + "schema": "public", + "on_delete": null, + "multitenancy": { + "global": null, + "strategy": null, + "attribute": null + }, + "primary_key?": true, + "destination_attribute": "id", + "on_update": null, + "deferrable": false, + "index?": false, + "match_type": null, + "match_with": null, + "destination_attribute_default": null, + "destination_attribute_generated": null + }, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + }, + { + "default": "nil", + "size": null, + "type": "uuid", + "source": "author_id", + "references": { + "name": "posts_author_id_fkey", + "table": "authors", + "schema": "public", + "on_delete": null, + "multitenancy": { + "global": null, + "strategy": null, + "attribute": null + }, + "primary_key?": true, + "destination_attribute": "id", + "on_update": null, + "deferrable": false, + "index?": false, + "match_type": null, + "match_with": null, + "destination_attribute_default": null, + "destination_attribute_generated": null + }, + "allow_nil?": true, + "generated?": false, + "primary_key?": false + } + ], + "table": "posts", + "hash": "1E9B5F3F36E68AC20FDA61AC5AC645F86FCD61DA2EBD0C2716A91AE072737C25", + "repo": "Elixir.AshPostgres.TestRepo", + "identities": [ + { + "name": "uniq_if_contains_foo", + "keys": [ + "uniq_if_contains_foo" + ], + "where": "(uniq_if_contains_foo LIKE '%foo%')", + "base_filter": "type = 'sponsored'", + "nils_distinct?": true, + "all_tenants?": false, + "index_name": "posts_uniq_if_contains_foo_index" + }, + { + "name": "uniq_on_upper", + "keys": [ + "(UPPER(uniq_on_upper))" + ], + "where": null, + "base_filter": "type = 'sponsored'", + "nils_distinct?": true, + "all_tenants?": false, + "index_name": "posts_uniq_on_upper_index" + }, + { + "name": "uniq_one_and_two", + "keys": [ + "uniq_one", + "uniq_two" + ], + "where": null, + "base_filter": "type = 'sponsored'", + "nils_distinct?": true, + "all_tenants?": false, + "index_name": "posts_uniq_one_and_two_index" + } + ], + "schema": null, + "check_constraints": [ + { + "name": "price_must_be_positive", + "check": "price > 0", + "attribute": [ + "price" + ], + "base_filter": "type = 'sponsored'" + } + ], + "custom_indexes": [ + { + "message": "dude what the heck", + "name": null, + "table": null, + "include": null, + "where": null, + "prefix": null, + "fields": [ + { + "type": "atom", + "value": "uniq_custom_one" + }, + { + "type": "atom", + "value": "uniq_custom_two" + } + ], + "unique": true, + "all_tenants?": false, + "concurrently": true, + "error_fields": [ + "uniq_custom_one", + "uniq_custom_two" + ], + "nulls_distinct": true, + "using": null + } + ], + "base_filter": "type = 'sponsored'", + "multitenancy": { + "global": null, + "strategy": null, + "attribute": null + }, + "custom_statements": [], + "has_create_action": true +} \ No newline at end of file diff --git a/priv/test_repo/migrations/20240618102809_migrate_resources29.exs b/priv/test_repo/migrations/20240618102809_migrate_resources29.exs new file mode 100644 index 0000000..5a4aa79 --- /dev/null +++ b/priv/test_repo/migrations/20240618102809_migrate_resources29.exs @@ -0,0 +1,31 @@ +defmodule AshPostgres.TestRepo.Migrations.MigrateResources29 do + @moduledoc """ + Updates resources based on their most recent snapshots. + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + alter table(:posts) do + add( + :parent_post_id, + references(:posts, + column: :id, + name: "posts_parent_post_id_fkey", + type: :uuid, + prefix: "public" + ) + ) + end + end + + def down do + drop(constraint(:posts, "posts_parent_post_id_fkey")) + + alter table(:posts) do + remove(:parent_post_id) + end + end +end diff --git a/test/atomics_test.exs b/test/atomics_test.exs index 71dedea..95d4712 100644 --- a/test/atomics_test.exs +++ b/test/atomics_test.exs @@ -184,12 +184,24 @@ defmodule AshPostgres.AtomicsTest do test "relationships can be used in atomic update" do author = Author - |> Ash.Changeset.for_create(:create, %{first_name: "John", last_name: "Doe"}) + |> Ash.Changeset.for_create(:create, %{ + first_name: "John", + last_name: "Doe" + }) + |> Ash.create!() + + parent_post = + Post + |> Ash.Changeset.for_create(:create, %{price: 42, author_id: author.id}) |> Ash.create!() post = Post - |> Ash.Changeset.for_create(:create, %{price: 1, author_id: author.id}) + |> Ash.Changeset.for_create(:create, %{ + price: 1, + author_id: author.id, + parent_post_id: parent_post.id + }) |> Ash.create!() post = diff --git a/test/migration_generator_test.exs b/test/migration_generator_test.exs index 2b97ebc..1a32320 100644 --- a/test/migration_generator_test.exs +++ b/test/migration_generator_test.exs @@ -160,7 +160,7 @@ defmodule AshPostgres.MigrationGeneratorTest do # the migration creates unique_indexes based on the identities of the resource assert file_contents =~ - ~S{create unique_index(:posts, ["second_title", "title"], name: "posts_thing_index")} + ~S{create unique_index(:posts, ["title", "second_title"], name: "posts_thing_index")} # the migration creates unique_indexes using the `source` on the attributes of the identity on the resource assert file_contents =~ diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index 1516813..9bb77c0 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -144,7 +144,7 @@ defmodule AshPostgres.Test.Post do if is_nil(parent_post_id) do author.title else - parent_post.author.title + parent_post.author.first_name end ) )