From 5bda6003fbcbaa1868f80c2fb8ddbc6754e5e1b7 Mon Sep 17 00:00:00 2001 From: Greg Rychlewski Date: Sat, 5 Apr 2025 09:08:57 -0400 Subject: [PATCH 1/3] fix nil merges --- lib/ecto/repo/queryable.ex | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/ecto/repo/queryable.ex b/lib/ecto/repo/queryable.ex index 8e4ced5c29..f9d5afd043 100644 --- a/lib/ecto/repo/queryable.ex +++ b/lib/ecto/repo/queryable.ex @@ -310,7 +310,7 @@ defmodule Ecto.Repo.Queryable do defp process(row, {:merge, left, right}, from, adapter) do {left, row} = process(row, left, from, adapter) - {right, row} = process(row, right, from, adapter) + {right, row} = process_merge(row, right, from, adapter) data = case {left, right} do @@ -427,6 +427,15 @@ defmodule Ecto.Repo.Queryable do end) end + defp process_merge(row, {:source, {source, schema}, prefix, types}, _from, adapter) do + struct = Ecto.Schema.Loader.load_struct(schema, prefix, source) + struct_load!(types, row, [], false, struct, adapter) + end + + defp process_merge(row, process, from, adapter) do + process(row, process, from, adapter) + end + @compile {:inline, load!: 5} defp load!(type, value, field, struct, adapter) do case Ecto.Type.adapter_load(adapter, type, value) do From b53bfc4390f97f6cc65144d56bc34bf44ec87b69 Mon Sep 17 00:00:00 2001 From: Greg Rychlewski Date: Mon, 7 Apr 2025 08:41:09 -0400 Subject: [PATCH 2/3] update test --- integration_test/cases/repo.exs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration_test/cases/repo.exs b/integration_test/cases/repo.exs index 9a1bdc0d69..309fe6ee2a 100644 --- a/integration_test/cases/repo.exs +++ b/integration_test/cases/repo.exs @@ -1538,8 +1538,8 @@ defmodule Ecto.Integration.RepoTest do |> select_merge([_l, p], map(p, ^~w(title posted)a)) |> TestRepo.all() - # left join record is not present - assert [%{url: "Q", title: "Z", posted: nil}] = + # left join record is not present, we consider it the same as being present with nils + assert [%{url: "Q", title: nil, posted: nil}] = Permalink |> join(:left, [l], p in Post, on: l.post_id == p.id and p.public == true) |> select([l, p], merge(l, map(p, ^~w(title posted)a))) From 36a5a5e77fb847ea9b59cc98294eeb46991f0ded Mon Sep 17 00:00:00 2001 From: Greg Rychlewski Date: Mon, 7 Apr 2025 08:57:55 -0400 Subject: [PATCH 3/3] update test --- integration_test/cases/repo.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_test/cases/repo.exs b/integration_test/cases/repo.exs index 309fe6ee2a..e0abe00748 100644 --- a/integration_test/cases/repo.exs +++ b/integration_test/cases/repo.exs @@ -1545,7 +1545,7 @@ defmodule Ecto.Integration.RepoTest do |> select([l, p], merge(l, map(p, ^~w(title posted)a))) |> TestRepo.all() - assert [%{url: "Q", title: "Z", posted: nil}] = + assert [%{url: "Q", title: nil, posted: nil}] = Permalink |> join(:left, [l], p in Post, on: l.post_id == p.id and p.public == true) |> select_merge([_l, p], map(p, ^~w(title posted)a))