diff --git a/lib/ecto/repo.ex b/lib/ecto/repo.ex index b9c7a0b50d..9e5188aa9f 100644 --- a/lib/ecto/repo.ex +++ b/lib/ecto/repo.ex @@ -750,7 +750,7 @@ defmodule Ecto.Repo do @doc """ Calculate the given `aggregate`. - If the query has a limit, offset or distinct set, it will be + If the query has a limit, offset, distinct or combination set, it will be automatically wrapped in a subquery in order to return the proper result. diff --git a/lib/ecto/repo/queryable.ex b/lib/ecto/repo/queryable.ex index fa7034975c..f1014bce9e 100644 --- a/lib/ecto/repo/queryable.ex +++ b/lib/ecto/repo/queryable.ex @@ -473,7 +473,7 @@ defmodule Ecto.Repo.Queryable do defp query_for_aggregate(queryable, aggregate) do query = case prepare_for_aggregate(queryable) do - %{distinct: nil, limit: nil, offset: nil} = query -> + %{distinct: nil, limit: nil, offset: nil, combinations: []} = query -> %{query | order_bys: []} query -> @@ -491,7 +491,7 @@ defmodule Ecto.Repo.Queryable do query = case prepare_for_aggregate(queryable) do - %{distinct: nil, limit: nil, offset: nil} = query -> + %{distinct: nil, limit: nil, offset: nil, combinations: []} = query -> %{query | order_bys: []} query -> diff --git a/test/ecto/repo_test.exs b/test/ecto/repo_test.exs index 4d923b61d9..7c0cd0ec8e 100644 --- a/test/ecto/repo_test.exs +++ b/test/ecto/repo_test.exs @@ -355,7 +355,7 @@ defmodule Ecto.RepoTest do assert inspect(query) == "#Ecto.Query" end - test "removes order by from query without distinct/limit/offset" do + test "removes order by from query without distinct/limit/offset/combinations" do from(MySchema, order_by: :id) |> TestRepo.aggregate(:count, :id) assert_received {:all, query} assert inspect(query) == "#Ecto.Query" @@ -376,6 +376,17 @@ defmodule Ecto.RepoTest do " select: %{id: m0.id}), select: count(m0.id)>" end + test "uses subqueries with combinations" do + from(MySchema, union: ^from(MySchema)) |> TestRepo.aggregate(:count, :id) + assert_received {:all, query} + + assert inspect(query) == + "#Ecto.Query + " union: (from m0 in Ecto.RepoTest.MySchema,\n" <> + " select: m0),\n" <> + " select: %{id: m0.id}), select: count(m0.id)>" + end + test "raises when aggregating with group_by" do assert_raise Ecto.QueryError, ~r"cannot aggregate on query with group_by", fn -> from(MySchema, group_by: [:id]) |> TestRepo.aggregate(:count, :id)