Edit: paper bag over head … got the OK with the team to update Ecto in the app and the problem appears to have been fixed in Ecto 3.3. Yay for bug fixes! Sorry for the noise …
While building a relatively complex query with Ecto, I came across an error that I figured at first must be something in my code, but was having a hard time seeing what it could be. So I went about creating a minimal case from the full query to pinpoint the issue and ended up with this:
defmodule Queries do
import Ecto.Query
def works_single_statement() do
from f in "files", join: subquery(from s in "types"), on: [t: f.mimetype]
end
def works_without_on() do
query = from f in "files"
from f in query, join: subquery(from s in "types")
end
def fails() do
query = from f in "files"
from f in query, join: subquery(from s in "types"), on: [t: f.mimetype]
end
end
The queries in the minimal case above are pretty nonsensical after having been pared down this far, but they demonstrate the problem. When I use the query from Queries.fails/0
, this occurs:
iex(1)> Queries.fails() |> Repo.all()
** (ArithmeticError) bad argument in arithmetic expression
(ecto) Inspect.Ecto.Query.binding/2
(elixir) lib/macro.ex:880: Macro.module_to_string/2
(elixir) lib/macro.ex:995: Macro.call_to_string/2
(elixir) lib/macro.ex:1003: Macro.call_to_string_with_args/3
(elixir) lib/macro.ex:771: Macro.to_string/2
(elixir) lib/macro.ex:920: Macro.binary_call/2
(elixir) lib/macro.ex:760: Macro.to_string/2
(ecto) lib/ecto/query/inspect.ex:109: Inspect.Ecto.Query.join/3
Similarly, when passing the output from Queries.fails/0
to IO.inspect/2
there is an ArithmeticError that gets caught. So I thought perhaps this is only when Ecto is echoing the queries for display/logging in dev mode (which would still be problematic), but it also happens with MIX_ENV=prod
I have a work-around for the application I am writing, though it uglifies the code. However, I am wondering if anyone else has seen this, or if anyone knows why that exact formulation of a join with a subquery on an existing query might be failing.
Thoughts and insights?
Edit: Forgot the versions… this is is with Ecto 3.1.7 and Elixir 1.9.4