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
7 changes: 5 additions & 2 deletions lib/ecto/query/builder/order_by.ex
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@ defmodule Ecto.Query.Builder.OrderBy do

defp do_escape({dir, expr}, params_acc, kind, vars, env) do
fun = &escape_expansion(kind, &1, &2, &3, &4, &5)
{ast, params_acc} = Builder.escape(expr, :any, params_acc, vars, {env, fun})
{ast, params_acc} = Builder.escape(expr, :any, params_acc, vars, {get_env(env), fun})
{[{quoted_dir!(kind, dir), ast}], params_acc}
end

defp do_escape(expr, params_acc, kind, vars, env) do
fun = &escape_expansion(kind, &1, &2, &3, &4, &5)
{ast, params_acc} = Builder.escape(expr, :any, params_acc, vars, {env, fun})
{ast, params_acc} = Builder.escape(expr, :any, params_acc, vars, {get_env(env), fun})

if is_list(ast) do
{ast, params_acc}
Expand All @@ -90,6 +90,9 @@ defmodule Ecto.Query.Builder.OrderBy do
end
end

defp get_env({env, _}), do: env
defp get_env(env), do: env

defp escape_expansion(kind, expr, _type, params_acc, vars, env) when is_list(expr) do
escape(kind, expr, params_acc, vars, env)
end
Expand Down
39 changes: 39 additions & 0 deletions test/ecto/query/builder/select_test.exs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
Code.require_file("../builder_test.exs", __DIR__)

defmodule Ecto.Query.Builder.SelectTest do
use ExUnit.Case, async: true

import Ecto.Query
import Ecto.Query.Builder.Select
doctest Ecto.Query.Builder.Select

import Ecto.Query.BuilderTest, only: [my_custom_field: 1, my_complex_order: 1]

defmodule Post do
defstruct [:title]
end
Expand Down Expand Up @@ -174,6 +178,41 @@ defmodule Ecto.Query.Builder.SelectTest do
assert %{alias: _} = query.select.aliases
end

test "supports macro expansion in over/2" do
query = from p in "posts", select: %{row_number: over(row_number(), order_by: [desc: my_custom_field(p)])}

assert {:%{}, [],
[
row_number:
{:over, [],
[
{:row_number, [], []},
[
order_by: [
desc: {:fragment, [], [raw: "lower(", expr: _, raw: ")"]}
]
]
]}
]} = query.select.expr

query = from p in "posts", select: %{row_number: over(row_number(), order_by: my_complex_order(p))}
assert {:%{}, [],
[
row_number:
{:over, [],
[
{:row_number, [], []},
[
order_by: [
desc: _,
asc: {:fragment, [], [raw: "lower(", expr: _, raw: ")"]},
asc: {:nth_value, [], _}
]
]
]}
]} = query.select.expr
end

test "raises if name given to selected_as/2 is not an atom" do
message = "expected literal atom or interpolated value in selected_as/2, got: `\"ident\"`"

Expand Down
Loading