Skip to content

Commit

Permalink
Use after_verify callback and reduce compile-time work (#4552)
Browse files Browse the repository at this point in the history
Closes #4293.
  • Loading branch information
josevalim authored Nov 28, 2024
1 parent df8ef6a commit c0203db
Show file tree
Hide file tree
Showing 4 changed files with 240 additions and 215 deletions.
10 changes: 5 additions & 5 deletions examples/friends/mix.lock
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
%{
"connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
"db_connection": {:hex, :db_connection, "2.6.0", "77d835c472b5b67fc4f29556dee74bf511bbafecdcaf98c27d27fa5918152086", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c2f992d15725e721ec7fbc1189d4ecdb8afef76648c746a8e1cad35e3b8a35f3"},
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
"db_connection": {:hex, :db_connection, "2.7.0", "b99faa9291bb09892c7da373bb82cba59aefa9b36300f6145c5f201c7adf48ec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dcf08f31b2701f857dfc787fbad78223d61a32204f217f15e881dd93e4bdd3ff"},
"decimal": {:hex, :decimal, "2.2.0", "df3d06bb9517e302b1bd265c1e7f16cda51547ad9d99892049340841f3e15836", [:mix], [], "hexpm", "af8daf87384b51b7e611fb1a1f2c4d4876b65ef968fa8bd3adf44cff401c7f21"},
"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]}]},
"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"},
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
"poison": {:hex, :poison, "4.0.1", "bcb755a16fac91cad79bfe9fc3585bb07b9331e50cfe3420a24bcc2d735709ae", [:mix], [], "hexpm"},
"poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [], [], "hexpm"},
"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"},
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
"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"},
"telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"},
}
48 changes: 13 additions & 35 deletions lib/ecto/association.ex
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,6 @@ defmodule Ecto.Association do

alias Ecto.Query.Builder.OrderBy

@doc """
Helper to check if a queryable is compiled.
"""
def ensure_compiled(queryable, env) do
if not is_atom(queryable) or queryable in env.context_modules do
:skip
else
case Code.ensure_compiled(queryable) do
{:module, _} -> :compiled
{:error, :unavailable} -> :skip
{:error, _} -> :not_found
end
end
end

@doc """
Builds the association struct.
Expand Down Expand Up @@ -87,7 +72,7 @@ defmodule Ecto.Association do
Useful for checking if associated modules exist without running
into deadlocks.
"""
@callback after_compile_validation(t, Macro.Env.t()) :: :ok | {:error, String.t()}
@callback after_verify_validation(t) :: :ok | {:error, String.t()}

@doc """
Builds a struct for the given association.
Expand Down Expand Up @@ -771,14 +756,12 @@ defmodule Ecto.Association.Has do
]

@impl true
def after_compile_validation(%{queryable: queryable, related_key: related_key}, env) do
compiled = Ecto.Association.ensure_compiled(queryable, env)

def after_verify_validation(%{queryable: queryable, related_key: related_key}) do
cond do
compiled == :skip ->
not is_atom(queryable) ->
:ok

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

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

@impl true
def after_compile_validation(_, _) do
def after_verify_validation(_) do
:ok
end

Expand Down Expand Up @@ -1143,14 +1126,12 @@ defmodule Ecto.Association.BelongsTo do
]

@impl true
def after_compile_validation(%{queryable: queryable, related_key: related_key}, env) do
compiled = Ecto.Association.ensure_compiled(queryable, env)

def after_verify_validation(%{queryable: queryable, related_key: related_key}) do
cond do
compiled == :skip ->
not is_atom(queryable) ->
:ok

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

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

@impl true
def after_compile_validation(%{queryable: queryable, join_through: join_through}, env) do
compiled = Ecto.Association.ensure_compiled(queryable, env)
join_compiled = Ecto.Association.ensure_compiled(join_through, env)

def after_verify_validation(%{queryable: queryable, join_through: join_through}) do
cond do
compiled == :skip ->
not is_atom(queryable) ->
:ok

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

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

join_compiled == :skip ->
not is_atom(join_through) ->
:ok

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

not function_exported?(join_through, :__schema__, 2) ->
Expand Down
Loading

0 comments on commit c0203db

Please sign in to comment.