mirror of
https://github.com/ash-project/ash_postgres.git
synced 2024-09-20 05:23:18 +12:00
fix: only apply filters inside aggregate subquery
This commit is contained in:
parent
c2aeb2c8ef
commit
8fa10ac6ec
1 changed files with 43 additions and 26 deletions
|
@ -753,7 +753,9 @@ defmodule AshPostgres.DataLayer do
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def run_aggregate_query(query, aggregates, resource) do
|
def run_aggregate_query(original_query, aggregates, resource) do
|
||||||
|
original_query = default_bindings(original_query, resource)
|
||||||
|
|
||||||
{can_group, cant_group} =
|
{can_group, cant_group} =
|
||||||
aggregates
|
aggregates
|
||||||
|> Enum.split_with(&AshPostgres.Aggregate.can_group?(resource, &1))
|
|> Enum.split_with(&AshPostgres.Aggregate.can_group?(resource, &1))
|
||||||
|
@ -762,37 +764,16 @@ defmodule AshPostgres.DataLayer do
|
||||||
{can_group, cant_group} -> {can_group, cant_group}
|
{can_group, cant_group} -> {can_group, cant_group}
|
||||||
end
|
end
|
||||||
|
|
||||||
query = default_bindings(query, resource)
|
|
||||||
|
|
||||||
query =
|
|
||||||
if query.distinct || query.limit do
|
|
||||||
query =
|
|
||||||
query
|
|
||||||
|> Ecto.Query.exclude(:select)
|
|
||||||
|> Ecto.Query.exclude(:order_by)
|
|
||||||
|> Map.put(:windows, [])
|
|
||||||
|
|
||||||
from(row in subquery(query), as: ^0, select: %{})
|
|
||||||
else
|
|
||||||
query
|
|
||||||
|> Ecto.Query.exclude(:select)
|
|
||||||
|> Ecto.Query.exclude(:order_by)
|
|
||||||
|> Map.put(:windows, [])
|
|
||||||
|> Ecto.Query.select(%{})
|
|
||||||
end
|
|
||||||
|
|
||||||
query_before_select = query
|
|
||||||
|
|
||||||
{global_filter, can_group} =
|
{global_filter, can_group} =
|
||||||
AshPostgres.Aggregate.extract_shared_filters(can_group)
|
AshPostgres.Aggregate.extract_shared_filters(can_group)
|
||||||
|
|
||||||
query =
|
query =
|
||||||
case global_filter do
|
case global_filter do
|
||||||
{:ok, global_filter} ->
|
{:ok, global_filter} ->
|
||||||
filter(query, global_filter, resource)
|
filter(original_query, global_filter, resource)
|
||||||
|
|
||||||
:error ->
|
:error ->
|
||||||
{:ok, query}
|
{:ok, original_query}
|
||||||
end
|
end
|
||||||
|
|
||||||
case query do
|
case query do
|
||||||
|
@ -800,6 +781,23 @@ defmodule AshPostgres.DataLayer do
|
||||||
{:error, error}
|
{:error, error}
|
||||||
|
|
||||||
{:ok, query} ->
|
{:ok, query} ->
|
||||||
|
query =
|
||||||
|
if query.distinct || query.limit do
|
||||||
|
query =
|
||||||
|
query
|
||||||
|
|> Ecto.Query.exclude(:select)
|
||||||
|
|> Ecto.Query.exclude(:order_by)
|
||||||
|
|> Map.put(:windows, [])
|
||||||
|
|
||||||
|
from(row in subquery(query), as: ^0, select: %{})
|
||||||
|
else
|
||||||
|
query
|
||||||
|
|> Ecto.Query.exclude(:select)
|
||||||
|
|> Ecto.Query.exclude(:order_by)
|
||||||
|
|> Map.put(:windows, [])
|
||||||
|
|> Ecto.Query.select(%{})
|
||||||
|
end
|
||||||
|
|
||||||
query =
|
query =
|
||||||
Enum.reduce(
|
Enum.reduce(
|
||||||
can_group,
|
can_group,
|
||||||
|
@ -828,11 +826,28 @@ defmodule AshPostgres.DataLayer do
|
||||||
dynamic_repo(resource, query).one(query, repo_opts(nil, nil, resource))
|
dynamic_repo(resource, query).one(query, repo_opts(nil, nil, resource))
|
||||||
end
|
end
|
||||||
|
|
||||||
{:ok, add_single_aggs(result, resource, query_before_select, cant_group)}
|
{:ok, add_single_aggs(result, resource, original_query, cant_group)}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp add_single_aggs(result, resource, query, cant_group) do
|
defp add_single_aggs(result, resource, query, cant_group) do
|
||||||
|
query =
|
||||||
|
if query.distinct || query.limit do
|
||||||
|
query =
|
||||||
|
query
|
||||||
|
|> Ecto.Query.exclude(:select)
|
||||||
|
|> Ecto.Query.exclude(:order_by)
|
||||||
|
|> Map.put(:windows, [])
|
||||||
|
|
||||||
|
from(row in subquery(query), as: ^0, select: %{})
|
||||||
|
else
|
||||||
|
query
|
||||||
|
|> Ecto.Query.exclude(:select)
|
||||||
|
|> Ecto.Query.exclude(:order_by)
|
||||||
|
|> Map.put(:windows, [])
|
||||||
|
|> Ecto.Query.select(%{})
|
||||||
|
end
|
||||||
|
|
||||||
Enum.reduce(cant_group, result, fn
|
Enum.reduce(cant_group, result, fn
|
||||||
%{kind: :exists} = agg, result ->
|
%{kind: :exists} = agg, result ->
|
||||||
{:ok, filtered} =
|
{:ok, filtered} =
|
||||||
|
@ -948,6 +963,8 @@ defmodule AshPostgres.DataLayer do
|
||||||
{global_filter, can_group} =
|
{global_filter, can_group} =
|
||||||
AshPostgres.Aggregate.extract_shared_filters(can_group)
|
AshPostgres.Aggregate.extract_shared_filters(can_group)
|
||||||
|
|
||||||
|
original_subquery = subquery
|
||||||
|
|
||||||
subquery =
|
subquery =
|
||||||
case global_filter do
|
case global_filter do
|
||||||
{:ok, global_filter} ->
|
{:ok, global_filter} ->
|
||||||
|
@ -1002,7 +1019,7 @@ defmodule AshPostgres.DataLayer do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
{:ok, add_single_aggs(result, source_resource, subquery, cant_group)}
|
{:ok, add_single_aggs(result, source_resource, original_subquery, cant_group)}
|
||||||
end
|
end
|
||||||
|
|
||||||
{:error, error} ->
|
{:error, error} ->
|
||||||
|
|
Loading…
Reference in a new issue