Skip to content

Commit 447c1a2

Browse files
Allow fragment sources to have user defined columns (#743)
1 parent f761250 commit 447c1a2

8 files changed

Lines changed: 49 additions & 4 deletions

File tree

lib/ecto/adapters/myxql/connection.ex

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ if Code.ensure_loaded?(MyXQL) do
666666
defp operator_to_boolean(:or), do: " OR "
667667

668668
defp parens_for_select([first_expr | _] = expr) do
669-
if is_binary(first_expr) and String.match?(first_expr, ~r/^\s*select/i) do
669+
if is_binary(first_expr) and String.match?(first_expr, ~r/^\s*select\s/i) do
670670
[?(, expr, ?)]
671671
else
672672
expr
@@ -1567,6 +1567,16 @@ if Code.ensure_loaded?(MyXQL) do
15671567
[name, ?\s, ?(, quote_names(fields), ?)]
15681568
end
15691569

1570+
defp maybe_add_column_names({:fragment, meta, _}, name) do
1571+
fields = meta[:column_names]
1572+
1573+
if fields do
1574+
[name, ?\s, ?(, quote_names(fields), ?)]
1575+
else
1576+
name
1577+
end
1578+
end
1579+
15701580
defp maybe_add_column_names(_, name), do: name
15711581

15721582
defp quote_name(nil, name), do: quote_name(name)

lib/ecto/adapters/postgres/connection.ex

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1965,6 +1965,16 @@ if Code.ensure_loaded?(Postgrex) do
19651965
[name, ?\s, ?(, quote_names(fields), ?)]
19661966
end
19671967

1968+
defp maybe_add_column_names({:fragment, meta, _}, name) do
1969+
fields = meta[:column_names]
1970+
1971+
if fields do
1972+
[name, ?\s, ?(, quote_names(fields), ?)]
1973+
else
1974+
name
1975+
end
1976+
end
1977+
19681978
defp maybe_add_column_names(_, name), do: name
19691979

19701980
defp quote_qualified_name(name, sources, ix) do

lib/ecto/adapters/tds/connection.ex

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,6 +1720,16 @@ if Code.ensure_loaded?(Tds) do
17201720
[name, ?\s, ?(, quote_names(fields), ?)]
17211721
end
17221722

1723+
defp maybe_add_column_names({:fragment, meta, _}, name) do
1724+
fields = meta[:column_names]
1725+
1726+
if fields do
1727+
[name, ?\s, ?(, quote_names(fields), ?)]
1728+
else
1729+
name
1730+
end
1731+
end
1732+
17231733
defp maybe_add_column_names(_, name), do: name
17241734

17251735
defp quote_name(name) when is_atom(name) do

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ defmodule EctoSQL.MixProject do
8484
if path = System.get_env("ECTO_PATH") do
8585
{:ecto, path: path}
8686
else
87-
{:ecto, "~> 3.14.0"}
87+
{:ecto, git: "https://github.com/elixir-ecto/ecto.git"}
8888
end
8989
end
9090

mix.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
"benchee_html": {:hex, :benchee_html, "1.0.1", "1e247c0886c3fdb0d3f4b184b653a8d6fb96e4ad0d0389267fe4f36968772e24", [:mix], [{:benchee, ">= 0.99.0 and < 2.0.0", [hex: :benchee, repo: "hexpm", optional: false]}, {:benchee_json, "~> 1.0", [hex: :benchee_json, repo: "hexpm", optional: false]}], "hexpm", "b00a181af7152431901e08f3fc9f7197ed43ff50421a8347b0c80bf45d5b3fef"},
44
"benchee_json": {:hex, :benchee_json, "1.0.0", "cc661f4454d5995c08fe10dd1f2f72f229c8f0fb1c96f6b327a8c8fc96a91fe5", [:mix], [{:benchee, ">= 0.99.0 and < 2.0.0", [hex: :benchee, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "da05d813f9123505f870344d68fb7c86a4f0f9074df7d7b7e2bb011a63ec231c"},
55
"db_connection": {:hex, :db_connection, "2.10.1", "d5465f6bcc125c1b8981c1dbf23c193ca16f446ec0b25832dc174f74f18be510", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "18ed94c6e627b4bf452dbd4df61b69a35a1e768525140bc1917b7a685026a6a3"},
6-
"decimal": {:hex, :decimal, "3.1.0", "9ede268cff827e6f0c4fb1b34747c82630dce5d7b877dfb22ec8f0cb25855fce", [:mix], [], "hexpm", "e8b3efb3bb3a13cb5e4268ffe128569067b1972e9dee013537c71a5b073168f9"},
6+
"decimal": {:hex, :decimal, "3.1.1", "430d87b04011ce6cbd4fd205be758311a81f87d552d40904abd00f015935b1d0", [:mix], [], "hexpm", "c5f25f2ced74a0587d03e6023f595db8e924c9d3922c8c8ffd9edfc4498cf1f6"},
77
"deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"},
88
"earmark_parser": {:hex, :earmark_parser, "1.4.44", "f20830dd6b5c77afe2b063777ddbbff09f9759396500cdbe7523efd58d7a339c", [:mix], [], "hexpm", "4778ac752b4701a5599215f7030989c989ffdc4f6df457c5f36938cc2d2a2750"},
9-
"ecto": {:hex, :ecto, "3.14.0", "2fa64521eebfcb2670d907a86e4ad947290e9933706bb315e6fb5c21b172cb26", [:mix], [{:decimal, "~> 3.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", "130d69ffb4285f9ce4792b65dfbb994fd13ea4cbc3cbea2524b199aa3de84af3"},
9+
"ecto": {:git, "https://github.com/elixir-ecto/ecto.git", "d4add51346eb282f69eefd387503be49064a6304", []},
1010
"ex_doc": {:hex, :ex_doc, "0.40.2", "f50edec428c4b0a457a167de42414c461122a3585a99515a69d09fff19e5597e", [:mix], [{:earmark_parser, "~> 1.4.44", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "4fa426e2beb47854a162e2c488727fdec51cd4692e319b23810c2804cb1a40fe"},
1111
"jason": {:hex, :jason, "1.4.5", "2e3a008590b0b8d7388c20293e9dcc9cf3e5d642fd2a114e4cbbb52e595d940a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "b0c823996102bcd0239b3c2444eb00409b72f6a140c1950bc8b457d836b30684"},
1212
"makeup": {:hex, :makeup, "1.2.1", "e90ac1c65589ef354378def3ba19d401e739ee7ee06fb47f94c687016e3713d1", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d36484867b0bae0fea568d10131197a4c2e47056a6fbe84922bf6ba71c8d17ce"},

test/ecto/adapters/myxql_test.exs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ defmodule Ecto.Adapters.MyXQLTest do
134134
end
135135
end
136136

137+
test "fragment columns" do
138+
query = from(f in fragment("select_rows(arg)", columns: [:x]), select: f.x) |> plan()
139+
assert all(query) == ~s{SELECT f0.`x` FROM select_rows(arg) AS f0 (`x`)}
140+
end
141+
137142
test "CTE" do
138143
initial_query =
139144
"categories"

test/ecto/adapters/postgres_test.exs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,11 @@ defmodule Ecto.Adapters.PostgresTest do
156156
all(from(f in fragment("select ? as x", ^"abc"), select: f) |> plan())
157157
end
158158
end
159+
160+
test "fragment columns" do
161+
query = from(f in fragment("select_rows(arg)", columns: [:x]), select: f.x) |> plan()
162+
assert all(query) == ~s{SELECT f0."x" FROM select_rows(arg) AS f0 ("x")}
163+
end
159164

160165
test "CTE" do
161166
initial_query =

test/ecto/adapters/tds_test.exs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ defmodule Ecto.Adapters.TdsTest do
167167
end
168168
end
169169

170+
test "fragment columns" do
171+
query = from(f in fragment("select_rows(arg)", columns: [:x]), select: f.x) |> plan()
172+
assert all(query) == ~s{SELECT f0.[x] FROM select_rows(arg) AS f0 ([x])}
173+
end
174+
170175
test "join with subquery" do
171176
posts = subquery("posts" |> where(title: ^"hello") |> select([r], %{x: r.x, y: r.y}))
172177

0 commit comments

Comments
 (0)