You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
No function clause matching in anonymous fn/1 in Ecto.Adapters.SQLite3.Connection.group_by/2 #160
iex> Insights.list_top_n_customers_by_order_count**(FunctionClauseError) no function clause matching inanonymousfn/1inEcto.Adapters.SQLite3.Connection.group_by/2
Thefollowingargumentsweregiventoanonymousfn/1inEcto.Adapters.SQLite3.Connection.group_by/2:
# 1%Ecto.Query.ByExpr{expr: [{{:.,[],[{:&,[],[0]},:id]},[],[]}],file: ".../Northwind/northwind_elixir_traders/lib/northwind_elixir_traders/insights.ex",line: 43,params: nil,subqueries: []}
...
Any reason why group_by/2 would not work on a Mac? It's the only thing that seems to be pertinently different between our respective setups--the other one being that I'm on Elixir 1.18.2, but the code was working fine even as far back as 1.14, so this can't be the root cause.
Paging @brownerd in case he can provide more information about the platform.
What we found out since yesterday: @brownerd can run the query just fine from within the sqlite3 binary. However, this is irrelevant, as (if I am correct) the underlying exqlite uses the precompiled NIF, and since we are both on the same version of exqlite, we both get the same precompiled shared object sqlite3_nif.so.
Could you please try removing _build and running mix compile --force as well? I have a feeling this is more about some outdated .beam artifact and Elixir structs.
09:03:40.015 [debug] QUERY OK source="customers" db=0.2ms queue=0.2ms idle=1534.8ms
SELECT c0."id", c0."name", count(o1."id") FROM "customers" AS c0 INNER JOIN "orders" AS o1 ON o1."customer_id" = c0."id" GROUP BY c0."id" ORDER BY count(o1."id") DESC LIMIT ? [5]
In a sense, yes. ecto_sqlite3 was outdated, and ecto was current.
But I think it can also be thought of as an issue with versioning due to ecto_sqlite3 0.15 allowing but not supporting ecto 3.12 ... and I don't know of any easy way to prevent issues like that in the future other than following more strict versioning conventions.
Unsure. The only solution I could see offering is doing a patch release on the older version and bumping the min requirement to >= 3.12. Unfortunately I think the versioning thing will always be an issue in the distributed ecosystem we have.
Activity
ruslandoga commentedon Feb 23, 2025
👋 @waseigo
Would you or @brownerd be able to prepare a minimal example that reproduces the issue?
I ran the following on a Mac and it seems to work.
ruslandoga commentedon Feb 23, 2025
The error itself is weird, it seems to happen at
ecto_sqlite3/lib/ecto/adapters/sqlite3/connection.ex
Line 1078 in bbe7ebe
waseigo commentedon Feb 23, 2025
Hello @ruslandoga, thanks for helping out.
What we found out since yesterday: @brownerd can run the query just fine from within the
sqlite3binary. However, this is irrelevant, as (if I am correct) the underlying exqlite uses the precompiled NIF, and since we are both on the same version of exqlite, we both get the same precompiled shared objectsqlite3_nif.so.I have uploaded the latest version of the SQLite3 db here: https://www.dropbox.com/scl/fi/6dnznvup0acm7rmz6o76f/northwind_elixir_traders_repo.db?rlkey=z3k7aif88cxd37m0kbyrk06h4&st=noqsepx6&dl=0
Do you think I should report this issue to the exqlite repo instead?
ruslandoga commentedon Feb 23, 2025
I don't think the binary matters, at least with the information provided so far. The error happens during SQL "building" stage.
waseigo commentedon Feb 23, 2025
@brownerd killed all the deps and re-installed. Upon running iex, he saw this warning during the build:
ruslandoga commentedon Feb 23, 2025
Could you please try removing
_buildand runningmix compile --forceas well? I have a feeling this is more about some outdated.beamartifact and Elixir structs.ruslandoga commentedon Feb 23, 2025
Or even better, upload the whole project together with
_buildanddepssomewhere :)waseigo commentedon Feb 23, 2025
ruslandoga commentedon Feb 23, 2025
I was almost right :) The issue is renamed structs in Ecto.
In the SQLite adapter you are using (ecto_sqlite3 0.15.1) the expected struct is
Ecto.Query.QueryExprhttps://github.com/elixir-sqlite/ecto_sqlite3/blob/v0.15.1/lib/ecto/adapters/sqlite3/connection.ex#L1068
But in Ecto 3.12+ it's been renamed to
Ecto.Query.ByExprThe quickfix is to update the adapter to the latest version.
And the real fix is for this adapter to be more strict with the allowed Ecto versions :)
Related:
gandhiShepard commentedon Feb 23, 2025
I tried the example above and I got this error
Customer |> join(:inner, [c], o in assoc(c, :orders)) |> group_by([c, o], c.id) |> select([c, o], %{id: c.id, name: c.name, num_orders: count(o.id)}) |> order_by([c, o], desc: count(o.id)) |> limit(^5) |> Repo.all
error: undefined function limit/2 (there is no such import)
└─ iex:14
(╯°□°)╯** (CompileError) cannot compile code (errors have been logged)
ruslandoga commentedon Feb 23, 2025
👋 @gandhiShepard
You need to run
import Ecto.Queryfirst. Sorry, I missed it while copy-pasting.It doesn't matter much though, since I think it's clear what the issue is now: #160 (comment)
waseigo commentedon Feb 23, 2025
Also I don't think that the pin operator is needed in front of "5", but doesn't hurt.
gandhiShepard commentedon Feb 23, 2025
Gotcha. The example ran fine
09:03:40.015 [debug] QUERY OK source="customers" db=0.2ms queue=0.2ms idle=1534.8ms
SELECT c0."id", c0."name", count(o1."id") FROM "customers" AS c0 INNER JOIN "orders" AS o1 ON o1."customer_id" = c0."id" GROUP BY c0."id" ORDER BY count(o1."id") DESC LIMIT ? [5]
[
%{id: 1, name: "Ernst Handel", num_orders: 2},
%{id: 2, name: "QUICK-Stop", num_orders: 1}
]
ruslandoga commentedon Feb 23, 2025
The query is built differently with it. And the original example included it.
waseigo commentedon Feb 23, 2025
Yep, you're right -- it passes 5 as a parameter for the
?placeholder.gandhiShepard commentedon Feb 23, 2025
Updating to {:ecto_sqlite3, "~> 0.18.1"} fixed the issue for me. :)
warmwaffles commentedon Feb 23, 2025
So was this just due to outdated dependencies?
ruslandoga commentedon Feb 23, 2025
In a sense, yes.
ecto_sqlite3was outdated, andectowas current.But I think it can also be thought of as an issue with versioning due to
ecto_sqlite3 0.15allowing but not supportingecto 3.12... and I don't know of any easy way to prevent issues like that in the future other than following more strict versioning conventions.warmwaffles commentedon Feb 23, 2025
Unsure. The only solution I could see offering is doing a patch release on the older version and bumping the min requirement to
>= 3.12. Unfortunately I think the versioning thing will always be an issue in the distributed ecosystem we have.Edit: maybe setting an upper bound?
Bump Ecto SQLite3 adapter version to v0.18.1 (see elixir-sqlite/ecto_…
Fix sqlite error