Skip to content

Commit a7c99e4

Browse files
committed
fix: handle atomic no_rollback errors during creates
1 parent b056b1b commit a7c99e4

File tree

5 files changed

+20
-6
lines changed

5 files changed

+20
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide
1414
## [v2.6.30](https://github.com/ash-project/ash_postgres/compare/v2.6.29...v2.6.30) (2026-02-04)
1515

1616

17-
17+
* fix for atomic create support
1818

1919
## [v2.6.29](https://github.com/ash-project/ash_postgres/compare/v2.6.28...v2.6.29) (2026-02-03)
2020

lib/data_layer.ex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2452,6 +2452,9 @@ defmodule AshPostgres.DataLayer do
24522452

24532453
{:error, error} ->
24542454
{:error, error}
2455+
2456+
{:error, :no_rollback, error} ->
2457+
{:error, :no_rollback, error}
24552458
end
24562459
end
24572460

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ defmodule AshPostgres.MixProject do
185185
# Run "mix help deps" to learn about dependencies.
186186
defp deps do
187187
[
188-
{:ash, ash_version("~> 3.14")},
188+
{:ash, ash_version("~> 3.15")},
189189
{:spark, "~> 2.3 and >= 2.3.4"},
190190
{:ash_sql, ash_sql_version("~> 0.4 and >= 0.4.3")},
191191
{:igniter, "~> 0.6 and >= 0.6.29", optional: true},

mix.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
%{
2-
"ash": {:hex, :ash, "3.14.1", "22e0ac5dfd4c7d502bd103f0b4380defd66d7c6c83b3a4f54af7045f13da00d7", [:mix], [{:crux, ">= 0.1.2 and < 1.0.0-0", [hex: :crux, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 1.0", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.14 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.3", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "776a5963790d5af79855ddca1718a037d06b49063a6b97fae9110050b3d5127d"},
3-
"ash_sql": {:hex, :ash_sql, "0.4.3", "2c74e0a19646e3d31a384a2712fc48a82d04ceea74467771ce496fd64dbb55db", [:mix], [{:ash, "~> 3.7", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, ">= 3.13.4 and < 4.0.0-0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "b0ecc00502178407e607ae4bcfd2f264f36f6a884218024b5e4d5b3dcfa5e027"},
2+
"ash": {:hex, :ash, "3.15.0", "e52c6be244bb22f4afc5eb9fe9cc6e8f034906ef43c114f75c3c372ba6b470c6", [:mix], [{:crux, ">= 0.1.2 and < 1.0.0-0", [hex: :crux, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 1.0", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.14 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.3", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "adc219ada41d5ec363ef80143404f287d207d0575f93c664a41441d73898306a"},
3+
"ash_sql": {:hex, :ash_sql, "0.4.4", "7e8943b984ad416ba46d297fea6b4d2bcea25c8dfe5666e22d14c42182907798", [:mix], [{:ash, "~> 3.7", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, ">= 3.13.4 and < 4.0.0-0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "19859ba3f111f1e6e4b0b9ab2f7d849e17b6b0ea5dc54811b3e2b54a7ddff5c0"},
44
"benchee": {:hex, :benchee, "1.5.0", "4d812c31d54b0ec0167e91278e7de3f596324a78a096fd3d0bea68bb0c513b10", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.1", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "5b075393aea81b8ae74eadd1c28b1d87e8a63696c649d8293db7c4df3eb67535"},
55
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
66
"credo": {:hex, :credo, "1.7.16", "a9f1389d13d19c631cb123c77a813dbf16449a2aebf602f590defa08953309d4", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "d0562af33756b21f248f066a9119e3890722031b6d199f22e3cf95550e4f1579"},
@@ -48,7 +48,7 @@
4848
"sobelow": {:hex, :sobelow, "0.14.1", "2f81e8632f15574cba2402bcddff5497b413c01e6f094bc0ab94e83c2f74db81", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8fac9a2bd90fdc4b15d6fca6e1608efb7f7c600fa75800813b794ee9364c87f2"},
4949
"sourceror": {:hex, :sourceror, "1.10.1", "325753ed460fe9fa34ebb4deda76d57b2e1507dcd78a5eb9e1c41bfb78b7cdfe", [:mix], [], "hexpm", "288f3079d93865cd1e3e20df5b884ef2cb440e0e03e8ae393624ee8a770ba588"},
5050
"spark": {:hex, :spark, "2.4.0", "f93d3ae6b5f3004e956d52f359fa40670366685447631bc7c058f4fbf250ebf3", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "4e5185f5737cd987bb9ef377ae3462a55b8312f5007c2bc4ad6e850d14ac0111"},
51-
"spitfire": {:hex, :spitfire, "0.3.1", "409b5ed3a2677df8790ed8b0542ca7e36c607d744fef4cb8cb8872fc80dd1803", [:mix], [], "hexpm", "72ff34d8f0096313a4b1a6505513c5ef4bbc0919bd8c181c07fc8d8dea8c9056"},
51+
"spitfire": {:hex, :spitfire, "0.3.2", "476b7b5151fd053a864dae7b5eaeed01811e8b2ff3f24f3c048af1c9dfee5e3d", [:mix], [], "hexpm", "014f7b8c6dd45d1e3b08103c7e61515a590efc872441cf3e933a20efa4b5c46c"},
5252
"splode": {:hex, :splode, "0.3.0", "ff8effecc509a51245df2f864ec78d849248647c37a75886033e3b1a53ca9470", [:mix], [], "hexpm", "73cfd0892d7316d6f2c93e6e8784bd6e137b2aa38443de52fd0a25171d106d81"},
5353
"statistex": {:hex, :statistex, "1.1.0", "7fec1eb2f580a0d2c1a05ed27396a084ab064a40cfc84246dbfb0c72a5c761e5", [:mix], [], "hexpm", "f5950ea26ad43246ba2cce54324ac394a4e7408fdcf98b8e230f503a0cba9cf5"},
5454
"stream_data": {:hex, :stream_data, "1.2.0", "58dd3f9e88afe27dc38bef26fce0c84a9e7a96772b2925c7b32cd2435697a52b", [:mix], [], "hexpm", "eb5c546ee3466920314643edf68943a5b14b32d1da9fe01698dc92b73f89a9ed"},

test/atomics_test.exs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,13 +469,24 @@ defmodule AshPostgres.AtomicsTest do
469469
test "atomic_set works on create with required attribute and fragment" do
470470
temp_entity =
471471
TempEntity
472-
|> Ash.Changeset.for_create(:create, %{})
472+
|> Ash.Changeset.new()
473473
|> Ash.Changeset.atomic_set(:full_name, expr(fragment("(SELECT 'name')")))
474+
|> Ash.Changeset.for_create(:create, %{})
474475
|> Ash.create!()
475476

476477
assert temp_entity.full_name == "name"
477478
end
478479

480+
test "atomic_set works on create with required attribute and fragment resolving to null" do
481+
assert_raise Ash.Error.Invalid, ~r/full_name is required/, fn ->
482+
TempEntity
483+
|> Ash.Changeset.new()
484+
|> Ash.Changeset.atomic_set(:full_name, expr(fragment("(SELECT NULL)")))
485+
|> Ash.Changeset.for_create(:create, %{})
486+
|> Ash.create!()
487+
end
488+
end
489+
479490
test "atomic_set on create overrides attributes when both are set" do
480491
# If both attributes and atomic_set set a value, atomics should win
481492
post =

0 commit comments

Comments
 (0)