Skip to content

Commit 390aab9

Browse files
committed
Fix finding values for limit and offset with where arrays, close #170
1 parent b897537 commit 390aab9

File tree

2 files changed

+44
-6
lines changed

2 files changed

+44
-6
lines changed

lib/mongo_ecto/normalized_query.ex

+33-6
Original file line numberDiff line numberDiff line change
@@ -345,8 +345,21 @@ defmodule Mongo.Ecto.NormalizedQuery do
345345

346346
defp offset_limit(nil, _params, _pk, _query, _where), do: nil
347347

348-
defp offset_limit(%Query.QueryExpr{expr: expr}, params, pk, query, where),
349-
do: value(expr, params, pk, query, where)
348+
defp offset_limit(%Query.QueryExpr{expr: expr}, params, pk, %Query{wheres: wheres} = query, where) do
349+
case expr do
350+
{:^, l, [idx]} ->
351+
param_offset =
352+
Enum.reduce(wheres, 0, fn %Query.BooleanExpr{expr: expr}, acc ->
353+
_from..to = pair_param_range(expr)
354+
acc + to
355+
end)
356+
357+
value({:^, l, [idx + param_offset]}, params, pk, query, where)
358+
359+
_ ->
360+
value(expr, params, pk, query, where)
361+
end
362+
end
350363

351364
defp primary_key(nil), do: nil
352365

@@ -466,9 +479,10 @@ defmodule Mongo.Ecto.NormalizedQuery do
466479
{field(left, pk, query, place), ["$in": []]}
467480
end
468481

469-
defp pair({:in, _, [left, {:^, _, [ix, len]}]}, params, pk, query, place) do
482+
defp pair({:in, _, [left, _]} = expr, params, pk, query, place) do
470483
args =
471-
ix..(ix + len - 1)
484+
expr
485+
|> pair_param_range()
472486
|> Enum.map(&elem(params, &1))
473487
|> Enum.map(&value(&1, params, pk, query, place))
474488

@@ -483,9 +497,10 @@ defmodule Mongo.Ecto.NormalizedQuery do
483497
{field(left, pk, query, place), [{binary_op(op), value(right, params, pk, query, place)}]}
484498
end
485499

486-
defp pair({:not, _, [{:in, _, [left, {:^, _, [ix, len]}]}]}, params, pk, query, place) do
500+
defp pair({:not, _, [{:in, _, [left, _]}]} = expr, params, pk, query, place) do
487501
args =
488-
ix..(ix + len - 1)
502+
expr
503+
|> pair_param_range()
489504
|> Enum.map(&elem(params, &1))
490505
|> Enum.map(&value(&1, params, pk, query, place))
491506

@@ -545,4 +560,16 @@ defmodule Mongo.Ecto.NormalizedQuery do
545560
defp error(place) do
546561
raise ArgumentError, "Invalid expression for MongoDB adapter in #{place}"
547562
end
563+
564+
defp pair_param_range({:in, _, [_, {:^, _, [ix, len]}]}) do
565+
ix..(ix + len - 1)
566+
end
567+
568+
defp pair_param_range({:not, _, [{:in, _, [_, {:^, _, [ix, len]}]}]}) do
569+
ix..(ix + len - 1)
570+
end
571+
572+
defp pair_param_range(expr) do
573+
0..0
574+
end
548575
end

test/mongo_ecto_test.exs

+11
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,17 @@ defmodule Mongo.EctoTest do
9191
assert 10 == TestRepo.one(query)
9292
end
9393

94+
test "where in ids + dynamic limit + dynamic offset" do
95+
post1 = TestRepo.insert!(%Post{})
96+
post2 = TestRepo.insert!(%Post{})
97+
ids = [post1.id, post2.id]
98+
limit = 1
99+
offset = 1
100+
101+
query = from p in Post, where: p.id in ^ids, limit: ^limit, offset: ^offset
102+
assert TestRepo.all(query) == [post2]
103+
end
104+
94105
# test "partial update in map" do
95106
# post = TestRepo.insert!(%Post{meta: %{author: %{name: "michal"}, other: "value"}})
96107
# TestRepo.update_all(Post, set: [meta: change_map("author.name", "michal")])

0 commit comments

Comments
 (0)