diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 5248797..934ee1c 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -810,7 +810,7 @@ defmodule AshPostgres.DataLayer do |> Ash.Query.new() |> Ash.Query.set_context(through_relationship.context) |> Ash.Query.do_filter(through_relationship.filter) - |> Ash.Query.sort(through_relationship.sort) + |> Ash.Query.sort(through_relationship.sort, prepend?: true) |> Ash.Query.set_tenant(source_query.tenant) |> set_lateral_join_prefix(query) |> case do @@ -849,13 +849,15 @@ defmodule AshPostgres.DataLayer do source_query, relationship.through ), - as: ^1, on: field(through, ^destination_attribute_on_join_resource) == field(destination, ^destination_attribute), where: field(through, ^source_attribute_on_join_resource) == - field(parent_as(^0), ^source_attribute) + field(parent_as(^0), ^source_attribute), + select_merge: %{ + __lateral_join_source__: field(through, ^source_attribute_on_join_resource) + } ) |> set_subquery_prefix( source_query, @@ -882,13 +884,15 @@ defmodule AshPostgres.DataLayer do source_query, relationship.through ), - as: ^1, on: field(through, ^destination_attribute_on_join_resource) == field(destination, ^destination_attribute), where: field(through, ^source_attribute_on_join_resource) == - field(parent_as(^0), ^source_attribute) + field(parent_as(^0), ^source_attribute), + select_merge: %{ + __lateral_join_source__: field(through, ^source_attribute_on_join_resource) + } ) |> set_subquery_prefix( source_query, diff --git a/test/load_test.exs b/test/load_test.exs index 5e6151a..908e372 100644 --- a/test/load_test.exs +++ b/test/load_test.exs @@ -174,5 +174,52 @@ defmodule AshPostgres.Test.LoadTest do assert %{linked_posts: [%{title: "abc"}, %{title: "def"}]} = results end + + test "lateral join loads with many to many relationships are supported with aggregates" do + source_post = + Post + |> Ash.Changeset.new(%{title: "source"}) + |> Api.create!() + + destination_post = + Post + |> Ash.Changeset.new(%{title: "abc"}) + |> Api.create!() + + destination_post2 = + Post + |> Ash.Changeset.new(%{title: "def"}) + |> Api.create!() + + source_post + |> Ash.Changeset.new() + |> Ash.Changeset.manage_relationship(:linked_posts, [destination_post, destination_post2], + type: :append_and_remove + ) + |> Api.update!() + + linked_posts_query = + Post + |> Ash.Query.limit(1) + |> Ash.Query.sort(title: :asc) + + results = + source_post + |> Api.load!(linked_posts: linked_posts_query) + + assert %{linked_posts: [%{title: "abc"}]} = results + + linked_posts_query = + Post + |> Ash.Query.limit(2) + |> Ash.Query.sort(title: :asc) + |> Ash.Query.filter(count_of_comments_called_match == 0) + + results = + source_post + |> Api.load!(linked_posts: linked_posts_query) + + assert %{linked_posts: [%{title: "abc"}, %{title: "def"}]} = results + end end end diff --git a/test/support/resources/post_link.ex b/test/support/resources/post_link.ex index 4913ec1..58cac61 100644 --- a/test/support/resources/post_link.ex +++ b/test/support/resources/post_link.ex @@ -12,6 +12,10 @@ defmodule AshPostgres.Test.PostLink do defaults([:create, :read, :update, :destroy]) end + identities do + identity(:unique_link, [:source_post_id, :destination_post_id]) + end + relationships do belongs_to :source_post, AshPostgres.Test.Post do allow_nil?(false)