Commit graph

194 commits

Author SHA1 Message Date
Barnabas Jovanovics
3385bd21f1
improvement: add storage type option (#342)
---------

Co-authored-by: Zach Daniel <zach@zachdaniel.dev>
2024-07-08 09:54:50 -04:00
Zach Daniel
f0d07a3a4d fix: ensure that from_many? relationships in lateral join are limited 2024-07-06 06:38:31 -04:00
Zach Daniel
ffd3ff5a81 test: rollback change for uuid -> string type in tests 2024-07-02 13:01:54 -04:00
Zach Daniel
185e9bea83 test: adjustments for tests 2024-07-02 12:30:25 -04:00
Zach Daniel
e42665b14c chore: update to latest igniter 2024-07-01 21:34:47 -04:00
Zach Daniel
e520ddfc35 chore: get build passing
fix: properly delete args passed from migrate to ecto
2024-06-24 10:20:16 -04:00
Barnabas Jovanovics
2a1bc993eb
test: update tests to show many_to_many filter problem (#309) 2024-06-18 09:03:24 -04:00
Zach Daniel
860d085386 fix: update ash_sql to fix query generation issues 2024-06-18 07:50:54 -04:00
Barnabas Jovanovics
14938f9f47
test: add test to show error with building a reference (#330) 2024-06-18 06:23:27 -04:00
Zach Daniel
8e32e0ab9a fix: ensure that context multitenancy is properly applied to lateral many-to-many joins 2024-06-10 12:49:04 -04:00
Zach Daniel
4b5d980c69 chore: undo accidental git stash for previous commit 2024-06-06 14:34:01 -04:00
Jesse Williams
9940edf633
test: demonstrating issue filtering relationship by parent (#318) 2024-06-05 13:12:32 -04:00
Zach Daniel
df250964e0 fix: ensure that all current attribute values are selected on bulk update shifted root query
closes #314
2024-06-02 12:35:57 -04:00
Zach Daniel
bc46d9d9c4 test: add test reproducing related aggregate reference 2024-05-30 00:27:20 -05:00
Zach Daniel
ff47ff0e06 fix: properly support aggregate references in atomic updates
(yes, you read that right)
2024-05-29 12:30:16 -04:00
Zach Daniel
8ad92cc3c0 improvement: update ash and support new identity features 2024-05-24 01:14:55 -04:00
Zach Daniel
264f4c0bac fix: handle complex maps/list on update
fix: support anonymous aggregates in sorts
fix: ensure parent_as bindings properly reference binding names

closes #296
closes #297
closes #298
2024-05-22 17:47:10 -04:00
Alan Heywood
45d0284aa8
test: add failing test to demonstrate an error with nested aggregates (#295)
1) test complex aggregates (AshPostgres.Test.ComplexCalculationsTest)
     test/complex_calculations_test.exs:66
     ** (Ash.Error.Unknown) Unknown Error

     * ** (Ecto.SubQueryError) the following exception happened when compiling a subquery.

         ** (Ecto.SubQueryError) the following exception happened when compiling a subquery.

             ** (Ecto.QueryError) could not find named binding `parent_as(false)` in query:

             from c0 in AshPostgres.Test.ComplexCalculations.Certification,
               as: 0,
               left_lateral_join: s1 in subquery(from s0 in AshPostgres.Test.ComplexCalculations.Skill,
               as: 0,
               left_lateral_join: d1 in subquery(from d0 in AshPostgres.Test.ComplexCalculations.Documentation,
               as: 0,
               where: parent_as(false).id == as(0).skill_id,
               where: type(
               as(0).status,
               {:parameterized, Ash.Type.Atom.EctoType,
                one_of: [:demonstrated, :performed, :approved, :reopened]}
             ) ==
               type(
                 ^"demonstrated",
                 {:parameterized, Ash.Type.Atom.EctoType,
                  one_of: [:demonstrated, :performed, :approved, :reopened]}
               ),
               group_by: [d0.skill_id],
               select: %{
               skill_id: map(d0, [:skill_id]).skill_id,
               count_of_demonstrated_documentations:
                 type(
                   coalesce(
                     count(type(as(0).id, {:parameterized, Ash.Type.UUID.EctoType, []})),
                     type(^0, {:parameterized, Ash.Type.Integer.EctoType, []})
                   ),
                   {:parameterized, Ash.Type.Integer.EctoType, []}
                 )
             }),
               on: true,
               where: parent_as(0).id == as(0).certification_id,
               where: type(as(0).removed, {:parameterized, Ash.Type.Boolean.EctoType, []}) ==
               type(^false, {:parameterized, Ash.Type.Boolean.EctoType, []}),
               group_by: [s0.certification_id],
               select: %{
               certification_id: map(s0, [:certification_id]).certification_id,
               count_of_skills_ever_demonstrated:
                 type(
                   sum(
                     type(
                       fragment(
                         "(CASE WHEN ? THEN ? ELSE ? END)",
                         type(
                           coalesce(
                             as(1).count_of_demonstrated_documentations,
                             type(^0, {:parameterized, Ash.Type.Integer.EctoType, []})
                           ),
                           {:parameterized, Ash.Type.Integer.EctoType, []}
                         ) == type(^0, {:parameterized, Ash.Type.Integer.EctoType, []}),
                         type(^0, {:parameterized, Ash.Type.Integer.EctoType, []}),
                         type(^1, {:parameterized, Ash.Type.Integer.EctoType, []})
                       ),
                       {:parameterized, Ash.Type.Integer.EctoType, []}
                     )
                   ),
                   {:parameterized, Ash.Type.Integer.EctoType, []}
                 )
             }),
               on: true,
               where: type(as(0).id, {:parameterized, Ash.Type.UUID.EctoType, []}) ==
               type(^"e24ef8a5-d39d-4293-9f69-1abd10a996e6", {:parameterized, Ash.Type.UUID.EctoType, []}),
               select: merge(
               merge(struct(c0, [:id]), %{
                 count_of_skills_ever_demonstrated:
                   type(
                     type(
                       s1.count_of_skills_ever_demonstrated,
                       {:parameterized, Ash.Type.Integer.EctoType, []}
                     ),
                     {:parameterized, Ash.Type.Integer.EctoType, []}
                   )
               }),
               %{}
             )

         The subquery originated from the following query:

         from s0 in AshPostgres.Test.ComplexCalculations.Skill,
           as: 0,
           left_lateral_join: d1 in subquery(from d0 in AshPostgres.Test.ComplexCalculations.Documentation,
           as: 0,
           where: parent_as(false).id == as(0).skill_id,
           where: type(
           as(0).status,
           {:parameterized, Ash.Type.Atom.EctoType,
            one_of: [:demonstrated, :performed, :approved, :reopened]}
         ) ==
           type(
             ^"demonstrated",
             {:parameterized, Ash.Type.Atom.EctoType,
              one_of: [:demonstrated, :performed, :approved, :reopened]}
           ),
           group_by: [d0.skill_id],
           select: %{
           skill_id: map(d0, [:skill_id]).skill_id,
           count_of_demonstrated_documentations:
             type(
               coalesce(
                 count(type(as(0).id, {:parameterized, Ash.Type.UUID.EctoType, []})),
                 type(^0, {:parameterized, Ash.Type.Integer.EctoType, []})
               ),
               {:parameterized, Ash.Type.Integer.EctoType, []}
             )
         }),
           on: true,
           where: parent_as(0).id == as(0).certification_id,
           where: type(as(0).removed, {:parameterized, Ash.Type.Boolean.EctoType, []}) ==
           type(^false, {:parameterized, Ash.Type.Boolean.EctoType, []}),
           group_by: [s0.certification_id],
           select: %{
           certification_id: map(s0, [:certification_id]).certification_id,
           count_of_skills_ever_demonstrated:
             type(
               sum(
                 type(
                   fragment(
                     "(CASE WHEN ? THEN ? ELSE ? END)",
                     type(
                       coalesce(
                         d1.count_of_demonstrated_documentations,
                         type(^..., {:parameterized, Ash.Type.Integer.EctoType, []})
                       ),
                       {:parameterized, Ash.Type.Integer.EctoType, []}
                     ) == type(^..., {:parameterized, Ash.Type.Integer.EctoType, []}),
                     type(^..., {:parameterized, Ash.Type.Integer.EctoType, []}),
                     type(^..., {:parameterized, Ash.Type.Integer.EctoType, []})
                   ),
                   {:parameterized, Ash.Type.Integer.EctoType, []}
                 )
               ),
               {:parameterized, Ash.Type.Integer.EctoType, []}
             )
         }

     The subquery originated from the following query:

     from c0 in AshPostgres.Test.ComplexCalculations.Certification,
       as: 0,
       left_lateral_join: s1 in subquery(from s0 in AshPostgres.Test.ComplexCalculations.Skill,
       as: 0,
       left_lateral_join: d1 in subquery(from d0 in AshPostgres.Test.ComplexCalculations.Documentation,
       as: 0,
       where: parent_as(false).id == as(0).skill_id,
       where: type(
       as(0).status,
       {:parameterized, Ash.Type.Atom.EctoType,
        one_of: [:demonstrated, :performed, :approved, :reopened]}
     ) ==
       type(
         ^"demonstrated",
         {:parameterized, Ash.Type.Atom.EctoType,
          one_of: [:demonstrated, :performed, :approved, :reopened]}
       ),
       group_by: [d0.skill_id],
       select: %{
       skill_id: map(d0, [:skill_id]).skill_id,
       count_of_demonstrated_documentations:
         type(
           coalesce(
             count(type(as(0).id, {:parameterized, Ash.Type.UUID.EctoType, []})),
             type(^0, {:parameterized, Ash.Type.Integer.EctoType, []})
           ),
           {:parameterized, Ash.Type.Integer.EctoType, []}
         )
     }),
       on: true,
       where: parent_as(0).id == as(0).certification_id,
       where: type(as(0).removed, {:parameterized, Ash.Type.Boolean.EctoType, []}) ==
       type(^false, {:parameterized, Ash.Type.Boolean.EctoType, []}),
       group_by: [s0.certification_id],
       select: %{
       certification_id: map(s0, [:certification_id]).certification_id,
       count_of_skills_ever_demonstrated:
         type(
           sum(
             type(
               fragment(
                 "(CASE WHEN ? THEN ? ELSE ? END)",
                 type(
                   coalesce(
                     as(1).count_of_demonstrated_documentations,
                     type(^0, {:parameterized, Ash.Type.Integer.EctoType, []})
                   ),
                   {:parameterized, Ash.Type.Integer.EctoType, []}
                 ) == type(^0, {:parameterized, Ash.Type.Integer.EctoType, []}),
                 type(^0, {:parameterized, Ash.Type.Integer.EctoType, []}),
                 type(^1, {:parameterized, Ash.Type.Integer.EctoType, []})
               ),
               {:parameterized, Ash.Type.Integer.EctoType, []}
             )
           ),
           {:parameterized, Ash.Type.Integer.EctoType, []}
         )
     }),
       on: true,
       where: type(as(0).id, {:parameterized, Ash.Type.UUID.EctoType, []}) ==
       type(^"e24ef8a5-d39d-4293-9f69-1abd10a996e6", {:parameterized, Ash.Type.UUID.EctoType, []}),
       select: merge(
       merge(struct(c0, [:id]), %{
         count_of_skills_ever_demonstrated:
           type(
             type(
               s1.count_of_skills_ever_demonstrated,
               {:parameterized, Ash.Type.Integer.EctoType, []}
             ),
             {:parameterized, Ash.Type.Integer.EctoType, []}
           )
       }),
       %{}
     )

       (elixir 1.16.2) lib/enum.ex:1826: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
       (elixir 1.16.2) lib/enum.ex:2528: Enum."-reduce/3-lists^foldl/2-0-"/3
       (ecto 3.11.2) lib/ecto/repo/queryable.ex:214: Ecto.Repo.Queryable.execute/4
       (ecto 3.11.2) lib/ecto/repo/queryable.ex:19: Ecto.Repo.Queryable.all/3
       (ash_postgres 2.0.2) lib/data_layer.ex:706: anonymous fn/3 in AshPostgres.DataLayer.run_query/2
       (ash_postgres 2.0.2) lib/data_layer.ex:704: AshPostgres.DataLayer.run_query/2
       (ash 3.0.2) lib/ash/actions/read/read.ex:2259: Ash.Actions.Read.run_query/4
       (ash 3.0.2) lib/ash/actions/read/read.ex:903: Ash.Actions.Read.reselect_and_load/5
       (ash 3.0.2) lib/ash/actions/read/read.ex:244: Ash.Actions.Read.do_run/3
       (ash 3.0.2) lib/ash/actions/read/read.ex:66: anonymous fn/3 in Ash.Actions.Read.run/3
       (ash 3.0.2) lib/ash/actions/read/read.ex:65: Ash.Actions.Read.run/3
       (ash 3.0.2) lib/ash.ex:1717: Ash.load/3
       (ash 3.0.2) lib/ash.ex:1687: Ash.load/3
       (ash 3.0.2) lib/ash.ex:1635: Ash.load!/3
       test/complex_calculations_test.exs:85: AshPostgres.Test.ComplexCalculationsTest."test complex aggregates"/1
       (ex_unit 1.16.2) lib/ex_unit/runner.ex:472: ExUnit.Runner.exec_test/2
       (stdlib 5.2) timer.erl:270: :timer.tc/2
       (ex_unit 1.16.2) lib/ex_unit/runner.ex:394: anonymous fn/6 in ExUnit.Runner.spawn_test_monitor/4
     code: |> Ash.load!([:count_of_skills_ever_demonstrated])
     stacktrace:
       (elixir 1.16.2) lib/process.ex:860: Process.info/2
       (ash 3.0.2) lib/ash/error/unknown.ex:3: Ash.Error.Unknown."exception (overridable 2)"/1
       (ash 3.0.2) ash_postgres/deps/splode/lib/splode.ex:211: Ash.Error.to_class/2
       (ash 3.0.2) lib/ash/error/error.ex:66: Ash.Error.to_error_class/2
       (ash 3.0.2) lib/ash/actions/read/read.ex:324: Ash.Actions.Read.do_run/3
       (ash 3.0.2) lib/ash/actions/read/read.ex:66: anonymous fn/3 in Ash.Actions.Read.run/3
       (ash 3.0.2) lib/ash/actions/read/read.ex:65: Ash.Actions.Read.run/3
       (ash 3.0.2) lib/ash.ex:1717: Ash.load/3
       (ash 3.0.2) lib/ash.ex:1687: Ash.load/3
       (ash 3.0.2) lib/ash.ex:1635: Ash.load!/3
       test/complex_calculations_test.exs:85: (test)
2024-05-20 22:42:44 -04:00
Riccardo Binetti
0313734db0
chore: failing test for calculation ordered paginated relationship (#292) 2024-05-20 10:06:49 -04:00
Riccardo Binetti
ad0b1a5c6c
chore: add relationship pagination tests (#265) 2024-05-16 17:28:43 -05:00
Dmitry Maganov
74cead8749
test: add failing test for changing_attributes check for create (#288) 2024-05-16 08:39:47 -05:00
Barnabas Jovanovics
e597c39687
add test for rels in atomic updates (#286) 2024-05-15 09:50:36 -04:00
Barnabas Jovanovics
6d0cca1fae
test: show error with calc depending on other exists calc (#280) 2024-05-14 08:35:40 -04:00
Zach Daniel
d0c7984a89 test: add tests for action filters in bulk update/destroy
fix: ensure filter is included in stale record error message
2024-05-12 16:28:48 -04:00
Frank Dugan III
bc02a4d23c
feat: add timestamptz types (#266) 2024-05-05 06:08:21 -04:00
Zach Daniel
8eef44951c test additional bulk action tests 2024-05-03 21:26:08 -04:00
Lukas Ender
f405225731
feat: test with calculations using exists (#240) 2024-05-03 12:31:42 -04:00
Zach Daniel
56f3a5eb2f fix: fix calculate when exprs aren't dynamics
test: add test for datetimes
2024-05-02 21:29:21 -04:00
Riccardo Binetti
65f93561d8
chore: add failing test for bulk actions and non-null violations (#260)
- bulk_create returns a Postgrex error instead of Ash.Error.Changes.Required
like the non-bulk create does
- bulk_update with :stream strategy does the same
- bulk_update with :atomic strategy doesn't trim the empty string and writes it
to the database
2024-05-02 20:31:35 -04:00
Zach Daniel
a6c1dedffb test: add tests for fix in ash_sql around actor refs in relationships 2024-05-01 08:27:49 -04:00
Zach Daniel
a2083ff736 fix: update ash_sql for inner join fixes
closes #252

chore: small test fixes
2024-04-26 23:51:29 -04:00
Zach Daniel
3c4a3d30a5 fix: handle missing aggregate relationships and fields better in transformers
fix: update ash_sql for bug fixes
2024-04-22 20:42:11 -04:00
32448ea5de
chore: Add failing test for tenanted aggregate bug. (#244) 2024-04-22 19:06:06 -04:00
Zach Daniel
ec91e2ee9b fix: reproduce issue around atomic updates & validations 2024-04-22 18:58:57 -04:00
Zach Daniel
7f3661ce42 chore: support adapter option to use AshPostgres.Repo 2024-04-21 11:11:00 -04:00
Zach Daniel
8f1ae86db9 test: add some explicit destroy/soft destroy tests 2024-04-21 09:35:47 -04:00
Zach Daniel
3647fc42ee improvement: add default implementation for pg_version, and rename to min_pg_version 2024-03-27 19:20:49 -04:00
Zach Daniel
8a505607ab ci: set PG_VERSION better for CI 2024-03-27 17:46:51 -04:00
Zach Daniel
3ad3f5f5d6 chore: update ash, resources and an error message 2024-03-27 17:03:16 -04:00
Zach Daniel
37cc01957d
improvement!: 3.0 (#227)
* WIP

* chore: fix mix.lock merge issues

* improvement: upgrade to 3.0

* chore: remove `repo.to_tenant`

* chore: continue removal of unnecessary helper

* chore: use `Ash.ToTenant`
2024-03-27 16:52:28 -04:00
Zach Daniel
5a513a82c2 fix: handle fully fleshed out aggregate fields 2024-03-22 02:13:07 -04:00
Zach Daniel
43deb00e36 fix: properly handle multiple sorts in aggregate 2024-02-29 13:42:42 -05:00
Zach Daniel
f716e3bb69 fix: simplify(and fix) exists subquery generation 2024-02-28 22:55:53 -05:00
Zach Daniel
23dd650100 test: test improvements, regression test 2024-02-28 21:24:31 -05:00
Zach Daniel
f6d029d85b improvement: add test for aggregates 2024-02-24 18:08:00 -05:00
Zach Daniel
37cb3825f1 fix: properly handle complex types in lists 2024-02-23 20:53:19 -05:00
Zach Daniel
3fd5a7a907 test: add some tests for atomics 2024-02-15 10:54:20 -05:00
Zach Daniel
7a4fe87561 chore: update ash, add tests 2024-02-14 13:56:58 -05:00
Zach Daniel
3146d5f97d chore: update ash, add tests for field policies 2024-02-14 11:04:06 -05:00
Barnabas Jovanovics
be15759de0
test: add test to show problem with field policies in filters (#206) 2024-02-14 10:25:25 -05:00