Skip to content

Commit 5a417a4

Browse files
authored
test: binding error when loading aggregate (#657)
1 parent 14397be commit 5a417a4

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

test/aggregate_test.exs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,61 @@ defmodule AshSql.AggregateTest do
101101
assert read_post.count_of_comments == 1
102102
end
103103

104+
test "loading optimizable first aggregate with relationship filter does not cause binding errors" do
105+
org =
106+
Organization
107+
|> Ash.Changeset.for_create(:create, %{name: "The Org"})
108+
|> Ash.create!()
109+
110+
user =
111+
User
112+
|> Ash.Changeset.for_create(:create, %{})
113+
|> Ash.Changeset.manage_relationship(:organization, org, type: :append_and_remove)
114+
|> Ash.create!()
115+
116+
author =
117+
Author
118+
|> Ash.Changeset.for_create(:create, %{first_name: "John", last_name: "Doe"})
119+
|> Ash.create!()
120+
121+
post =
122+
Post
123+
|> Ash.Changeset.for_create(:create, %{title: "Test Post"})
124+
|> Ash.Changeset.manage_relationship(:organization, org, type: :append_and_remove)
125+
|> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove)
126+
|> Ash.create!()
127+
128+
comment =
129+
Comment
130+
|> Ash.Changeset.for_create(:create, %{title: "Test Comment"})
131+
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
132+
|> Ash.create!()
133+
134+
Rating
135+
|> Ash.Changeset.for_create(:create, %{score: 5, resource_id: comment.id})
136+
|> Ash.Changeset.set_context(%{data_layer: %{table: "comment_ratings"}})
137+
|> Ash.create!()
138+
139+
# 1. Filter through :author adds a binding for the :author relationship
140+
# 2. Policy joins through has_many which adds DISTINCT
141+
# 3. limit(1) also triggers subquery wrapping condition
142+
# 4. Loading :count_of_comment_ratings (non-optimizable, through [:comments, :ratings])
143+
# triggers wrap_in_subquery_for_aggregates
144+
# 5. Loading :author_first_name (optimizable first through belongs_to :author)
145+
# after wrapping, code tries to reuse the :author binding from before wrapping
146+
loaded_post =
147+
Post
148+
|> Ash.Query.filter(id == ^post.id and author.first_name == "John")
149+
|> Ash.Query.limit(1)
150+
|> Ash.Query.load([:author_first_name, :count_of_comment_ratings])
151+
|> Ash.read!(actor: user)
152+
|> hd()
153+
154+
assert loaded_post.id == post.id
155+
assert loaded_post.author_first_name == "John"
156+
assert loaded_post.count_of_comment_ratings == 1
157+
end
158+
104159
test "nested filters on aggregates works" do
105160
org =
106161
Organization

0 commit comments

Comments
 (0)