Skip to content

Commit b819c36

Browse files
fix nesting
1 parent 93989fc commit b819c36

File tree

2 files changed

+39
-12
lines changed

2 files changed

+39
-12
lines changed

lib/ecto/query/builder.ex

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ defmodule Ecto.Query.Builder do
215215
end
216216

217217
{frags, params_acc} = Enum.map_reduce(frags, params_acc, &escape_fragment(&1, &2, vars, env))
218-
{{:{}, [], [:fragment, [], merge_fragments(pieces, frags)]}, params_acc}
218+
{{:{}, [], [:fragment, [], merge_fragments(pieces, frags, [])]}, params_acc}
219219
end
220220

221221
# subqueries
@@ -638,7 +638,7 @@ defmodule Ecto.Query.Builder do
638638
def fragment_pieces(frag, args) do
639639
frag
640640
|> split_fragment("")
641-
|> merge_fragments(args)
641+
|> merge_fragments(args, [])
642642
end
643643

644644
defp escape_window_description([], params_acc, _vars, _env),
@@ -816,20 +816,24 @@ defmodule Ecto.Query.Builder do
816816
escape(expr, :any, params_acc, vars, env)
817817
end
818818

819-
defp merge_fragments([h1 | t1], [{:splice, exprs} | t2]),
820-
do: [{:raw, h1} | merge_splice(exprs, t1, t2)]
819+
defp merge_fragments([raw_h | raw_t], [{:splice, exprs} | expr_t], []),
820+
do: [{:raw, raw_h} | merge_fragments(raw_t, expr_t, exprs)]
821821

822-
defp merge_fragments([h1 | t1], [h2 | t2]),
823-
do: [{:raw, h1}, {:expr, h2} | merge_fragments(t1, t2)]
822+
defp merge_fragments([raw_h | raw_t], [expr_h | expr_t], []),
823+
do: [{:raw, raw_h}, {:expr, expr_h} | merge_fragments(raw_t, expr_t, [])]
824824

825-
defp merge_fragments([h1], []),
826-
do: [{:raw, h1}]
825+
defp merge_fragments([raw_h], [], []),
826+
do: [{:raw, raw_h}]
827827

828-
defp merge_splice([splice_h], raw_t, expr_t),
829-
do: [{:expr, splice_h} | merge_fragments(raw_t, expr_t)]
828+
defp merge_fragments(raw, expr, [{:splice, exprs} | splice_t]),
829+
do: merge_fragments(raw, expr, exprs ++ splice_t)
830+
831+
defp merge_fragments(raw, expr, [splice_h]),
832+
do: [{:expr, splice_h} | merge_fragments(raw, expr, [])]
833+
834+
defp merge_fragments(raw, expr, [splice_h | splice_t]),
835+
do: [{:expr, splice_h}, {:raw, ","} | merge_fragments(raw, expr, splice_t)]
830836

831-
defp merge_splice([splice_h | splice_t], raw_t, expr_t),
832-
do: [{:expr, splice_h}, {:raw, ","} | merge_splice(splice_t, raw_t, expr_t)]
833837

834838
for {agg, arity} <- @dynamic_aggregates do
835839
defp call_type(unquote(agg), unquote(arity)), do: {:any, :any}

test/ecto/query_test.exs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,6 +1194,7 @@ defmodule Ecto.QueryTest do
11941194
end
11951195

11961196
test "supports compile-time list splicing with nested splicing" do
1197+
# nested runtime splice
11971198
list = [3, 4]
11981199

11991200
query =
@@ -1212,6 +1213,28 @@ defmodule Ecto.QueryTest do
12121213
expr: {:^, _, [2]},
12131214
raw: ")"
12141215
] = parts
1216+
1217+
# nested compile-time splice
1218+
query =
1219+
from p in "posts", where: p.id in fragment("(?,?,?)", ^1, splice([2, splice([3, 4]), 5]), ^6)
1220+
1221+
assert {:in, _, [_, {:fragment, _, parts}]} = hd(query.wheres).expr
1222+
1223+
assert [
1224+
raw: "(",
1225+
expr: {:^, _, [0]},
1226+
raw: ",",
1227+
expr: 2,
1228+
raw: ",",
1229+
expr: 3,
1230+
raw: ",",
1231+
expr: 4,
1232+
raw: ",",
1233+
expr: 5,
1234+
raw: ",",
1235+
expr: {:^, _, [1]},
1236+
raw: ")"
1237+
] = parts
12151238
end
12161239

12171240
test "supports compile-time splicing with macro" do

0 commit comments

Comments
 (0)