Skip to content

Commit

Permalink
Merge pull request #336 from michallepicki/subquery-group-by
Browse files Browse the repository at this point in the history
Use subqueries in Flop.count for queries with group_by
  • Loading branch information
woylie authored Jun 18, 2023
2 parents f587432 + 5d62388 commit fa196d9
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
28 changes: 26 additions & 2 deletions lib/flop.ex
Original file line number Diff line number Diff line change
Expand Up @@ -779,8 +779,32 @@ defmodule Flop do
if count = opts[:count] do
count
else
q = opts[:count_query] || q
apply_on_repo(:aggregate, "count", [filter(q, flop, opts), :count], opts)
q =
if opts[:count_query] do
filter(opts[:count_query], flop, opts)
else
q |> filter(flop, opts) |> count_query()
end

apply_on_repo(:aggregate, "count", [q, :count], opts)
end
end

defp count_query(query) do
query =
query
|> Query.exclude(:preload)
|> Query.exclude(:order_by)
|> Query.exclude(:select)

case query do
%{group_bys: group_bys} = query when group_bys != [] ->
query
|> Query.select(%{})
|> Query.subquery()

query ->
query
end
end

Expand Down
22 changes: 22 additions & 0 deletions test/flop_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,28 @@ defmodule FlopTest do
# custom count
assert Flop.count(Pet, flop, count: 6) == 6
end

test "counts entries for queries with group_by clauses" do
_owner_1 = insert(:owner, age: 13, pets: build_list(3, :pet))
_owner_2 = insert(:owner, age: 20, pets: build_list(2, :pet))
_owner_3 = insert(:owner, age: 22, pets: build_list(1, :pet))
_non_matching_owner = insert(:owner, age: 52, pets: build_list(4, :pet))

q =
Owner
|> join(:left, [o], p in assoc(o, :pets), as: :pets)
|> group_by([o], o.id)
|> select(
[o, pets: p],
%{o | pet_count: count(p.id)}
)

flop = %Flop{
filters: [%Filter{field: :age, op: :<=, value: 30}]
}

assert Flop.count(q, flop) == 3
end
end

describe "meta/3" do
Expand Down

0 comments on commit fa196d9

Please sign in to comment.