Skip to content

Commit

Permalink
Allow exclude/2 to remove windows (#4569)
Browse files Browse the repository at this point in the history
  • Loading branch information
greg-rychlewski authored Jan 20, 2025
1 parent aacf5ff commit 372934d
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
18 changes: 16 additions & 2 deletions lib/ecto/query.ex
Original file line number Diff line number Diff line change
Expand Up @@ -957,9 +957,9 @@ defmodule Ecto.Query do
Ecto.Query.exclude(query, :lock)
Ecto.Query.exclude(query, :preload)
Ecto.Query.exclude(query, :update)
Ecto.Query.exclude(query, :windows)
You can also remove specific joins as well such as `left_join` and
`inner_join`:
You can remove specific joins such as `left_join` and `inner_join`:
Ecto.Query.exclude(query, :inner_join)
Ecto.Query.exclude(query, :cross_join)
Expand All @@ -973,6 +973,14 @@ defmodule Ecto.Query do
However, keep in mind that if a join is removed and its bindings
were referenced elsewhere, the bindings won't be removed, leading
to a query that won't compile.
You can remove specific windows by name:
Ecto.Query.exclude(query, {:windows, [name1, name2]})
If a window was referenced elsewhere, for example in `select` or `order_by`,
it won't be removed. You must recreate the expressions manually.
"""
def exclude(%Ecto.Query{} = query, field), do: do_exclude(query, field)
def exclude(query, field), do: do_exclude(Ecto.Queryable.to_query(query), field)
Expand All @@ -988,6 +996,11 @@ defmodule Ecto.Query do
%{query | joins: remaining, aliases: aliases}
end

defp do_exclude(%Ecto.Query{} = query, {:windows, window_names}) when is_list(window_names) do
remaining = Enum.filter(query.windows, fn {name, _} -> name not in window_names end)
%{query | windows: remaining}
end

defp do_exclude(%Ecto.Query{} = query, :where), do: %{query | wheres: []}
defp do_exclude(%Ecto.Query{} = query, :order_by), do: %{query | order_bys: []}
defp do_exclude(%Ecto.Query{} = query, :group_by), do: %{query | group_bys: []}
Expand All @@ -1001,6 +1014,7 @@ defmodule Ecto.Query do
defp do_exclude(%Ecto.Query{} = query, :lock), do: %{query | lock: nil}
defp do_exclude(%Ecto.Query{} = query, :preload), do: %{query | preloads: [], assocs: []}
defp do_exclude(%Ecto.Query{} = query, :update), do: %{query | updates: []}
defp do_exclude(%Ecto.Query{} = query, :windows), do: %{query | windows: []}

@doc """
Creates a query.
Expand Down
12 changes: 12 additions & 0 deletions test/ecto/query_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,18 @@ defmodule Ecto.QueryTest do
assert excluded_all_joins_query.joins == []
assert Map.has_key?(excluded_all_joins_query.aliases, :base)
end

test "removes windows" do
query =
from p in "posts",
windows: [title: [partition_by: p.title], visits: [partition_by: p.visits]]

exclude_all = exclude(query, :windows)
assert exclude_all.windows == []

exclude_one = exclude(query, {:windows, [:title]})
assert [visits: %Ecto.Query.ByExpr{}] = exclude_one.windows
end
end

describe "dynamic/2" do
Expand Down

0 comments on commit 372934d

Please sign in to comment.