Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/ecto/query/builder/select.ex
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ defmodule Ecto.Query.Builder.Select do
take?(other) ->
{
{:{}, [], [:&, [], [0]]},
{[], %{take: %{0 => {:any, Macro.expand(other, env)}}, subqueries: [], aliases: %{}}}
{[], %{take: %{0 => {:struct, Macro.expand(other, env)}}, subqueries: [], aliases: %{}}}
}

maybe_take?(other) ->
Expand Down Expand Up @@ -239,7 +239,7 @@ defmodule Ecto.Query.Builder.Select do
end

def select!(kind, query, fields, file, line) do
take = %{0 => {:any, fields!(:select, fields)}}
take = %{0 => {:struct, fields!(:select, fields)}}

%Ecto.Query.SelectExpr{expr: {:&, [], [0]}, take: take, file: file, line: line}
|> apply_or_merge(kind, query)
Expand Down
11 changes: 6 additions & 5 deletions lib/ecto/query/planner.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2258,8 +2258,8 @@ defmodule Ecto.Query.Planner do
{{:ok, {:struct, _}}, {:fragment, _, _}} ->
error!(query, "it is not possible to return a struct subset of a fragment")

{{:ok, {:struct, fields}}, %Ecto.SubQuery{select: select}} ->
subquery_select_fields(select, fields, ix, query)
{{:ok, {kind, fields}}, %Ecto.SubQuery{select: select}} ->
subquery_select_fields(kind, select, fields, ix, query)

{{:ok, {_, []}}, {_, _, _}} ->
error!(
Expand Down Expand Up @@ -2336,7 +2336,7 @@ defmodule Ecto.Query.Planner do
end)
end

defp subquery_select_fields(select, requested_fields, ix, query) do
defp subquery_select_fields(kind, select, requested_fields, ix, query) do
available_fields = subquery_source_fields(select)
requested_fields = List.wrap(requested_fields)

Expand All @@ -2345,7 +2345,7 @@ defmodule Ecto.Query.Planner do
{:source, {_, schema}, _, _} when not is_nil(schema) -> schema

_ ->
error!(query, "it is not possible to return a struct subset of a subquery that does not return a schema struct")
error!(query, "it is not possible to return a #{kind} subset of a subquery that does not return a schema struct")
end

types =
Expand All @@ -2355,12 +2355,13 @@ defmodule Ecto.Query.Planner do
{field, type}

:error ->
error!(query, "field `#{field}` in struct/2 is not available in the subquery. " <>
error!(query, "field `#{field}` in #{kind}/2 is not available in the subquery. " <>
"Subquery only returns fields: #{inspect(available_fields)}")
end
end)

field_exprs = Enum.map(requested_fields, &select_field(&1, ix, :always))
schema = if kind == :map, do: nil, else: schema

{{:source, {nil, schema}, nil, types}, field_exprs}
end
Expand Down
14 changes: 14 additions & 0 deletions test/ecto/query/planner_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -1139,7 +1139,7 @@
] = cache
end

test "on update_all" do

Check failure on line 1142 in test/ecto/query/planner_test.exs

View workflow job for this annotation

GitHub Actions / unit test (1.17.3, 27.2)

test plan: CTEs on update_all (Ecto.Query.PlannerTest)

Check failure on line 1142 in test/ecto/query/planner_test.exs

View workflow job for this annotation

GitHub Actions / unit test (1.14.5, 24.3.4.17)

test plan: CTEs on update_all (Ecto.Query.PlannerTest)

Check failure on line 1142 in test/ecto/query/planner_test.exs

View workflow job for this annotation

GitHub Actions / unit test (1.17.3, 25.0.4)

test plan: CTEs on update_all (Ecto.Query.PlannerTest)

Check failure on line 1142 in test/ecto/query/planner_test.exs

View workflow job for this annotation

GitHub Actions / unit test (1.19.5, 28.4, lint)

test plan: CTEs on update_all (Ecto.Query.PlannerTest)

Check failure on line 1142 in test/ecto/query/planner_test.exs

View workflow job for this annotation

GitHub Actions / unit test (1.18.1, 27.2)

test plan: CTEs on update_all (Ecto.Query.PlannerTest)
recent_comments =
from(c in Comment,
order_by: [desc: c.posted],
Expand Down Expand Up @@ -1267,7 +1267,7 @@
] = cte_cache
end

test "on delete_all" do

Check failure on line 1270 in test/ecto/query/planner_test.exs

View workflow job for this annotation

GitHub Actions / unit test (1.17.3, 27.2)

test plan: CTEs on delete_all (Ecto.Query.PlannerTest)

Check failure on line 1270 in test/ecto/query/planner_test.exs

View workflow job for this annotation

GitHub Actions / unit test (1.14.5, 24.3.4.17)

test plan: CTEs on delete_all (Ecto.Query.PlannerTest)

Check failure on line 1270 in test/ecto/query/planner_test.exs

View workflow job for this annotation

GitHub Actions / unit test (1.17.3, 25.0.4)

test plan: CTEs on delete_all (Ecto.Query.PlannerTest)

Check failure on line 1270 in test/ecto/query/planner_test.exs

View workflow job for this annotation

GitHub Actions / unit test (1.19.5, 28.4, lint)

test plan: CTEs on delete_all (Ecto.Query.PlannerTest)

Check failure on line 1270 in test/ecto/query/planner_test.exs

View workflow job for this annotation

GitHub Actions / unit test (1.18.1, 27.2)

test plan: CTEs on delete_all (Ecto.Query.PlannerTest)
recent_comments =
from(c in Comment,
order_by: [desc: c.posted],
Expand Down Expand Up @@ -2303,7 +2303,7 @@
assert Macro.to_string(query.select.fields) == "[bucket: ^1 + &0.number()]"
end

test "with field select" do

Check failure on line 2306 in test/ecto/query/planner_test.exs

View workflow job for this annotation

GitHub Actions / unit test (1.17.3, 27.2)

test normalize: CTEs with field select (Ecto.Query.PlannerTest)

Check failure on line 2306 in test/ecto/query/planner_test.exs

View workflow job for this annotation

GitHub Actions / unit test (1.14.5, 24.3.4.17)

test normalize: CTEs with field select (Ecto.Query.PlannerTest)

Check failure on line 2306 in test/ecto/query/planner_test.exs

View workflow job for this annotation

GitHub Actions / unit test (1.17.3, 25.0.4)

test normalize: CTEs with field select (Ecto.Query.PlannerTest)

Check failure on line 2306 in test/ecto/query/planner_test.exs

View workflow job for this annotation

GitHub Actions / unit test (1.19.5, 28.4, lint)

test normalize: CTEs with field select (Ecto.Query.PlannerTest)

Check failure on line 2306 in test/ecto/query/planner_test.exs

View workflow job for this annotation

GitHub Actions / unit test (1.18.1, 27.2)

test normalize: CTEs with field select (Ecto.Query.PlannerTest)
query =
"parent"
|> with_cte("cte", as: ^from(r in "cte", select: r.child))
Expand Down Expand Up @@ -2670,6 +2670,20 @@
] = query.select.fields
end

test "normalze: select list of fields from subquery source" do
{_, _, _, select} = subquery(Post) |> select([p], [:title]) |> normalize_with_params()
%{from: {_, {:source, {_, postprocess_schema}, _, types}}} = select
assert postprocess_schema == Post
assert types == [title: :string]
end

test "normalze: select map/2 from subquery source" do
{_, _, _, select} = subquery(Post) |> select([p], map(p, [:title])) |> normalize_with_params()
%{from: {_, {:source, {_, postprocess_schema}, _, types}}} = select
assert postprocess_schema == nil
assert types == [title: :string]
end

test "normalize: select with :%{}" do
query = Post |> select([p], %{p | title: "foo"}) |> normalize()
assert query.select.expr == {:%{}, [], [{:|, [], [{:&, [], [0]}, [title: "foo"]]}]}
Expand Down
Loading