@@ -171,6 +171,71 @@ defmodule AshPostgres.BulkCreateTest do
171171 end )
172172 end
173173
174+ @ tag :focus
175+ test "bulk upsert returns skipped records with return_skipped_upsert?" do
176+ assert [
177+ { :ok , % { title: "fredfoo" , uniq_if_contains_foo: "1foo" , price: 10 } } ,
178+ { :ok , % { title: "georgefoo" , uniq_if_contains_foo: "2foo" , price: 20 } } ,
179+ { :ok , % { title: "herbert" , uniq_if_contains_foo: "3" , price: 30 } }
180+ ] =
181+ Ash . bulk_create! (
182+ [
183+ % { title: "fredfoo" , uniq_if_contains_foo: "1foo" , price: 10 } ,
184+ % { title: "georgefoo" , uniq_if_contains_foo: "2foo" , price: 20 } ,
185+ % { title: "herbert" , uniq_if_contains_foo: "3" , price: 30 }
186+ ] ,
187+ Post ,
188+ :create ,
189+ return_stream?: true ,
190+ return_records?: true
191+ )
192+ |> Enum . sort_by ( fn { :ok , result } -> result . title end )
193+
194+ results =
195+ Ash . bulk_create! (
196+ [
197+ % { title: "fredfoo" , uniq_if_contains_foo: "1foo" , price: 10 } ,
198+ % { title: "georgefoo" , uniq_if_contains_foo: "2foo" , price: 20_000 } ,
199+ % { title: "herbert" , uniq_if_contains_foo: "3" , price: 30 }
200+ ] ,
201+ Post ,
202+ :upsert_with_no_filter ,
203+ return_stream?: true ,
204+ upsert_condition: expr ( price != upsert_conflict ( :price ) ) ,
205+ return_errors?: true ,
206+ return_records?: true ,
207+ return_skipped_upsert?: true
208+ )
209+ |> Enum . sort_by ( fn
210+ { :ok , result } ->
211+ result . title
212+
213+ _ ->
214+ nil
215+ end )
216+
217+ assert [
218+ { :ok , skipped } ,
219+ { :ok , updated } ,
220+ { :ok , no_conflict }
221+ ] = results
222+
223+ # "fredfoo" was skipped because price matches (10 == 10)
224+ assert skipped . title == "fredfoo"
225+ assert skipped . price == 10
226+ assert Ash.Resource . get_metadata ( skipped , :upsert_skipped ) == true
227+
228+ # "georgefoo" was updated because price differs (20 -> 20_000)
229+ assert updated . title == "georgefoo"
230+ assert updated . price == 20_000
231+ refute Ash.Resource . get_metadata ( updated , :upsert_skipped )
232+
233+ # "herbert" had no conflict (doesn't match identity)
234+ assert no_conflict . title == "herbert"
235+ assert no_conflict . price == 30
236+ refute Ash.Resource . get_metadata ( no_conflict , :upsert_skipped )
237+ end
238+
174239 # confirmed that this doesn't work because it can't. An upsert must map to a potentially successful insert.
175240 # leaving this test here for posterity
176241 # test "bulk creates can upsert with id" do
0 commit comments