Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
11 changes: 10 additions & 1 deletion lib/ecto/query/builder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ defmodule Ecto.Query.Builder do
optional(any) => any
}

@doc """
Returns the file of the given environment to store in query expressions.

It is relative to the current working directory when inside it, like the
paths in Elixir's stacktraces and diagnostics, so copies of a project that
reuse its build (such as git worktrees) report their own files.
"""
def file(%Macro.Env{file: file}), do: Path.relative_to_cwd(file)

@doc """
Smart escapes a query expression and extracts interpolated values in
a map.
Expand Down Expand Up @@ -1630,7 +1639,7 @@ defmodule Ecto.Query.Builder do

For example, take into account the `Builder.OrderBy`:

select = %Ecto.Query.QueryExpr{expr: expr, file: env.file, line: env.line}
select = %Ecto.Query.QueryExpr{expr: expr, file: file(env), line: env.line}
Builder.apply_query(query, __MODULE__, [order_by], env)

`expr` is already an escaped expression and we must not escape
Expand Down
2 changes: 1 addition & 1 deletion lib/ecto/query/builder/cte.ex
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ defmodule Ecto.Query.Builder.CTE do
%Ecto.Query.QueryExpr{
expr: unquote(expr),
params: unquote(params),
file: unquote(env.file),
file: unquote(Builder.file(env)),
line: unquote(env.line)
}
end
Expand Down
4 changes: 2 additions & 2 deletions lib/ecto/query/builder/distinct.ex
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ defmodule Ecto.Query.Builder.Distinct do
@spec build(Macro.t, [Macro.t], Macro.t, Macro.Env.t) :: Macro.t
def build(query, _binding, {:^, _, [var]}, env) do
quote do
Ecto.Query.Builder.Distinct.distinct!(unquote(query), unquote(var), unquote(env.file), unquote(env.line))
Ecto.Query.Builder.Distinct.distinct!(unquote(query), unquote(var), unquote(Builder.file(env)), unquote(env.line))
end
end

Expand All @@ -70,7 +70,7 @@ defmodule Ecto.Query.Builder.Distinct do
expr: unquote(expr),
params: unquote(params),
subqueries: unquote(Enum.reverse(acc.subqueries)),
file: unquote(env.file),
file: unquote(Builder.file(env)),
line: unquote(env.line)}
Builder.apply_query(query, __MODULE__, [distinct], env)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/ecto/query/builder/dynamic.ex
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ defmodule Ecto.Query.Builder.Dynamic do
{unquote(expr), unquote(params), unquote(Enum.reverse(acc.subqueries)), unquote(aliases)}
end,
binding: unquote(Macro.escape(binding)),
file: unquote(env.file),
file: unquote(Builder.file(env)),
line: unquote(env.line)}
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/ecto/query/builder/filter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ defmodule Ecto.Query.Builder.Filter do
def build(kind, op, query, _binding, {:^, _, [var]}, env) do
quote do
Ecto.Query.Builder.Filter.filter!(unquote(kind), unquote(op), unquote(query),
unquote(var), 0, unquote(env.file), unquote(env.line))
unquote(var), 0, unquote(Builder.file(env)), unquote(env.line))
end
end

Expand All @@ -74,7 +74,7 @@ defmodule Ecto.Query.Builder.Filter do
op: unquote(op),
params: unquote(params),
subqueries: unquote(subqueries),
file: unquote(env.file),
file: unquote(Builder.file(env)),
line: unquote(env.line)}
Builder.apply_query(query, __MODULE__, [kind, expr], env)
end
Expand Down
12 changes: 6 additions & 6 deletions lib/ecto/query/builder/from.ex
Original file line number Diff line number Diff line change
Expand Up @@ -103,28 +103,28 @@ defmodule Ecto.Query.Builder.From do
# dependencies between modules are added
source = quote(do: unquote(schema).__schema__(:source))
{:ok, prefix} = prefix || {:ok, quote(do: unquote(schema).__schema__(:prefix))}
{query(prefix, {source, schema}, [], as, hints, env.file, env.line), binds, 1}
{query(prefix, {source, schema}, [], as, hints, Builder.file(env), env.line), binds, 1}

source when is_binary(source) ->
{:ok, prefix} = prefix || {:ok, nil}
# When a binary is used, there is no schema
{query(prefix, {source, nil}, [], as, hints, env.file, env.line), binds, 1}
{query(prefix, {source, nil}, [], as, hints, Builder.file(env), env.line), binds, 1}

{source, schema} when is_binary(source) and is_atom(schema) ->
{:ok, prefix} = prefix || {:ok, quote(do: unquote(schema).__schema__(:prefix))}
{query(prefix, {source, schema}, [], as, hints, env.file, env.line), binds, 1}
{query(prefix, {source, schema}, [], as, hints, Builder.file(env), env.line), binds, 1}

{{:{}, _, [:fragment, _, _]} = fragment, params} ->
{:ok, prefix} = prefix || {:ok, nil}
{query(prefix, fragment, params, as, hints, env.file, env.line), binds, 1}
{query(prefix, fragment, params, as, hints, Builder.file(env), env.line), binds, 1}

{{{:{}, _, [:fragment, _, _]} = fragment, params}, schema} when is_atom(schema) ->
{:ok, prefix} = prefix || {:ok, nil}
{query(prefix, {fragment, schema}, params, as, hints, env.file, env.line), binds, 1}
{query(prefix, {fragment, schema}, params, as, hints, Builder.file(env), env.line), binds, 1}

{{:{}, _, [:values, _, _]} = values, prelude, params} ->
{:ok, prefix} = prefix || {:ok, nil}
query = query(prefix, values, params, as, hints, env.file, env.line)
query = query(prefix, values, params, as, hints, Builder.file(env), env.line)

quoted =
quote do
Expand Down
4 changes: 2 additions & 2 deletions lib/ecto/query/builder/group_by.ex
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ defmodule Ecto.Query.Builder.GroupBy do
@spec build(Macro.t, [Macro.t], Macro.t, Macro.Env.t) :: Macro.t
def build(query, _binding, {:^, _, [var]}, env) do
quote do
Ecto.Query.Builder.GroupBy.group_by!(unquote(query), unquote(var), unquote(env.file), unquote(env.line))
Ecto.Query.Builder.GroupBy.group_by!(unquote(query), unquote(var), unquote(Builder.file(env)), unquote(env.line))
end
end

Expand All @@ -106,7 +106,7 @@ defmodule Ecto.Query.Builder.GroupBy do
expr: unquote(expr),
params: unquote(params),
subqueries: unquote(Enum.reverse(acc.subqueries)),
file: unquote(env.file),
file: unquote(Builder.file(env)),
line: unquote(env.line)}
Builder.apply_query(query, __MODULE__, [group_by], env)
end
Expand Down
6 changes: 3 additions & 3 deletions lib/ecto/query/builder/join.ex
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ defmodule Ecto.Query.Builder.Join do
join = [
as: as,
assoc: join_assoc,
file: env.file,
file: Builder.file(env),
line: env.line,
params: join_params,
prefix: prefix,
Expand Down Expand Up @@ -266,7 +266,7 @@ defmodule Ecto.Query.Builder.Join do
unquote(var),
unquote(as),
unquote(count_bind),
unquote(env.file),
unquote(Builder.file(env)),
unquote(env.line)
)
end
Expand All @@ -291,7 +291,7 @@ defmodule Ecto.Query.Builder.Join do
expr: unquote(on_expr),
params: unquote(on_params),
line: unquote(env.line),
file: unquote(env.file)
file: unquote(Builder.file(env))
}
}
end
Expand Down
4 changes: 2 additions & 2 deletions lib/ecto/query/builder/limit_offset.ex
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ defmodule Ecto.Query.Builder.LimitOffset do
quote do: %Ecto.Query.LimitExpr{
expr: unquote(expr),
params: unquote(params),
file: unquote(env.file),
file: unquote(Builder.file(env)),
line: unquote(env.line)
}
end
Expand All @@ -63,7 +63,7 @@ defmodule Ecto.Query.Builder.LimitOffset do
quote do: %Ecto.Query.QueryExpr{
expr: unquote(expr),
params: unquote(params),
file: unquote(env.file),
file: unquote(Builder.file(env)),
line: unquote(env.line)
}
end
Expand Down
4 changes: 2 additions & 2 deletions lib/ecto/query/builder/order_by.ex
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ defmodule Ecto.Query.Builder.OrderBy do
unquote(query),
unquote(var),
unquote(op),
unquote(env.file),
unquote(Builder.file(env)),
unquote(env.line)
)
end
Expand All @@ -255,7 +255,7 @@ defmodule Ecto.Query.Builder.OrderBy do
expr: unquote(expr),
params: unquote(params),
subqueries: unquote(Enum.reverse(acc.subqueries)),
file: unquote(env.file),
file: unquote(Builder.file(env)),
line: unquote(env.line)
}

Expand Down
4 changes: 2 additions & 2 deletions lib/ecto/query/builder/select.ex
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ defmodule Ecto.Query.Builder.Select do
def build(kind, query, _binding, {:^, _, [var]}, env) do
quote do
Ecto.Query.Builder.Select.select!(unquote(kind), unquote(query), unquote(var),
unquote(env.file), unquote(env.line))
unquote(Builder.file(env)), unquote(env.line))
end
end

Expand All @@ -324,7 +324,7 @@ defmodule Ecto.Query.Builder.Select do
select = quote do: %Ecto.Query.SelectExpr{
expr: unquote(expr),
params: unquote(params),
file: unquote(env.file),
file: unquote(Builder.file(env)),
line: unquote(env.line),
take: unquote(take),
subqueries: unquote(acc.subqueries),
Expand Down
4 changes: 2 additions & 2 deletions lib/ecto/query/builder/update.ex
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ defmodule Ecto.Query.Builder.Update do

update = quote do
%Ecto.Query.QueryExpr{expr: unquote(compile), params: unquote(params),
file: unquote(env.file), line: unquote(env.line)}
file: unquote(Builder.file(env)), line: unquote(env.line)}
end

Builder.apply_query(query, __MODULE__, [update], env)
Expand All @@ -127,7 +127,7 @@ defmodule Ecto.Query.Builder.Update do
else
quote do
Ecto.Query.Builder.Update.update!(unquote(query), unquote(runtime),
unquote(env.file), unquote(env.line))
unquote(Builder.file(env)), unquote(env.line))
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/ecto/query/builder/windows.ex
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ defmodule Ecto.Query.Builder.Windows do
Ecto.Query.Builder.Windows.runtime!(
unquote(query),
unquote(runtime),
unquote(env.file),
unquote(Builder.file(env)),
unquote(env.line)
)
end
Expand All @@ -149,7 +149,7 @@ defmodule Ecto.Query.Builder.Windows do
expr: unquote(compile_acc),
params: unquote(params),
subqueries: unquote(Enum.reverse(acc.subqueries)),
file: unquote(env.file),
file: unquote(Builder.file(env)),
line: unquote(env.line)
}
end}
Expand Down
14 changes: 14 additions & 0 deletions test/ecto/query_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,20 @@ defmodule Ecto.QueryTest do
end

describe "query building" do
test "stores the file relative to the current directory" do
file = Path.relative_to_cwd(__ENV__.file)
assert Path.type(file) == :relative

query = from p in "posts", where: p.id == 1, select: p.id, order_by: p.id
assert query.from.file == file
assert hd(query.wheres).file == file
assert query.select.file == file
assert hd(query.order_bys).file == file

query = select("posts", [p], p.id)
assert query.select.file == file
end

test "allows macros" do
test_data = "test"
query = from(p in "posts") |> where([q], Macros.macro_equal(q.title, ^test_data))
Expand Down
Loading