Skip to content

Commit 1bf8166

Browse files
authored
Add support for cross lateral joins. (#458)
1 parent 4371bb7 commit 1bf8166

File tree

7 files changed

+31
-2
lines changed

7 files changed

+31
-2
lines changed

lib/ecto/adapters/myxql/connection.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ if Code.ensure_loaded?(MyXQL) do
388388
end
389389

390390
defp join_on(:cross, true, _sources, _query), do: []
391+
defp join_on(:cross_lateral, true, _sources, _query), do: []
391392
defp join_on(_qual, expr, sources, query), do: [" ON " | expr(expr, sources, query)]
392393

393394
defp join_qual(:inner, _), do: " INNER JOIN "
@@ -397,6 +398,7 @@ if Code.ensure_loaded?(MyXQL) do
397398
defp join_qual(:right, _), do: " RIGHT OUTER JOIN "
398399
defp join_qual(:full, _), do: " FULL OUTER JOIN "
399400
defp join_qual(:cross, _), do: " CROSS JOIN "
401+
defp join_qual(:cross_lateral, _), do: " CROSS JOIN LATERAL "
400402

401403
defp where(%{wheres: wheres} = query, sources) do
402404
boolean(" WHERE ", wheres, sources, query)

lib/ecto/adapters/postgres/connection.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,7 @@ if Code.ensure_loaded?(Postgrex) do
510510
end
511511

512512
defp join_on(:cross, true, _sources, _query), do: []
513+
defp join_on(:cross_lateral, true, _sources, _query), do: []
513514
defp join_on(_qual, expr, sources, query), do: [" ON " | expr(expr, sources, query)]
514515

515516
defp join_qual(:inner), do: "INNER JOIN "
@@ -519,6 +520,7 @@ if Code.ensure_loaded?(Postgrex) do
519520
defp join_qual(:right), do: "RIGHT OUTER JOIN "
520521
defp join_qual(:full), do: "FULL OUTER JOIN "
521522
defp join_qual(:cross), do: "CROSS JOIN "
523+
defp join_qual(:cross_lateral), do: "CROSS JOIN LATERAL "
522524

523525
defp where(%{wheres: wheres} = query, sources) do
524526
boolean(" WHERE ", wheres, sources, query)

lib/ecto/adapters/tds/connection.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,7 @@ if Code.ensure_loaded?(Tds) do
526526
defp join_qual(:cross), do: "CROSS JOIN "
527527
defp join_qual(:inner_lateral), do: "CROSS APPLY "
528528
defp join_qual(:left_lateral), do: "OUTER APPLY "
529+
defp join_qual(:cross_lateral), do: error!(nil, "cross lateral joins are not supported in the Tds Adapter")
529530

530531
defp where(%Query{wheres: wheres} = query, sources) do
531532
boolean(" WHERE ", wheres, sources, query)

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ defmodule EctoSQL.MixProject do
7777
if path = System.get_env("ECTO_PATH") do
7878
{:ecto, path: path}
7979
else
80-
{:ecto, "~> 3.9.0"}
80+
{:ecto, "~> 3.10.0-dev", github: "elixir-ecto/ecto"}
8181
end
8282
end
8383

mix.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
77
"deep_merge": {:hex, :deep_merge, "0.2.0", "c1050fa2edf4848b9f556fba1b75afc66608a4219659e3311d9c9427b5b680b3", [:mix], [], "hexpm", "e3bf435a54ed27b0ba3a01eb117ae017988804e136edcbe8a6a14c310daa966e"},
88
"earmark_parser": {:hex, :earmark_parser, "1.4.29", "149d50dcb3a93d9f3d6f3ecf18c918fb5a2d3c001b5d3305c926cddfbd33355b", [:mix], [], "hexpm", "4902af1b3eb139016aed210888748db8070b8125c2342ce3dcae4f38dcc63503"},
9-
"ecto": {:hex, :ecto, "3.9.0", "7c74fc0d950a700eb7019057ff32d047ed7f19b57c1b2ca260cf0e565829101d", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fed5ebc5831378b916afd0b5852a0c5bb3e7390665cc2b0ec8ab0c712495b73d"},
9+
"ecto": {:git, "https://github.com/elixir-ecto/ecto.git", "96d4920339d5d645dedaed1ef2ce7428683f529d", []},
1010
"ex_doc": {:hex, :ex_doc, "0.29.0", "4a1cb903ce746aceef9c1f9ae8a6c12b742a5461e6959b9d3b24d813ffbea146", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "f096adb8bbca677d35d278223361c7792d496b3fc0d0224c9d4bc2f651af5db1"},
1111
"jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"},
1212
"makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},

test/ecto/adapters/myxql_test.exs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,18 @@ defmodule Ecto.Adapters.MyXQLTest do
10061006
~s{WHERE ((s0.`id` > 0) AND (s0.`id` < ?))}
10071007
end
10081008

1009+
test "cross lateral join with fragment" do
1010+
query = Schema
1011+
|> join(:cross_lateral, [p], q in fragment("SELECT * FROM schema2 AS s2 WHERE s2.id = ? AND s2.field = ?", p.x, ^10))
1012+
|> select([p, q], {p.id, q.z})
1013+
|> where([p], p.id > 0 and p.id < ^100)
1014+
|> plan()
1015+
assert all(query) ==
1016+
~s{SELECT s0.`id`, f1.`z` FROM `schema` AS s0 CROSS JOIN LATERAL } <>
1017+
~s{(SELECT * FROM schema2 AS s2 WHERE s2.id = s0.`x` AND s2.field = ?) AS f1 } <>
1018+
~s{WHERE ((s0.`id` > 0) AND (s0.`id` < ?))}
1019+
end
1020+
10091021
test "cross join" do
10101022
query = from(p in Schema, cross_join: c in Schema2, select: {p.id, c.id}) |> plan()
10111023
assert all(query) ==

test/ecto/adapters/postgres_test.exs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,6 +1162,18 @@ defmodule Ecto.Adapters.PostgresTest do
11621162
~s{WHERE ((s0."id" > 0) AND (s0."id" < $2))}
11631163
end
11641164

1165+
test "cross lateral join with fragment" do
1166+
query = Schema
1167+
|> join(:cross_lateral, [p], q in fragment("SELECT * FROM schema2 AS s2 WHERE s2.id = ? AND s2.field = ?", p.x, ^10))
1168+
|> select([p, q], {p.id, q.z})
1169+
|> where([p], p.id > 0 and p.id < ^100)
1170+
|> plan()
1171+
assert all(query) ==
1172+
~s{SELECT s0."id", f1."z" FROM "schema" AS s0 CROSS JOIN LATERAL } <>
1173+
~s{(SELECT * FROM schema2 AS s2 WHERE s2.id = s0."x" AND s2.field = $1) AS f1 } <>
1174+
~s{WHERE ((s0."id" > 0) AND (s0."id" < $2))}
1175+
end
1176+
11651177
test "cross join" do
11661178
query = from(p in Schema, cross_join: c in Schema2, select: {p.id, c.id}) |> plan()
11671179
assert all(query) ==

0 commit comments

Comments
 (0)