diff --git a/integration_test/cases/repo.exs b/integration_test/cases/repo.exs index e0abe00748..35ae119e86 100644 --- a/integration_test/cases/repo.exs +++ b/integration_test/cases/repo.exs @@ -1432,6 +1432,26 @@ defmodule Ecto.Integration.RepoTest do assert p3 == %{id: pid3} end + test "take with join nil maps" do + TestRepo.insert!(%Post{}) + + assert {%{title: nil}, %{title: nil}} == + from(p1 in Post) + |> join(:left, [p1], p2 in Post, on: p1.id == p2.id) + |> select([p1, p2], {map(p1, [:title]), map(p2, [:title])}) + |> TestRepo.one() + end + + test "take with join nil source" do + TestRepo.insert!(%Post{}) + + assert {%{title: nil}, nil} == + from(p1 in Post) + |> join(:left, [p1], p2 in Post, on: p2.id == -1) + |> select([p1, p2], {map(p1, [:title]), p2}) + |> TestRepo.one() + end + test "take with preload assocs" do %{id: pid} = TestRepo.insert!(%Post{title: "post"}) TestRepo.insert!(%Comment{post_id: pid, text: "comment"}) diff --git a/lib/ecto/repo/queryable.ex b/lib/ecto/repo/queryable.ex index f9d5afd043..43e8d07797 100644 --- a/lib/ecto/repo/queryable.ex +++ b/lib/ecto/repo/queryable.ex @@ -203,11 +203,11 @@ defmodule Ecto.Repo.Queryable do struct_load!(types, values, [{field, value} | acc], all_nil?, struct, adapter) end - def struct_load!([], values, _acc, true, _struct, _adapter) do + def struct_load!([], values, _acc, true, struct, _adapter) when struct != %{} do {nil, values} end - def struct_load!([], values, acc, false, struct, _adapter) do + def struct_load!([], values, acc, _all_nil?, struct, _adapter) do {Map.merge(struct, Map.new(acc)), values} end @@ -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_merge(row, right, from, adapter) + {right, row} = process(row, right, from, adapter) data = case {left, right} do @@ -427,15 +427,6 @@ 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