@@ -2123,35 +2123,63 @@ defmodule AshPostgres.DataLayer do
21232123 { Map . take ( r , keys ) , r }
21242124 end )
21252125
2126- results =
2127- changesets
2128- |> Enum . map ( fn changeset ->
2129- identity =
2130- changeset . attributes
2131- |> Map . take ( keys )
2126+ cant_map_results_to_changesets =
2127+ any_generated_keys_missing? ( keys , resource , changesets )
21322128
2133- result_for_changeset = Map . get ( results_by_identity , identity )
2134-
2135- if result_for_changeset do
2129+ results =
2130+ if cant_map_results_to_changesets do
2131+ results
2132+ |> Enum . zip ( changesets )
2133+ |> Enum . map ( fn { result , changeset } ->
21362134 if ! opts [ :upsert? ] do
2137- maybe_create_tenant! ( resource , result_for_changeset )
2135+ maybe_create_tenant! ( resource , result )
21382136 end
21392137
21402138 case get_bulk_operation_metadata ( changeset ) do
21412139 { index , metadata_key } ->
2142- Ash.Resource . put_metadata ( result_for_changeset , metadata_key , index )
2140+ Ash.Resource . put_metadata ( result , metadata_key , index )
21432141
21442142 nil ->
21452143 # Compatibility fallback
21462144 Ash.Resource . put_metadata (
2147- result_for_changeset ,
2145+ result ,
21482146 :bulk_create_index ,
21492147 changeset . context [ :bulk_create ] [ :index ]
21502148 )
21512149 end
2152- end
2153- end )
2154- |> Enum . filter ( & & 1 )
2150+ end )
2151+ else
2152+ changesets
2153+ |> Enum . map ( fn changeset ->
2154+ identity =
2155+ changeset . attributes
2156+ |> Map . take ( keys )
2157+
2158+ result_for_changeset = Map . get ( results_by_identity , identity )
2159+
2160+ if result_for_changeset do
2161+ if ! opts [ :upsert? ] do
2162+ maybe_create_tenant! ( resource , result_for_changeset )
2163+ end
2164+
2165+ case get_bulk_operation_metadata ( changeset ) do
2166+ { index , metadata_key } ->
2167+ Ash.Resource . put_metadata ( result_for_changeset , metadata_key , index )
2168+
2169+ nil ->
2170+ # Compatibility fallback
2171+ Ash.Resource . put_metadata (
2172+ result_for_changeset ,
2173+ :bulk_create_index ,
2174+ changeset . context [ :bulk_create ] [ :index ]
2175+ )
2176+ end
2177+ end
2178+ end )
2179+ |> Enum . concat ( results )
2180+ |> Enum . filter ( & & 1 )
2181+ |> Enum . uniq_by ( & Map . take ( & 1 , keys ) )
2182+ end
21552183
21562184 { :ok , results }
21572185 end
@@ -3737,6 +3765,16 @@ defmodule AshPostgres.DataLayer do
37373765 end
37383766 end
37393767
3768+ # checks if any of the attributes in the list of keys are generated and missing from any of the changesets
3769+ # if so, we can't match the created record to the changeset by the identity and just need to zip the return
3770+ # values with the changesets
3771+ defp any_generated_keys_missing? ( keys , resource , changesets ) do
3772+ Enum . any? ( keys , fn key ->
3773+ Ash.Resource.Info . attribute ( resource , key ) . generated? &&
3774+ Enum . any? ( changesets , fn changeset -> is_nil ( changeset . attributes [ key ] ) end )
3775+ end )
3776+ end
3777+
37403778 defp get_bulk_operation_metadata ( changeset ) do
37413779 changeset . context
37423780 |> Enum . find_value ( fn
0 commit comments