fix: properly set binding names for many to many join filters

This commit is contained in:
Zach Daniel 2022-12-04 15:01:24 -05:00
parent 7d0663588f
commit ee8e77dca4
4 changed files with 76 additions and 26 deletions

View file

@ -577,11 +577,23 @@ defmodule AshPostgres.Aggregate do
join_relationship =
Ash.Resource.Info.relationship(relationship.source, relationship.join_relationship)
through_bindings =
root_query
|> Map.delete(:__ash_bindings__)
|> AshPostgres.DataLayer.default_bindings(
root_query.__ash_bindings__.resource,
root_query.__ash_bindings__.context
)
|> Map.get(:__ash_bindings__)
|> Map.put(:bindings, %{1 => %{path: [], source: relationship.through, type: :left}})
through =
case AshPostgres.Join.maybe_get_resource_query(
relationship.through,
join_relationship,
root_query
root_query,
[],
through_bindings
) do
{:ok, query} ->
query

View file

@ -732,20 +732,37 @@ defmodule AshPostgres.Expr do
bindings
)
free_binding = filtered.__ash_bindings__.current
exists_query =
if first_relationship.type == :many_to_many do
through_relationship =
Ash.Resource.Info.relationship(resource, first_relationship.join_relationship)
through_bindings =
query
|> Map.delete(:__ash_bindings__)
|> AshPostgres.DataLayer.default_bindings(
query.__ash_bindings__.resource,
query.__ash_bindings__.context
)
|> Map.get(:__ash_bindings__)
|> Map.put(:bindings, %{
free_binding => %{path: [], source: first_relationship.through, type: :left}
})
{:ok, through} =
AshPostgres.Join.maybe_get_resource_query(
first_relationship.through,
through_relationship,
query
query,
[],
through_bindings
)
Ecto.Query.from(destination in filtered,
join: through in ^through,
as: ^free_binding,
on:
field(through, ^first_relationship.destination_attribute_on_join_resource) ==
field(destination, ^first_relationship.destination_attribute),
@ -763,7 +780,7 @@ defmodule AshPostgres.Expr do
)
end
Ecto.Query.dynamic(exists(exists_query))
Ecto.Query.dynamic(exists(Ecto.Query.subquery(exists_query)))
end
defp do_dynamic_expr(

View file

@ -109,7 +109,7 @@ defmodule AshPostgres.Join do
relationship,
root_query,
path \\ [],
use_root_query_bindings? \\ false
bindings \\ nil
) do
resource
|> Ash.Query.new(nil, base_filter?: false)
@ -135,14 +135,15 @@ defmodule AshPostgres.Join do
ash_query,
resource,
path,
use_root_query_bindings?
bindings
)
|> do_relationship_filter(
relationship.filter,
root_query,
ash_query,
resource,
path
path,
bindings
)
{:ok, query}
@ -156,7 +157,7 @@ defmodule AshPostgres.Join do
end
end
defp do_relationship_filter(query, nil, _, _, _, _), do: query
defp do_relationship_filter(query, nil, _, _, _, _, _), do: query
defp do_relationship_filter(
query,
@ -164,7 +165,8 @@ defmodule AshPostgres.Join do
root_query,
ash_query,
resource,
path
path,
bindings
) do
filter =
resource
@ -176,18 +178,19 @@ defmodule AshPostgres.Join do
)
dynamic =
AshPostgres.Expr.dynamic_expr(
root_query,
Ash.Filter.move_to_relationship_path(filter, path),
root_query.__ash_bindings__,
true
)
if bindings do
filter = Ash.Filter.move_to_relationship_path(filter, path)
AshPostgres.Expr.dynamic_expr(root_query, filter, bindings, true)
else
AshPostgres.Expr.dynamic_expr(query, filter, query.__ash_bindings__, true)
end
{:ok, query} = join_all_relationships(query, filter)
from(row in query, where: ^dynamic)
end
defp do_base_filter(query, root_query, ash_query, resource, path, use_root_query_bindings?) do
defp do_base_filter(query, root_query, ash_query, resource, path, bindings) do
case Ash.Resource.Info.base_filter(resource) do
nil ->
query
@ -203,10 +206,10 @@ defmodule AshPostgres.Join do
)
dynamic =
if use_root_query_bindings? do
if bindings do
filter = Ash.Filter.move_to_relationship_path(filter, path)
AshPostgres.Expr.dynamic_expr(root_query, filter, root_query.__ash_bindings__, true)
AshPostgres.Expr.dynamic_expr(root_query, filter, bindings, true)
else
AshPostgres.Expr.dynamic_expr(query, filter, query.__ash_bindings__, true)
end
@ -389,14 +392,20 @@ defmodule AshPostgres.Join do
%{aggregate | load: aggregate.name}
end)
use_root_query_bindings? = Enum.empty?(used_aggregates)
use_root_query_bindings? =
Enum.empty?(used_aggregates) && !match?({:aggregate, _, _, _}, kind)
root_bindings =
if use_root_query_bindings? do
query.__ash_bindings__
end
case maybe_get_resource_query(
relationship.destination,
relationship,
query,
full_path,
use_root_query_bindings?
root_bindings
) do
{:error, error} ->
{:error, error}
@ -554,7 +563,13 @@ defmodule AshPostgres.Join do
%{aggregate | load: aggregate.name}
end)
use_root_query_bindings? = Enum.empty?(used_aggregates)
use_root_query_bindings? =
Enum.empty?(used_aggregates) && !match?({:aggregate, _, _, _}, kind)
root_bindings =
if use_root_query_bindings? do
query.__ash_bindings__
end
with {:ok, relationship_through} <-
maybe_get_resource_query(
@ -562,7 +577,7 @@ defmodule AshPostgres.Join do
join_relationship,
query,
join_path,
use_root_query_bindings?
root_bindings
),
{:ok, relationship_destination} <-
maybe_get_resource_query(
@ -570,7 +585,7 @@ defmodule AshPostgres.Join do
relationship,
query,
path,
use_root_query_bindings?
root_bindings
) do
relationship_through =
relationship_through
@ -703,14 +718,20 @@ defmodule AshPostgres.Join do
%{aggregate | load: aggregate.name}
end)
use_root_query_bindings? = Enum.empty?(used_aggregates)
use_root_query_bindings? =
Enum.empty?(used_aggregates) && !match?({:aggregate, _, _, _}, kind)
root_bindings =
if use_root_query_bindings? do
query.__ash_bindings__
end
case maybe_get_resource_query(
relationship.destination,
relationship,
query,
full_path,
use_root_query_bindings?
root_bindings
) do
{:error, error} ->
{:error, error}

View file

@ -11,7 +11,7 @@
"earmark_parser": {:hex, :earmark_parser, "1.4.25", "2024618731c55ebfcc5439d756852ec4e85978a39d0d58593763924d9a15916f", [:mix], [], "hexpm", "56749c5e1c59447f7b7a23ddb235e4b3defe276afc220a6227237f3efe83f51e"},
"ecto": {:hex, :ecto, "3.9.2", "017db3bc786ff64271108522c01a5d3f6ba0aea5c84912cfb0dd73bf13684108", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "21466d5177e09e55289ac7eade579a642578242c7a3a9f91ad5c6583337a9d15"},
"ecto_sql": {:hex, :ecto_sql, "3.9.0", "2bb21210a2a13317e098a420a8c1cc58b0c3421ab8e3acfa96417dab7817918c", [:mix], [{:db_connection, "~> 2.5 or ~> 2.4.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 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", "a8f3f720073b8b1ac4c978be25fa7960ed7fd44997420c304a4a2e200b596453"},
"elixir_make": {:hex, :elixir_make, "0.6.3", "bc07d53221216838d79e03a8019d0839786703129599e9619f4ab74c8c096eac", [:mix], [], "hexpm", "f5cbd651c5678bcaabdbb7857658ee106b12509cd976c2c2fca99688e1daf716"},
"elixir_make": {:hex, :elixir_make, "0.7.0", "03e6a43ac701a2afee73bb5dd030b4dcddcb403bf81abb4753c1da64521cd05d", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "b1ccb45cc1c5df16349473b52adbd718f362585a5481d761b8a9fdb45f25b303"},
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
"ets": {:hex, :ets, "0.8.1", "8ff9bcda5682b98493f8878fc9dbd990e48d566cba8cce59f7c2a78130da29ea", [:mix], [], "hexpm", "6be41b50adb5bc5c43626f25ea2d0af1f4a242fb3fad8d53f0c67c20b78915cc"},
"ex_check": {:hex, :ex_check, "0.14.0", "d6fbe0bcc51cf38fea276f5bc2af0c9ae0a2bb059f602f8de88709421dae4f0e", [:mix], [], "hexpm", "8a602e98c66e6a4be3a639321f1f545292042f290f91fa942a285888c6868af0"},
@ -35,7 +35,7 @@
"postgrex": {:hex, :postgrex, "0.16.5", "fcc4035cc90e23933c5d69a9cd686e329469446ef7abba2cf70f08e2c4b69810", [:mix], [{:connection, "~> 1.1", [hex: :connection, repo: "hexpm", optional: false]}, {: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", "edead639dc6e882618c01d8fc891214c481ab9a3788dfe38dd5e37fd1d5fb2e8"},
"sobelow": {:hex, :sobelow, "0.11.1", "23438964486f8112b41e743bbfd402da3e5b296fdc9eacab29914b79c48916dd", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "9897363a7eff96f4809304a90aad819e2ad5e5d24db547af502885146746a53c"},
"sourceror": {:hex, :sourceror, "0.11.2", "549ce48be666421ac60cfb7f59c8752e0d393baa0b14d06271d3f6a8c1b027ab", [:mix], [], "hexpm", "9ab659118896a36be6eec68ff7b0674cba372fc8e210b1e9dc8cf2b55bb70dfb"},
"spark": {:hex, :spark, "0.2.13", "6a27fa40830cfdeb51ca417cb775c9b9b7583ab3b55c9b70ea9dae04b92a767a", [:mix], [{:nimble_options, "~> 0.4.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:sourceror, "~> 0.1", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "8bc0c5e226c2d6be6365a7a9d5bdd394cd9fe4bc0c2074a1ad32b17bc8610c61"},
"spark": {:hex, :spark, "0.2.17", "90c201fefe02eba9611733454c6b330ec2adc6eb823ce7aa1f6c83e38c05cd62", [:mix], [{:nimble_options, "~> 0.4.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:sourceror, "~> 0.1", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "a2a9375bb6d06aab960c6990688258d820160e454e3d22e9669ea0eda37a2e07"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
"stream_data": {:hex, :stream_data, "0.5.0", "b27641e58941685c75b353577dc602c9d2c12292dd84babf506c2033cd97893e", [:mix], [], "hexpm", "012bd2eec069ada4db3411f9115ccafa38540a3c78c4c0349f151fc761b9e271"},
"telemetry": {:hex, :telemetry, "1.1.0", "a589817034a27eab11144ad24d5c0f9fab1f58173274b1e9bae7074af9cbee51", [:rebar3], [], "hexpm", "b727b2a1f75614774cff2d7565b64d0dfa5bd52ba517f16543e6fc7efcc0df48"},