Nebo15 / ecto_mnesia

Ecto adapter for Mnesia Erlang term database.
https://hex.pm/packages/ecto_mnesia
MIT License
243 stars 41 forks source link

Limit does not support expressions #42

Open troygnichols opened 7 years ago

troygnichols commented 7 years ago

With SQL adapters like postgres you can write something like this:

limit = 42
MyRepo.all(from item in Item, limit: ^limit)

In ecto_mnesia, this produces an error like this:

** (FunctionClauseError) no function clause matching in Enum.take/2
 stacktrace:
   (elixir) lib/enum.ex:2334: Enum.take([[%SellOffer{__meta__: #Ecto.Schema.Metadata<:loaded, "sell_offer">, age: 11, application: nil, book_value: nil, booked_at: nil, dividable: nil, dpc: nil, dpd: nil, ended_at: nil, guaranteed: nil, id: 1, income: nil, inserted_at: ~N[2017-07-02 02:32:52.743812], loan_changes: nil, loan_currency: nil, loan_duration: nil, loan_id: "hello", loan_oap: nil, loan_product_type: nil, loan_risk_class: nil, loan_risk_subclass: nil, loan_status: nil, max_shared_apr: nil, min_price_rate: nil, status: nil, trader_id: nil, updated_at: ~N[2017-07-02 02:32:52.743819]}], [%SellOffer{__meta__: #Ecto.Schema.Metadata<:loaded, "sell_offer">, age: 21, application: nil, book_value: nil, booked_at: nil, dividable: nil, dpc: nil, dpd: nil, ended_at: nil, guaranteed: nil, id: 3, income: nil, inserted_at: ~N[2017-07-02 02:32:52.744109], loan_changes: nil, loan_currency: nil, loan_duration: nil, loan_id: "world", loan_oap: nil, loan_product_type: nil, loan_risk_class: nil, loan_risk_subclass: nil, loan_status: nil, max_shared_apr: nil, min_price_rate: nil, status: nil, trader_id: nil, updated_at: ~N[2017-07-02 02:32:52.744113]}], [%SellOffer{__meta__: #Ecto.Schema.Metadata<:loaded, "sell_offer">, age: 15, application: nil, book_value: nil, booked_at: nil, dividable: nil, dpc: nil, dpd: nil, ended_at: nil, guaranteed: nil, id: 2, income: nil, inserted_at: ~N[2017-07-02 02:32:52.743973], loan_changes: nil, loan_currency: nil, loan_duration: nil, loan_id: "hello", loan_oap: nil, loan_product_type: nil, loan_risk_class: nil, loan_risk_subclass: nil, loan_status: nil, max_shared_apr: nil, min_price_rate: nil, status: nil, trader_id: nil, updated_at: ~N[2017-07-02 02:32:52.743977]}]], {:^, [], [0]})
   (ecto_mnesia) lib/ecto_mnesia/planner.ex:65: EctoMnesia.Planner.execute/6
   (ecto) lib/ecto/repo/queryable.ex:130: Ecto.Repo.Queryable.execute/5
   (ecto) lib/ecto/repo/queryable.ex:35: Ecto.Repo.Queryable.all/4
   test/unit/adapter_test.exs:378: (test)

Limit works fine if you give it a literal like this:

    MyRepo.all(from item in Item, limit: 42)

It's only a problem if you use a ^ expression

Expressions do seem to work for order_by, just not limit, e.g. this works fine:

field = :name
MyRepo.all(from item in Item, order_by: [desc: ^field])

Here are some tests that demonstrate the issue:

https://github.com/troygnichols/ecto_mnesia/commit/ae0a038c801fdb39d692fd348bd7b230379c94e4

brodeuralexis commented 6 years ago

I've hit this problem to. Here's what I could figure out:

query = from u in User, limit: ^limit

will set query.limit as a %Ecto.Query.QueryExpr{}

I think EctoMnesia.Planner.get_limit/1 should make use of Ecto.Query.Dynamic.