Skip to content

Commit 85620a0

Browse files
committed
improvement: don't sort identity keys.
There are important implications here, specifically that there are optimizations that can be had based on what the first column in a unique constraint is, and we want to make sure that can be taken advantage of. closes #313
1 parent 49db2be commit 85620a0

File tree

3 files changed

+142
-8
lines changed

3 files changed

+142
-8
lines changed

lib/migration_generator/migration_generator.ex

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ defmodule AshPostgres.MigrationGenerator do
557557
|> Kernel.!()
558558
end)
559559
|> Enum.uniq_by(fn identity ->
560-
{Enum.sort(identity.keys), identity.base_filter}
560+
{identity.keys, identity.base_filter}
561561
end)
562562

563563
new_snapshot = %{new_snapshot | identities: all_identities}
@@ -740,7 +740,7 @@ defmodule AshPostgres.MigrationGenerator do
740740

741741
identities =
742742
Enum.reject(identities, fn identity ->
743-
Enum.sort(identity.keys) == primary_key
743+
identity.keys == primary_key
744744
end)
745745

746746
{primary_key, identities}
@@ -1817,7 +1817,7 @@ defmodule AshPostgres.MigrationGenerator do
18171817
Enum.reject(old_snapshot.identities, fn old_identity ->
18181818
Enum.find(snapshot.identities, fn identity ->
18191819
identity.name == old_identity.name &&
1820-
Enum.sort(old_identity.keys) == Enum.sort(identity.keys) &&
1820+
old_identity.keys == identity.keys &&
18211821
old_identity.base_filter == identity.base_filter &&
18221822
old_identity.all_tenants? == identity.all_tenants? &&
18231823
old_identity.nils_distinct? == identity.nils_distinct? &&
@@ -1874,7 +1874,7 @@ defmodule AshPostgres.MigrationGenerator do
18741874
if identity.all_tenants? do
18751875
Enum.find(old_snapshot.identities, fn old_identity ->
18761876
old_identity.name == identity.name &&
1877-
Enum.sort(old_identity.keys) == Enum.sort(identity.keys) &&
1877+
old_identity.keys == identity.keys &&
18781878
old_identity.base_filter == identity.base_filter &&
18791879
old_identity.all_tenants? == identity.all_tenants? &&
18801880
old_identity.nils_distinct? == identity.nils_distinct? &&
@@ -1888,7 +1888,7 @@ defmodule AshPostgres.MigrationGenerator do
18881888
Enum.reject(snapshot.identities, fn identity ->
18891889
Enum.find(old_snapshot.identities, fn old_identity ->
18901890
old_identity.name == identity.name &&
1891-
Enum.sort(old_identity.keys) == Enum.sort(identity.keys) &&
1891+
old_identity.keys == identity.keys &&
18921892
old_identity.base_filter == identity.base_filter &&
18931893
old_identity.all_tenants? == identity.all_tenants? &&
18941894
old_identity.nils_distinct? == identity.nils_distinct? &&
@@ -3244,9 +3244,6 @@ defmodule AshPostgres.MigrationGenerator do
32443244
defp load_identity(identity, table) do
32453245
identity
32463246
|> Map.update!(:name, &maybe_to_atom/1)
3247-
|> Map.update!(:keys, fn keys ->
3248-
Enum.sort(keys)
3249-
end)
32503247
|> add_index_name(table)
32513248
|> Map.put_new(:base_filter, nil)
32523249
|> Map.put_new(:all_tenants?, false)
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
{
2+
"attributes": [
3+
{
4+
"default": "\"active\"",
5+
"size": null,
6+
"type": "text",
7+
"source": "state",
8+
"references": null,
9+
"primary_key?": false,
10+
"allow_nil?": true,
11+
"generated?": false
12+
},
13+
{
14+
"default": "nil",
15+
"size": null,
16+
"type": "uuid",
17+
"source": "source_post_id",
18+
"references": {
19+
"name": "post_links_source_post_id_fkey",
20+
"table": "posts",
21+
"multitenancy": {
22+
"global": null,
23+
"strategy": null,
24+
"attribute": null
25+
},
26+
"primary_key?": true,
27+
"destination_attribute": "id",
28+
"schema": "public",
29+
"deferrable": false,
30+
"index?": false,
31+
"destination_attribute_default": null,
32+
"destination_attribute_generated": null,
33+
"on_delete": null,
34+
"on_update": null,
35+
"match_with": null,
36+
"match_type": null
37+
},
38+
"primary_key?": true,
39+
"allow_nil?": false,
40+
"generated?": false
41+
},
42+
{
43+
"default": "nil",
44+
"size": null,
45+
"type": "uuid",
46+
"source": "destination_post_id",
47+
"references": {
48+
"name": "post_links_destination_post_id_fkey",
49+
"table": "posts",
50+
"multitenancy": {
51+
"global": null,
52+
"strategy": null,
53+
"attribute": null
54+
},
55+
"primary_key?": true,
56+
"destination_attribute": "id",
57+
"schema": "public",
58+
"deferrable": false,
59+
"index?": false,
60+
"destination_attribute_default": null,
61+
"destination_attribute_generated": null,
62+
"on_delete": null,
63+
"on_update": null,
64+
"match_with": null,
65+
"match_type": null
66+
},
67+
"primary_key?": true,
68+
"allow_nil?": false,
69+
"generated?": false
70+
}
71+
],
72+
"table": "post_links",
73+
"hash": "AF3FA145E25BB98CD83D51B551C8E623F1CE088DA1DE09B9905CA5E4B085C872",
74+
"repo": "Elixir.AshPostgres.TestRepo",
75+
"multitenancy": {
76+
"global": null,
77+
"strategy": null,
78+
"attribute": null
79+
},
80+
"schema": null,
81+
"identities": [
82+
{
83+
"name": "unique_link",
84+
"keys": [
85+
"destination_post_id",
86+
"source_post_id"
87+
],
88+
"where": null,
89+
"base_filter": null,
90+
"all_tenants?": false,
91+
"nils_distinct?": true,
92+
"index_name": "post_links_unique_link_index"
93+
}
94+
],
95+
"has_create_action": true,
96+
"custom_indexes": [],
97+
"custom_statements": [],
98+
"base_filter": null,
99+
"check_constraints": []
100+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
defmodule AshPostgres.TestRepo.Migrations.MigrateResources27 do
2+
@moduledoc """
3+
Updates resources based on their most recent snapshots.
4+
5+
This file was autogenerated with `mix ash_postgres.generate_migrations`
6+
"""
7+
8+
use Ecto.Migration
9+
10+
def up do
11+
drop_if_exists(
12+
unique_index(:post_links, ["source_post_id", "destination_post_id"],
13+
name: "post_links_unique_link_index"
14+
)
15+
)
16+
17+
create(
18+
unique_index(:post_links, ["destination_post_id", "source_post_id"],
19+
name: "post_links_unique_link_index"
20+
)
21+
)
22+
end
23+
24+
def down do
25+
drop_if_exists(
26+
unique_index(:post_links, ["destination_post_id", "source_post_id"],
27+
name: "post_links_unique_link_index"
28+
)
29+
)
30+
31+
create(
32+
unique_index(:post_links, ["source_post_id", "destination_post_id"],
33+
name: "post_links_unique_link_index"
34+
)
35+
)
36+
end
37+
end

0 commit comments

Comments
 (0)