From 9d9d3eb09ecdfed88235593f22bd186a5cd3b882 Mon Sep 17 00:00:00 2001
From: Anton Satin <8176627+antonsatin@users.noreply.github.com>
Date: Fri, 2 Aug 2024 09:24:09 +0300
Subject: [PATCH] Fix for custom `distinct` handling in laterals

Ecto represents distinct clauses in a query as a
`%Ecto.Query.QueryExpr{}` struct. In Elixir, guards pass only when the
evaluated condition is true but since the distinct struct is not explicitly true, the guard fails to pass.

This update reverses the guard logic so that it passes as long as the distinct value is not nil.
---
 lib/dataloader/ecto.ex                    | 3 ++-
 test/dataloader/ecto/limit_query_test.exs | 6 +++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/lib/dataloader/ecto.ex b/lib/dataloader/ecto.ex
index 33406b6..ab66273 100644
--- a/lib/dataloader/ecto.ex
+++ b/lib/dataloader/ecto.ex
@@ -917,7 +917,8 @@ if Code.ensure_loaded?(Ecto) do
         build_preload_lateral_query(rest, join_query, :join_last)
       end
 
-      defp maybe_distinct(%Ecto.Query{distinct: dist} = query, _) when dist, do: query
+      defp maybe_distinct(%Ecto.Query{distinct: distinct} = query, _) when not is_nil(distinct),
+        do: query
 
       defp maybe_distinct(query, [%Ecto.Association.Has{}, %Ecto.Association.BelongsTo{} | _]),
         do: distinct(query, true)
diff --git a/test/dataloader/ecto/limit_query_test.exs b/test/dataloader/ecto/limit_query_test.exs
index f0d598d..853fb7f 100644
--- a/test/dataloader/ecto/limit_query_test.exs
+++ b/test/dataloader/ecto/limit_query_test.exs
@@ -36,21 +36,21 @@ defmodule Dataloader.LimitQueryTest do
     |> preload(likes: :user)
   end
 
-  defp query(schema, %{limit: limit, order_by: order_by}, test_pid) do
+  defp query(schema, %{limit: limit, distinct: true, order_by: order_by}, test_pid) do
     send(test_pid, :querying)
 
     schema
     |> order_by(^order_by)
     |> limit(^limit)
+    |> distinct(true)
   end
 
-  defp query(schema, %{limit: limit, distinct: true, order_by: order_by}, test_pid) do
+  defp query(schema, %{limit: limit, order_by: order_by}, test_pid) do
     send(test_pid, :querying)
 
     schema
     |> order_by(^order_by)
     |> limit(^limit)
-    |> distinct(true)
   end
 
   test "Query limit does not apply globally", %{loader: loader} do