Skip to content

Commit 6e3f57e

Browse files
committed
Merge branch 'main' into main
2 parents ccf2da4 + e7530aa commit 6e3f57e

File tree

4 files changed

+115
-3
lines changed

4 files changed

+115
-3
lines changed

mix.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
%{
22
"ash": {:hex, :ash, "3.9.0", "004371ffb181a142cda09544342dad1ffedf360a5636219d71cb5431ccbe3ad6", [: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, "~> 0.11", [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.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [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", "e3e80a182c6e8b4d87f1caa4dba774da210f1f75f1420650ba012eb4388dc8c3"},
3-
"ash_sql": {:hex, :ash_sql, "0.3.12", "e1ccab3a9aca0a9e8bd2c55dc8858bfaff75b892cada1b1c28639782c81b8f7b", [: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", "2d1e8bff8335d4b433d66baa8c9a584a2a0a6057b133fad07070d3d1ec7138fb"},
3+
"ash_sql": {:hex, :ash_sql, "0.3.13", "1018528aa2589fc69240242c48f553b211899a574d860c564533c830644b5e25", [: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", "2b65acafb677983d96aa6a9c43c107f71c63f3dd7bff220b55b99b3bdab53a95"},
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.13", "126a0697df6b7b71cd18c81bc92335297839a806b6f62b61d417500d1070ff4e", [: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", "47641e6d2bbff1e241e87695b29f617f1a8f912adea34296fb10ecc3d7e9e84f"},
@@ -40,12 +40,12 @@
4040
"owl": {:hex, :owl, "0.13.0", "26010e066d5992774268f3163506972ddac0a7e77bfe57fa42a250f24d6b876e", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "59bf9d11ce37a4db98f57cb68fbfd61593bf419ec4ed302852b6683d3d2f7475"},
4141
"postgrex": {:hex, :postgrex, "0.21.1", "2c5cc830ec11e7a0067dd4d623c049b3ef807e9507a424985b8dcf921224cd88", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "27d8d21c103c3cc68851b533ff99eef353e6a0ff98dc444ea751de43eb48bdac"},
4242
"reactor": {:hex, :reactor, "0.17.0", "eb8bdb530dbae824e2d36a8538f8ec4f3aa7c2d1b61b04959fa787c634f88b49", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "3c3bf71693adbad9117b11ec83cfed7d5851b916ade508ed9718de7ae165bf25"},
43-
"req": {:hex, :req, "0.5.15", "662020efb6ea60b9f0e0fac9be88cd7558b53fe51155a2d9899de594f9906ba9", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "a6513a35fad65467893ced9785457e91693352c70b58bbc045b47e5eb2ef0c53"},
43+
"req": {:hex, :req, "0.5.16", "99ba6a36b014458e52a8b9a0543bfa752cb0344b2a9d756651db1281d4ba4450", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "974a7a27982b9b791df84e8f6687d21483795882a7840e8309abdbe08bb06f09"},
4444
"rewrite": {:hex, :rewrite, "1.2.0", "80220eb14010e175b67c939397e1a8cdaa2c32db6e2e0a9d5e23e45c0414ce21", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "a1cd702bbb9d51613ab21091f04a386d750fc6f4516b81900df082d78b2d8c50"},
4545
"simple_sat": {:hex, :simple_sat, "0.1.4", "39baf72cdca14f93c0b6ce2b6418b72bbb67da98fa9ca4384e2f79bbc299899d", [:mix], [], "hexpm", "3569b68e346a5fd7154b8d14173ff8bcc829f2eb7b088c30c3f42a383443930b"},
4646
"sobelow": {:hex, :sobelow, "0.14.1", "2f81e8632f15574cba2402bcddff5497b413c01e6f094bc0ab94e83c2f74db81", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8fac9a2bd90fdc4b15d6fca6e1608efb7f7c600fa75800813b794ee9364c87f2"},
4747
"sourceror": {:hex, :sourceror, "1.10.0", "38397dedbbc286966ec48c7af13e228b171332be1ad731974438c77791945ce9", [:mix], [], "hexpm", "29dbdfc92e04569c9d8e6efdc422fc1d815f4bd0055dc7c51b8800fb75c4b3f1"},
48-
"spark": {:hex, :spark, "2.3.13", "129c2f7ecabd0c27e53daea7aa8b1de4dd068fdafb8d7d5ee49e1f2e8d87ba64", [: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", "d06de23b5e8961d98c9c81d798dbafb9ac64694da19b0e9ca4ba4a8a54b75e31"},
48+
"spark": {:hex, :spark, "2.3.14", "a08420d08e6e0e49d740aed3e160f1cb894ba8f6b3f5e6c63253e9df1995265c", [: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", "af50c4ea5dd67eba822247f1c98e1d4e598cb7f6c28ccf5d002f0e0718096f4f"},
4949
"spitfire": {:hex, :spitfire, "0.2.1", "29e154873f05444669c7453d3d931820822cbca5170e88f0f8faa1de74a79b47", [:mix], [], "hexpm", "6eeed75054a38341b2e1814d41bb0a250564092358de2669fdb57ff88141d91b"},
5050
"splode": {:hex, :splode, "0.2.9", "3a2776e187c82f42f5226b33b1220ccbff74f4bcc523dd4039c804caaa3ffdc7", [:mix], [], "hexpm", "8002b00c6e24f8bd1bcced3fbaa5c33346048047bb7e13d2f3ad428babbd95c3"},
5151
"statistex": {:hex, :statistex, "1.1.0", "7fec1eb2f580a0d2c1a05ed27396a084ab064a40cfc84246dbfb0c72a5c761e5", [:mix], [], "hexpm", "f5950ea26ad43246ba2cce54324ac394a4e7408fdcf98b8e230f503a0cba9cf5"},

test/aggregate_test.exs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1919,4 +1919,102 @@ defmodule AshSql.AggregateTest do
19191919
|> Ash.read!()
19201920
end
19211921
end
1922+
1923+
test "multiple aggregates filtering on nested first aggregate" do
1924+
post =
1925+
Post
1926+
|> Ash.Changeset.for_create(:create, %{title: "test"})
1927+
|> Ash.create!()
1928+
1929+
comment =
1930+
Comment
1931+
|> Ash.Changeset.for_create(:create, %{title: "comment"})
1932+
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
1933+
|> Ash.create!()
1934+
1935+
Rating
1936+
|> Ash.Changeset.for_create(:create, %{score: 10, resource_id: comment.id})
1937+
|> Ash.Changeset.set_context(%{data_layer: %{table: "comment_ratings"}})
1938+
|> Ash.create!()
1939+
1940+
# ERROR 42803 (grouping_error) aggregate functions are not allowed in FILTER
1941+
#
1942+
# Multiple Post aggregates filter on Comment.latest_rating_score (a first aggregate)
1943+
# AshPostgres includes ss1.latest_rating_score in SELECT but not in GROUP BY
1944+
# error: column "ss1.latest_rating_score" must appear in the GROUP BY clause
1945+
#
1946+
# This regression was introduced by ash_sql bb458d56
1947+
assert {:ok, _} =
1948+
Post
1949+
|> Ash.Query.load([
1950+
:count_of_comments_with_ratings,
1951+
:count_of_comments_with_high_ratings
1952+
])
1953+
|> Ash.read()
1954+
end
1955+
1956+
describe "page with count and aggregates with relationship-based calculations" do
1957+
test "loads relationship-based calculations correctly when using page(count: true) with aggregates" do
1958+
# This test reproduces the bug from https://github.com/ash-project/ash_sql/issues/191
1959+
# When using page(count: true) with both an aggregate and a calculation that depends on
1960+
# a relationship, the calculation fails to load (remains #Ash.NotLoaded)
1961+
1962+
# Create test data
1963+
author =
1964+
Author
1965+
|> Ash.Changeset.for_create(:create, %{
1966+
first_name: "John",
1967+
last_name: "Doe"
1968+
})
1969+
|> Ash.create!()
1970+
1971+
post =
1972+
Post
1973+
|> Ash.Changeset.for_create(:create, %{
1974+
title: "Test Post"
1975+
})
1976+
|> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove)
1977+
|> Ash.create!()
1978+
1979+
Comment
1980+
|> Ash.Changeset.for_create(:create, %{title: "Test Comment"})
1981+
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
1982+
|> Ash.create!()
1983+
1984+
# Test without page(count: true) - should work
1985+
result_without_page_count =
1986+
Post
1987+
|> Ash.Query.filter(id == ^post.id)
1988+
|> Ash.Query.load([
1989+
# aggregate
1990+
:count_of_comments,
1991+
# calculation that depends on author relationship
1992+
:author_first_name_calc
1993+
])
1994+
|> Ash.read_one!()
1995+
1996+
assert result_without_page_count.count_of_comments == 1
1997+
assert result_without_page_count.author_first_name_calc == "John"
1998+
1999+
Logger.configure(level: :debug)
2000+
# Test with page(count: true) - this triggers the bug
2001+
%{results: [result_with_page_count | _]} =
2002+
Post
2003+
|> Ash.Query.filter(id == ^post.id)
2004+
|> Ash.Query.load([
2005+
# aggregate
2006+
:count_of_comments,
2007+
# calculation that depends on author relationship
2008+
:author_first_name_calc
2009+
])
2010+
|> Ash.Query.page(limit: 50, offset: 0, count: true)
2011+
|> Ash.read!()
2012+
2013+
# Both should be loaded correctly
2014+
assert result_with_page_count.count_of_comments == 1
2015+
# This assertion should fail if the bug is present
2016+
assert result_with_page_count.author_first_name_calc == "John",
2017+
"Calculation was not loaded when using page(count: true) with aggregates"
2018+
end
2019+
end
19222020
end

test/support/resources/comment.ex

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ defmodule AshPostgres.Test.Comment do
6565
list :linked_comment_post_ids, [:linked_comments, :post], :id do
6666
uniq?(true)
6767
end
68+
69+
first :latest_rating_score, :ratings, :score do
70+
sort(score: :desc)
71+
end
6872
end
6973

7074
calculations do
@@ -78,6 +82,8 @@ defmodule AshPostgres.Test.Comment do
7882
"hello"
7983
end)}
8084
end)
85+
86+
calculate(:has_rating, :boolean, expr(not is_nil(latest_rating_score)))
8187
end
8288

8389
relationships do

test/support/resources/post.ex

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,6 +1349,14 @@ defmodule AshPostgres.Test.Post do
13491349
count :count_of_high_like_comments, :comments do
13501350
filter(expr(likes > 10))
13511351
end
1352+
1353+
count :count_of_comments_with_ratings, :comments do
1354+
filter(expr(has_rating == true))
1355+
end
1356+
1357+
count :count_of_comments_with_high_ratings, :comments do
1358+
filter(expr(latest_rating_score > 5))
1359+
end
13521360
end
13531361
end
13541362

0 commit comments

Comments
 (0)