Ecto Inconsistency using limit between 3.9 and 3.10

I am trying to learn Elixir by writing a program utilizing ecto with ecto_sqlite3. While attempting to limit a query to a single result my program was returning

** (FunctionClauseError) no function clause matching in Ecto.Adapters.SQLite3.Connection.limit/2    
    
    The following arguments were given to Ecto.Adapters.SQLite3.Connection.limit/2:
...

After some experiementing I noticed that a similar test case worked with deps

      {:ecto_sqlite3, "~> 0.9.1"},
      {:ecto, "~> 3.9.5"},
      {:ecto_sql, "~> 3.9.2"}

returning

20:34:31.718 [debug] QUERY OK source="sample" db=1.3ms decode=1.3ms idle=16.7ms
SELECT s0."value" FROM "sample" AS s0 WHERE (s0."value" = 'first') []

20:34:31.726 [debug] QUERY OK source="sample" db=0.0ms queue=0.1ms idle=40.4ms
SELECT s0."value" FROM "sample" AS s0 WHERE (s0."value" = 'first') LIMIT 1 []

but fails with deps

      {:ecto_sqlite3, "~> 0.9.1"},
      {:ecto, "~> 3.10.2"},
      {:ecto_sql, "~> 3.10.1"}

returning

20:34:18.974 [debug] QUERY OK source="sample" db=1.0ms decode=1.1ms idle=13.3ms
SELECT s0."value" FROM "sample" AS s0 WHERE (s0."value" = 'first') []
** (FunctionClauseError) no function clause matching in Ecto.Adapters.SQLite3.Connection.limit/2    
    
    The following arguments were given to Ecto.Adapters.SQLite3.Connection.limit/2:
    
        # 1
        #Ecto.Query<from s0 in "sample", where: s0.value == "first", limit: 1, select: %{v: s0.value}>
    
        # 2
        {{[[34, "sample", 34]], [115 | "0"], nil}, []}
    
    Attempted function clauses (showing 2 out of 2):
    
        def limit(%{limit: nil}, _sources)
        def limit(%{limit: %Ecto.Query.QueryExpr{expr: expression}} = query, sources)
    
    (ecto_sqlite3 0.9.1) lib/ecto/adapters/sqlite3/connection.ex:1104: Ecto.Adapters.SQLite3.Connection.limit/2
    (ecto_sqlite3 0.9.1) lib/ecto/adapters/sqlite3/connection.ex:180: Ecto.Adapters.SQLite3.Connection.all/2
    (ecto_sqlite3 0.9.1) lib/ecto/adapters/sqlite3.ex:176: Ecto.Adapters.SQLite3.prepare/2
    (ecto 3.10.3) lib/ecto/query/planner.ex:182: Ecto.Query.Planner.query_without_cache/4
    (ecto 3.10.3) lib/ecto/query/planner.ex:152: Ecto.Query.Planner.query_prepare/6
    (ecto 3.10.3) lib/ecto/query/planner.ex:127: Ecto.Query.Planner.query_with_cache/8
    (ecto 3.10.3) lib/ecto/repo/queryable.ex:211: Ecto.Repo.Queryable.execute/4
    (ecto 3.10.3) lib/ecto/repo/queryable.ex:19: Ecto.Repo.Queryable.all/3

My test database schema is as follows

PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE sample (id INT, value STRING);
INSERT INTO sample VALUES(1,'first');
INSERT INTO sample VALUES(2,'second');
COMMIT;

The test code is as follows

Sql.Repo.all(from s in "sample",  select: %{v: s.value}, where: s.value == "first") 
Sql.Repo.all(from s in "sample",limit: 1,  select: %{v: s.value}, where: s.value == "first")

I am trying to determine whether i) I am making a mistake in my code, ii) I am not taking into account some change between ecto 3.9 and 3.10, iii) this is something I should submit as an issue, or iv) something else?

Any direction would be greatly appreciated.

A good place to check when things like this happen is the dependency’s repo - for ecto_sqlite3, this turns up a PR with a very auspicious title:

that changes the exact line in lib/ecto/adapters/sqlite3/connection.ex that’s raising FunctionClauseError.

According to the Github tags, the first release this commit appeared in was 0.10.0, so you’ll need to upgrade.

3 Likes

Thank you.
Updating to

      {:ecto_sqlite3, "~> 0.10.3"},

and updating deps corrected my issue.

I thought I had made an attempt to update ecto_sqlite3 and there wasn’t a newer release, but I could have made a mistake in that process.

ecto_sqlite3 0.10.x only supports Ecto 3.10 and higher, so if you tried to upgrade while you still had Ecto locked to 3.9 you’d get “no updates available” behavior.

1 Like