2023-08-17 12:49:18 +12:00
|
|
|
defmodule AshPostgres.Test.ComplexCalculationsTest do
|
|
|
|
use AshPostgres.RepoCase, async: false
|
|
|
|
|
2023-12-20 12:14:12 +13:00
|
|
|
require Ash.Query
|
|
|
|
|
2023-08-17 12:49:18 +12:00
|
|
|
test "complex calculation" do
|
|
|
|
certification =
|
|
|
|
AshPostgres.Test.ComplexCalculations.Certification
|
|
|
|
|> Ash.Changeset.new()
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.create!()
|
2023-08-17 12:49:18 +12:00
|
|
|
|
|
|
|
skill =
|
|
|
|
AshPostgres.Test.ComplexCalculations.Skill
|
|
|
|
|> Ash.Changeset.new()
|
|
|
|
|> Ash.Changeset.manage_relationship(:certification, certification, type: :append)
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.create!()
|
2023-08-17 12:49:18 +12:00
|
|
|
|
|
|
|
_documentation =
|
|
|
|
AshPostgres.Test.ComplexCalculations.Documentation
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{status: :demonstrated})
|
2023-08-17 12:49:18 +12:00
|
|
|
|> Ash.Changeset.manage_relationship(:skill, skill, type: :append)
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.create!()
|
2023-08-17 12:49:18 +12:00
|
|
|
|
|
|
|
skill =
|
|
|
|
skill
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.load!([:latest_documentation_status])
|
2023-08-17 12:49:18 +12:00
|
|
|
|
|
|
|
assert skill.latest_documentation_status == :demonstrated
|
|
|
|
|
|
|
|
certification =
|
|
|
|
certification
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.load!([
|
2023-08-17 12:49:18 +12:00
|
|
|
:count_of_skills
|
|
|
|
])
|
|
|
|
|
|
|
|
assert certification.count_of_skills == 1
|
|
|
|
|
|
|
|
certification =
|
|
|
|
certification
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.load!([
|
2023-08-17 12:49:18 +12:00
|
|
|
:count_of_approved_skills
|
|
|
|
])
|
|
|
|
|
|
|
|
assert certification.count_of_approved_skills == 0
|
|
|
|
|
|
|
|
certification =
|
|
|
|
certification
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.load!([
|
2023-08-17 12:49:18 +12:00
|
|
|
:count_of_documented_skills
|
|
|
|
])
|
|
|
|
|
|
|
|
assert certification.count_of_documented_skills == 1
|
|
|
|
|
|
|
|
certification =
|
|
|
|
certification
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.load!([
|
2023-08-17 15:02:56 +12:00
|
|
|
:count_of_documented_skills,
|
|
|
|
:all_documentation_approved,
|
2023-08-17 12:49:18 +12:00
|
|
|
:some_documentation_created
|
|
|
|
])
|
|
|
|
|
2023-08-17 15:02:56 +12:00
|
|
|
assert certification.some_documentation_created
|
2023-08-17 12:49:18 +12:00
|
|
|
end
|
2023-11-16 14:56:09 +13:00
|
|
|
|
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-21 14:42:44 +12:00
|
|
|
test "complex aggregates" do
|
|
|
|
certification =
|
|
|
|
AshPostgres.Test.ComplexCalculations.Certification
|
|
|
|
|> Ash.Changeset.new()
|
|
|
|
|> Ash.create!()
|
|
|
|
|
|
|
|
skill =
|
|
|
|
AshPostgres.Test.ComplexCalculations.Skill
|
|
|
|
|> Ash.Changeset.new()
|
|
|
|
|> Ash.Changeset.manage_relationship(:certification, certification, type: :append)
|
|
|
|
|> Ash.create!()
|
|
|
|
|
|
|
|
AshPostgres.Test.ComplexCalculations.Documentation
|
|
|
|
|> Ash.Changeset.for_create(:create, %{status: :demonstrated})
|
|
|
|
|> Ash.Changeset.manage_relationship(:skill, skill, type: :append)
|
|
|
|
|> Ash.create!()
|
|
|
|
|
|
|
|
certification =
|
|
|
|
certification
|
|
|
|
|> Ash.load!([:count_of_skills_ever_demonstrated])
|
|
|
|
|
|
|
|
assert certification.count_of_skills_ever_demonstrated == 1
|
|
|
|
end
|
|
|
|
|
2023-11-16 14:56:09 +13:00
|
|
|
test "channel: first_member and second member" do
|
|
|
|
channel =
|
|
|
|
AshPostgres.Test.ComplexCalculations.Channel
|
|
|
|
|> Ash.Changeset.new()
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.create!()
|
2023-11-16 14:56:09 +13:00
|
|
|
|
|
|
|
user_1 =
|
|
|
|
AshPostgres.Test.User
|
|
|
|
|> Ash.Changeset.for_create(:create, %{name: "User 1"})
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.create!()
|
2023-11-16 14:56:09 +13:00
|
|
|
|
|
|
|
user_2 =
|
|
|
|
AshPostgres.Test.User
|
|
|
|
|> Ash.Changeset.for_create(:create, %{name: "User 2"})
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.create!()
|
2023-11-16 14:56:09 +13:00
|
|
|
|
|
|
|
channel_member_1 =
|
|
|
|
AshPostgres.Test.ComplexCalculations.ChannelMember
|
|
|
|
|> Ash.Changeset.new()
|
|
|
|
|> Ash.Changeset.manage_relationship(:channel, channel, type: :append)
|
|
|
|
|> Ash.Changeset.manage_relationship(:user, user_1, type: :append)
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.create!()
|
2023-11-16 14:56:09 +13:00
|
|
|
|
|
|
|
channel_member_2 =
|
|
|
|
AshPostgres.Test.ComplexCalculations.ChannelMember
|
|
|
|
|> Ash.Changeset.new()
|
|
|
|
|> Ash.Changeset.manage_relationship(:channel, channel, type: :append)
|
|
|
|
|> Ash.Changeset.manage_relationship(:user, user_2, type: :append)
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.create!()
|
2023-11-16 14:56:09 +13:00
|
|
|
|
|
|
|
channel =
|
|
|
|
channel
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.load!([
|
2023-11-16 14:56:09 +13:00
|
|
|
:first_member,
|
|
|
|
:second_member
|
|
|
|
])
|
|
|
|
|
|
|
|
assert channel.first_member.id == channel_member_1.id
|
|
|
|
assert channel.second_member.id == channel_member_2.id
|
|
|
|
|
|
|
|
channel =
|
|
|
|
channel
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.load!(:name, actor: user_1)
|
2023-11-16 14:56:09 +13:00
|
|
|
|
|
|
|
assert channel.name == user_1.name
|
|
|
|
|
|
|
|
channel =
|
|
|
|
channel
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.load!(:name, actor: user_2)
|
2023-11-16 14:56:09 +13:00
|
|
|
|
|
|
|
assert channel.name == user_2.name
|
|
|
|
end
|
2023-11-20 17:48:38 +13:00
|
|
|
|
|
|
|
test "complex calculation while using actor on related resource passes reference" do
|
|
|
|
dm_channel =
|
|
|
|
AshPostgres.Test.ComplexCalculations.DMChannel
|
|
|
|
|> Ash.Changeset.new()
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.create!()
|
2023-11-20 17:48:38 +13:00
|
|
|
|
|
|
|
user_1 =
|
|
|
|
AshPostgres.Test.User
|
|
|
|
|> Ash.Changeset.for_create(:create, %{name: "User 1"})
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.create!()
|
2023-11-20 17:48:38 +13:00
|
|
|
|
|
|
|
user_2 =
|
|
|
|
AshPostgres.Test.User
|
|
|
|
|> Ash.Changeset.for_create(:create, %{name: "User 2"})
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.create!()
|
2023-11-20 17:48:38 +13:00
|
|
|
|
|
|
|
channel_member_1 =
|
|
|
|
AshPostgres.Test.ComplexCalculations.ChannelMember
|
|
|
|
|> Ash.Changeset.for_create(:create, %{channel_id: dm_channel.id, user_id: user_1.id})
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.create!()
|
2023-11-20 17:48:38 +13:00
|
|
|
|
|
|
|
channel_member_2 =
|
|
|
|
AshPostgres.Test.ComplexCalculations.ChannelMember
|
2023-11-21 01:05:47 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{channel_id: dm_channel.id, user_id: user_2.id})
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.create!()
|
2023-11-20 17:48:38 +13:00
|
|
|
|
|
|
|
dm_channel =
|
|
|
|
dm_channel
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.load!([
|
2023-11-20 17:48:38 +13:00
|
|
|
:first_member,
|
|
|
|
:second_member
|
|
|
|
])
|
|
|
|
|
|
|
|
assert dm_channel.first_member.id == channel_member_1.id
|
|
|
|
assert dm_channel.second_member.id == channel_member_2.id
|
|
|
|
|
|
|
|
dm_channel =
|
|
|
|
dm_channel
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.load!(:name, actor: user_1)
|
2023-11-20 17:48:38 +13:00
|
|
|
|
|
|
|
assert dm_channel.name == user_1.name
|
|
|
|
|
|
|
|
dm_channel =
|
|
|
|
dm_channel
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.load!(:name, actor: user_2)
|
2023-11-20 17:48:38 +13:00
|
|
|
|
|
|
|
assert dm_channel.name == user_2.name
|
|
|
|
|
|
|
|
channels =
|
|
|
|
AshPostgres.Test.ComplexCalculations.Channel
|
|
|
|
|> Ash.Query.for_read(:read)
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.read!()
|
2023-11-20 17:48:38 +13:00
|
|
|
|
|
|
|
channels =
|
|
|
|
channels
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.load!([dm_channel: :name],
|
2023-11-20 17:48:38 +13:00
|
|
|
actor: user_1
|
|
|
|
)
|
|
|
|
|
|
|
|
[channel | _] = channels
|
|
|
|
|
|
|
|
assert channel.dm_channel.name == user_1.name
|
|
|
|
|
|
|
|
channel =
|
|
|
|
channel
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.load!([:dm_name, :foo], actor: user_2)
|
2023-11-20 17:48:38 +13:00
|
|
|
|
2023-11-21 01:05:47 +13:00
|
|
|
assert channel.dm_name == user_2.name
|
2023-11-20 17:48:38 +13:00
|
|
|
end
|
2023-12-20 12:14:12 +13:00
|
|
|
|
|
|
|
test "calculations with parent filters can be filtered on themselves" do
|
|
|
|
AshPostgres.Test.ComplexCalculations.DMChannel
|
|
|
|
|> Ash.Changeset.new()
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.create!()
|
2023-12-20 12:14:12 +13:00
|
|
|
|
|
|
|
assert [%{foo: "foobar"}] =
|
|
|
|
AshPostgres.Test.ComplexCalculations.Channel
|
|
|
|
|> Ash.Query.filter(foo == "foobar")
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.read!(load: :foo)
|
2023-12-20 12:14:12 +13:00
|
|
|
end
|
2023-12-23 15:14:40 +13:00
|
|
|
|
|
|
|
test "calculations with aggregates can be referenced from aggregates" do
|
|
|
|
author =
|
|
|
|
AshPostgres.Test.Author
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{first_name: "is", last_name: "match"})
|
|
|
|
|> Ash.create!()
|
2023-12-23 15:14:40 +13:00
|
|
|
|
|
|
|
AshPostgres.Test.Post
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{title: "match"})
|
2023-12-23 15:14:40 +13:00
|
|
|
|> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove)
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.create!()
|
2023-12-23 15:14:40 +13:00
|
|
|
|
|
|
|
assert [%{author_count_of_posts: 1}] =
|
|
|
|
AshPostgres.Test.Post
|
|
|
|
|> Ash.Query.load(:author_count_of_posts)
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.read!()
|
2023-12-23 15:14:40 +13:00
|
|
|
|
|
|
|
assert [%{author_count_of_posts: 1}] =
|
|
|
|
AshPostgres.Test.Post
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.read!()
|
|
|
|
|> Ash.load!(:author_count_of_posts)
|
2023-12-23 15:14:40 +13:00
|
|
|
|
|
|
|
assert [_] =
|
|
|
|
AshPostgres.Test.Post
|
|
|
|
|> Ash.Query.filter(author_count_of_posts == 1)
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.read!()
|
2023-12-23 15:14:40 +13:00
|
|
|
end
|
2023-12-24 04:39:54 +13:00
|
|
|
|
|
|
|
test "calculations can reference aggregates from optimizable first aggregates" do
|
|
|
|
author =
|
|
|
|
AshPostgres.Test.Author
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{first_name: "is", last_name: "match"})
|
|
|
|
|> Ash.create!()
|
2023-12-24 04:39:54 +13:00
|
|
|
|
|
|
|
AshPostgres.Test.Post
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{title: "match"})
|
2023-12-24 04:39:54 +13:00
|
|
|
|> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove)
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.create!()
|
2023-12-24 04:39:54 +13:00
|
|
|
|
|
|
|
assert [%{author_count_of_posts_agg: 1}] =
|
|
|
|
AshPostgres.Test.Post
|
|
|
|
|> Ash.Query.load(:author_count_of_posts_agg)
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.read!()
|
2023-12-24 04:39:54 +13:00
|
|
|
|
|
|
|
assert [%{author_count_of_posts_agg: 1}] =
|
|
|
|
AshPostgres.Test.Post
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.read!()
|
|
|
|
|> Ash.load!(:author_count_of_posts_agg)
|
2023-12-24 04:39:54 +13:00
|
|
|
|
|
|
|
assert [_] =
|
|
|
|
AshPostgres.Test.Post
|
|
|
|
|> Ash.Query.filter(author_count_of_posts_agg == 1)
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.read!()
|
2023-12-24 04:39:54 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
test "calculations can reference aggregates from non optimizable aggregates" do
|
|
|
|
author =
|
|
|
|
AshPostgres.Test.Author
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{first_name: "is", last_name: "match"})
|
|
|
|
|> Ash.create!()
|
2023-12-24 04:39:54 +13:00
|
|
|
|
|
|
|
AshPostgres.Test.Post
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{title: "match"})
|
2023-12-24 04:39:54 +13:00
|
|
|
|> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove)
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.create!()
|
2023-12-24 04:39:54 +13:00
|
|
|
|
|
|
|
assert [%{sum_of_author_count_of_posts: 1}] =
|
|
|
|
AshPostgres.Test.Post
|
|
|
|
|> Ash.Query.load(:sum_of_author_count_of_posts)
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.read!()
|
2023-12-24 04:39:54 +13:00
|
|
|
|
|
|
|
assert [%{sum_of_author_count_of_posts: 1}] =
|
|
|
|
AshPostgres.Test.Post
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.read!()
|
|
|
|
|> Ash.load!(:sum_of_author_count_of_posts)
|
2023-12-24 04:39:54 +13:00
|
|
|
|
|
|
|
assert [_] =
|
|
|
|
AshPostgres.Test.Post
|
|
|
|
|> Ash.Query.filter(sum_of_author_count_of_posts == 1)
|
2024-03-28 09:52:28 +13:00
|
|
|
|> Ash.read!()
|
2023-12-24 04:39:54 +13:00
|
|
|
end
|
2023-08-17 12:49:18 +12:00
|
|
|
end
|