mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 13:33:20 +12:00
fix: don't optimize across or
boundaries
This commit is contained in:
parent
2e5f045f72
commit
b67c2b7f34
2 changed files with 21 additions and 17 deletions
|
@ -804,15 +804,15 @@ defmodule Ash.Filter do
|
||||||
defp simple_eq?(_, _), do: false
|
defp simple_eq?(_, _), do: false
|
||||||
|
|
||||||
def find_value(expr, pred) do
|
def find_value(expr, pred) do
|
||||||
do_find(expr, pred, true)
|
do_find(expr, pred, true, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc "Find an expression inside of a filter that matches the provided predicate"
|
@doc "Find an expression inside of a filter that matches the provided predicate"
|
||||||
def find(expr, pred) do
|
def find(expr, pred, ors? \\ true) do
|
||||||
do_find(expr, pred, false)
|
do_find(expr, pred, false, ors?)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp do_find(expr, pred, value?) do
|
defp do_find(expr, pred, value?, ors?) do
|
||||||
if value = pred.(expr) do
|
if value = pred.(expr) do
|
||||||
if value? do
|
if value? do
|
||||||
value
|
value
|
||||||
|
@ -822,22 +822,26 @@ defmodule Ash.Filter do
|
||||||
else
|
else
|
||||||
case expr do
|
case expr do
|
||||||
%__MODULE__{expression: expression} ->
|
%__MODULE__{expression: expression} ->
|
||||||
find(expression, pred)
|
find(expression, pred, ors?)
|
||||||
|
|
||||||
%Not{expression: expression} ->
|
%Not{expression: expression} ->
|
||||||
find(expression, pred)
|
find(expression, pred, ors?)
|
||||||
|
|
||||||
%BooleanExpression{left: left, right: right} ->
|
%BooleanExpression{op: op, left: left, right: right} ->
|
||||||
find(left, pred) || find(right, pred)
|
if op == :or && !ors? do
|
||||||
|
nil
|
||||||
|
else
|
||||||
|
find(left, pred, ors?) || find(right, pred, ors?)
|
||||||
|
end
|
||||||
|
|
||||||
%Call{args: arguments} ->
|
%Call{args: arguments} ->
|
||||||
Enum.find(arguments, &find(&1, pred))
|
Enum.find(arguments, &find(&1, pred, ors?))
|
||||||
|
|
||||||
%{__operator__?: true, left: left, right: right} ->
|
%{__operator__?: true, left: left, right: right} ->
|
||||||
find(left, pred) || find(right, pred)
|
find(left, pred, ors?) || find(right, pred, ors?)
|
||||||
|
|
||||||
%{__function__?: true, arguments: arguments} ->
|
%{__function__?: true, arguments: arguments} ->
|
||||||
Enum.find(arguments, &find(&1, pred))
|
Enum.find(arguments, &find(&1, pred, ors?))
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
nil
|
nil
|
||||||
|
|
|
@ -220,15 +220,15 @@ defmodule Ash.Query.BooleanExpression do
|
||||||
end
|
end
|
||||||
|
|
||||||
def optimized_new(
|
def optimized_new(
|
||||||
op,
|
:and,
|
||||||
%__MODULE__{left: left, right: right} = left_expr,
|
%__MODULE__{op: :and, left: left, right: right} = left_expr,
|
||||||
right_expr,
|
right_expr,
|
||||||
op
|
op
|
||||||
) do
|
) do
|
||||||
case right_expr do
|
case right_expr do
|
||||||
%In{} = in_op ->
|
%In{} = in_op ->
|
||||||
with {:left, nil} <- {:left, Ash.Filter.find(left, &simplify?(&1, in_op))},
|
with {:left, nil} <- {:left, Ash.Filter.find(left, &simplify?(&1, in_op), false)},
|
||||||
{:right, nil} <- {:right, Ash.Filter.find(right, &simplify?(&1, in_op))} do
|
{:right, nil} <- {:right, Ash.Filter.find(right, &simplify?(&1, in_op), false)} do
|
||||||
do_new(op, left_expr, in_op)
|
do_new(op, left_expr, in_op)
|
||||||
else
|
else
|
||||||
{:left, _} ->
|
{:left, _} ->
|
||||||
|
@ -240,9 +240,9 @@ defmodule Ash.Query.BooleanExpression do
|
||||||
|
|
||||||
%Eq{} = eq_op ->
|
%Eq{} = eq_op ->
|
||||||
with {:left, nil} <-
|
with {:left, nil} <-
|
||||||
{:left, Ash.Filter.find(left, &simplify?(&1, eq_op))},
|
{:left, Ash.Filter.find(left, &simplify?(&1, eq_op), false)},
|
||||||
{:right, nil} <-
|
{:right, nil} <-
|
||||||
{:right, Ash.Filter.find(right, &simplify?(&1, eq_op))} do
|
{:right, Ash.Filter.find(right, &simplify?(&1, eq_op), false)} do
|
||||||
do_new(op, left_expr, eq_op)
|
do_new(op, left_expr, eq_op)
|
||||||
else
|
else
|
||||||
{:left, _} ->
|
{:left, _} ->
|
||||||
|
|
Loading…
Reference in a new issue