Skip to content

Commit c0203db

Browse files
authored
Use after_verify callback and reduce compile-time work (#4552)
Closes #4293.
1 parent df8ef6a commit c0203db

File tree

4 files changed

+240
-215
lines changed

4 files changed

+240
-215
lines changed

examples/friends/mix.lock

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
%{
22
"connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
3-
"db_connection": {:hex, :db_connection, "2.6.0", "77d835c472b5b67fc4f29556dee74bf511bbafecdcaf98c27d27fa5918152086", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c2f992d15725e721ec7fbc1189d4ecdb8afef76648c746a8e1cad35e3b8a35f3"},
4-
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
3+
"db_connection": {:hex, :db_connection, "2.7.0", "b99faa9291bb09892c7da373bb82cba59aefa9b36300f6145c5f201c7adf48ec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dcf08f31b2701f857dfc787fbad78223d61a32204f217f15e881dd93e4bdd3ff"},
4+
"decimal": {:hex, :decimal, "2.2.0", "df3d06bb9517e302b1bd265c1e7f16cda51547ad9d99892049340841f3e15836", [:mix], [], "hexpm", "af8daf87384b51b7e611fb1a1f2c4d4876b65ef968fa8bd3adf44cff401c7f21"},
55
"ecto": {:hex, :ecto, "2.0.1", "cf97a4d353e14af3d3cc3b4452cfbd18b3aeee1fb4075475efeccec3853444a9", [:mix], [{:poison, "~> 1.5 or ~> 2.0", [hex: :poison, optional: true]}, {:sbroker, "~> 1.0-beta", [hex: :sbroker, optional: true]}, {:mariaex, "~> 0.7.7", [hex: :mariaex, optional: true]}, {:postgrex, "~> 0.11.2", [hex: :postgrex, optional: true]}, {:db_connection, "~> 1.0-rc.2", [hex: :db_connection, optional: true]}, {:decimal, "~> 1.0", [hex: :decimal, optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: false]}]},
66
"ecto_sql": {:hex, :ecto_sql, "3.11.3", "4eb7348ff8101fbc4e6bbc5a4404a24fecbe73a3372d16569526b0cf34ebc195", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.11.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e5f36e3d736b99c7fee3e631333b8394ade4bafe9d96d35669fca2d81c2be928"},
7-
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
7+
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
88
"poison": {:hex, :poison, "4.0.1", "bcb755a16fac91cad79bfe9fc3585bb07b9331e50cfe3420a24bcc2d735709ae", [:mix], [], "hexpm"},
99
"poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [], [], "hexpm"},
10-
"postgrex": {:hex, :postgrex, "0.18.0", "f34664101eaca11ff24481ed4c378492fed2ff416cd9b06c399e90f321867d7e", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "a042989ba1bc1cca7383ebb9e461398e3f89f868c92ce6671feb7ef132a252d1"},
11-
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
10+
"postgrex": {:hex, :postgrex, "0.19.3", "a0bda6e3bc75ec07fca5b0a89bffd242ca209a4822a9533e7d3e84ee80707e19", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "d31c28053655b78f47f948c85bb1cf86a9c1f8ead346ba1aa0d0df017fa05b61"},
11+
"telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"},
1212
}

lib/ecto/association.ex

+13-35
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,6 @@ defmodule Ecto.Association do
4444

4545
alias Ecto.Query.Builder.OrderBy
4646

47-
@doc """
48-
Helper to check if a queryable is compiled.
49-
"""
50-
def ensure_compiled(queryable, env) do
51-
if not is_atom(queryable) or queryable in env.context_modules do
52-
:skip
53-
else
54-
case Code.ensure_compiled(queryable) do
55-
{:module, _} -> :compiled
56-
{:error, :unavailable} -> :skip
57-
{:error, _} -> :not_found
58-
end
59-
end
60-
end
61-
6247
@doc """
6348
Builds the association struct.
6449
@@ -87,7 +72,7 @@ defmodule Ecto.Association do
8772
Useful for checking if associated modules exist without running
8873
into deadlocks.
8974
"""
90-
@callback after_compile_validation(t, Macro.Env.t()) :: :ok | {:error, String.t()}
75+
@callback after_verify_validation(t) :: :ok | {:error, String.t()}
9176

9277
@doc """
9378
Builds a struct for the given association.
@@ -771,14 +756,12 @@ defmodule Ecto.Association.Has do
771756
]
772757

773758
@impl true
774-
def after_compile_validation(%{queryable: queryable, related_key: related_key}, env) do
775-
compiled = Ecto.Association.ensure_compiled(queryable, env)
776-
759+
def after_verify_validation(%{queryable: queryable, related_key: related_key}) do
777760
cond do
778-
compiled == :skip ->
761+
not is_atom(queryable) ->
779762
:ok
780763

781-
compiled == :not_found ->
764+
not Code.ensure_loaded?(queryable) ->
782765
{:error, "associated schema #{inspect(queryable)} does not exist"}
783766

784767
not function_exported?(queryable, :__schema__, 2) ->
@@ -1040,7 +1023,7 @@ defmodule Ecto.Association.HasThrough do
10401023
]
10411024

10421025
@impl true
1043-
def after_compile_validation(_, _) do
1026+
def after_verify_validation(_) do
10441027
:ok
10451028
end
10461029

@@ -1143,14 +1126,12 @@ defmodule Ecto.Association.BelongsTo do
11431126
]
11441127

11451128
@impl true
1146-
def after_compile_validation(%{queryable: queryable, related_key: related_key}, env) do
1147-
compiled = Ecto.Association.ensure_compiled(queryable, env)
1148-
1129+
def after_verify_validation(%{queryable: queryable, related_key: related_key}) do
11491130
cond do
1150-
compiled == :skip ->
1131+
not is_atom(queryable) ->
11511132
:ok
11521133

1153-
compiled == :not_found ->
1134+
not Code.ensure_loaded?(queryable) ->
11541135
{:error, "associated schema #{inspect(queryable)} does not exist"}
11551136

11561137
not function_exported?(queryable, :__schema__, 2) ->
@@ -1346,24 +1327,21 @@ defmodule Ecto.Association.ManyToMany do
13461327
]
13471328

13481329
@impl true
1349-
def after_compile_validation(%{queryable: queryable, join_through: join_through}, env) do
1350-
compiled = Ecto.Association.ensure_compiled(queryable, env)
1351-
join_compiled = Ecto.Association.ensure_compiled(join_through, env)
1352-
1330+
def after_verify_validation(%{queryable: queryable, join_through: join_through}) do
13531331
cond do
1354-
compiled == :skip ->
1332+
not is_atom(queryable) ->
13551333
:ok
13561334

1357-
compiled == :not_found ->
1335+
not Code.ensure_loaded?(queryable) ->
13581336
{:error, "associated schema #{inspect(queryable)} does not exist"}
13591337

13601338
not function_exported?(queryable, :__schema__, 2) ->
13611339
{:error, "associated module #{inspect(queryable)} is not an Ecto schema"}
13621340

1363-
join_compiled == :skip ->
1341+
not is_atom(join_through) ->
13641342
:ok
13651343

1366-
join_compiled == :not_found ->
1344+
not Code.ensure_loaded?(join_through) ->
13671345
{:error, ":join_through schema #{inspect(join_through)} does not exist"}
13681346

13691347
not function_exported?(join_through, :__schema__, 2) ->

0 commit comments

Comments
 (0)