diff --git a/lib/ecto/adapters/myxql/connection.ex b/lib/ecto/adapters/myxql/connection.ex index e424c39e..4a03e821 100644 --- a/lib/ecto/adapters/myxql/connection.ex +++ b/lib/ecto/adapters/myxql/connection.ex @@ -666,7 +666,7 @@ if Code.ensure_loaded?(MyXQL) do defp operator_to_boolean(:or), do: " OR " defp parens_for_select([first_expr | _] = expr) do - if is_binary(first_expr) and String.match?(first_expr, ~r/^\s*select/i) do + if is_binary(first_expr) and String.match?(first_expr, ~r/^\s*select\s/i) do [?(, expr, ?)] else expr @@ -1567,6 +1567,16 @@ if Code.ensure_loaded?(MyXQL) do [name, ?\s, ?(, quote_names(fields), ?)] end + defp maybe_add_column_names({:fragment, meta, _}, name) do + fields = meta[:column_names] + + if fields do + [name, ?\s, ?(, quote_names(fields), ?)] + else + name + end + end + defp maybe_add_column_names(_, name), do: name defp quote_name(nil, name), do: quote_name(name) diff --git a/lib/ecto/adapters/postgres/connection.ex b/lib/ecto/adapters/postgres/connection.ex index b1b51ea3..3248f144 100644 --- a/lib/ecto/adapters/postgres/connection.ex +++ b/lib/ecto/adapters/postgres/connection.ex @@ -1965,6 +1965,16 @@ if Code.ensure_loaded?(Postgrex) do [name, ?\s, ?(, quote_names(fields), ?)] end + defp maybe_add_column_names({:fragment, meta, _}, name) do + fields = meta[:column_names] + + if fields do + [name, ?\s, ?(, quote_names(fields), ?)] + else + name + end + end + defp maybe_add_column_names(_, name), do: name defp quote_qualified_name(name, sources, ix) do diff --git a/lib/ecto/adapters/tds/connection.ex b/lib/ecto/adapters/tds/connection.ex index 27405d4b..9198df80 100644 --- a/lib/ecto/adapters/tds/connection.ex +++ b/lib/ecto/adapters/tds/connection.ex @@ -1720,6 +1720,16 @@ if Code.ensure_loaded?(Tds) do [name, ?\s, ?(, quote_names(fields), ?)] end + defp maybe_add_column_names({:fragment, meta, _}, name) do + fields = meta[:column_names] + + if fields do + [name, ?\s, ?(, quote_names(fields), ?)] + else + name + end + end + defp maybe_add_column_names(_, name), do: name defp quote_name(name) when is_atom(name) do diff --git a/mix.exs b/mix.exs index 5d1af626..fcc8392f 100644 --- a/mix.exs +++ b/mix.exs @@ -84,7 +84,7 @@ defmodule EctoSQL.MixProject do if path = System.get_env("ECTO_PATH") do {:ecto, path: path} else - {:ecto, "~> 3.14.0"} + {:ecto, git: "https://github.com/elixir-ecto/ecto.git"} end end diff --git a/mix.lock b/mix.lock index 1bd9862f..e07107e0 100644 --- a/mix.lock +++ b/mix.lock @@ -3,10 +3,10 @@ "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"}, "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"}, "db_connection": {:hex, :db_connection, "2.10.1", "d5465f6bcc125c1b8981c1dbf23c193ca16f446ec0b25832dc174f74f18be510", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "18ed94c6e627b4bf452dbd4df61b69a35a1e768525140bc1917b7a685026a6a3"}, - "decimal": {:hex, :decimal, "3.1.0", "9ede268cff827e6f0c4fb1b34747c82630dce5d7b877dfb22ec8f0cb25855fce", [:mix], [], "hexpm", "e8b3efb3bb3a13cb5e4268ffe128569067b1972e9dee013537c71a5b073168f9"}, + "decimal": {:hex, :decimal, "3.1.1", "430d87b04011ce6cbd4fd205be758311a81f87d552d40904abd00f015935b1d0", [:mix], [], "hexpm", "c5f25f2ced74a0587d03e6023f595db8e924c9d3922c8c8ffd9edfc4498cf1f6"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, "earmark_parser": {:hex, :earmark_parser, "1.4.44", "f20830dd6b5c77afe2b063777ddbbff09f9759396500cdbe7523efd58d7a339c", [:mix], [], "hexpm", "4778ac752b4701a5599215f7030989c989ffdc4f6df457c5f36938cc2d2a2750"}, - "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"}, + "ecto": {:git, "https://github.com/elixir-ecto/ecto.git", "d4add51346eb282f69eefd387503be49064a6304", []}, "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"}, "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"}, "makeup": {:hex, :makeup, "1.2.1", "e90ac1c65589ef354378def3ba19d401e739ee7ee06fb47f94c687016e3713d1", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d36484867b0bae0fea568d10131197a4c2e47056a6fbe84922bf6ba71c8d17ce"}, diff --git a/test/ecto/adapters/myxql_test.exs b/test/ecto/adapters/myxql_test.exs index 8e8485b8..76093a8b 100644 --- a/test/ecto/adapters/myxql_test.exs +++ b/test/ecto/adapters/myxql_test.exs @@ -134,6 +134,11 @@ defmodule Ecto.Adapters.MyXQLTest do end end + test "fragment columns" do + query = from(f in fragment("select_rows(arg)", columns: [:x]), select: f.x) |> plan() + assert all(query) == ~s{SELECT f0.`x` FROM select_rows(arg) AS f0 (`x`)} + end + test "CTE" do initial_query = "categories" diff --git a/test/ecto/adapters/postgres_test.exs b/test/ecto/adapters/postgres_test.exs index 5df1bb75..e907da5e 100644 --- a/test/ecto/adapters/postgres_test.exs +++ b/test/ecto/adapters/postgres_test.exs @@ -156,6 +156,11 @@ defmodule Ecto.Adapters.PostgresTest do all(from(f in fragment("select ? as x", ^"abc"), select: f) |> plan()) end end + + test "fragment columns" do + query = from(f in fragment("select_rows(arg)", columns: [:x]), select: f.x) |> plan() + assert all(query) == ~s{SELECT f0."x" FROM select_rows(arg) AS f0 ("x")} + end test "CTE" do initial_query = diff --git a/test/ecto/adapters/tds_test.exs b/test/ecto/adapters/tds_test.exs index 1f3f3b04..7a58e385 100644 --- a/test/ecto/adapters/tds_test.exs +++ b/test/ecto/adapters/tds_test.exs @@ -167,6 +167,11 @@ defmodule Ecto.Adapters.TdsTest do end end + test "fragment columns" do + query = from(f in fragment("select_rows(arg)", columns: [:x]), select: f.x) |> plan() + assert all(query) == ~s{SELECT f0.[x] FROM select_rows(arg) AS f0 ([x])} + end + test "join with subquery" do posts = subquery("posts" |> where(title: ^"hello") |> select([r], %{x: r.x, y: r.y}))