@@ -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