diff --git a/lib/ecto/adapters/sqlite3/connection.ex b/lib/ecto/adapters/sqlite3/connection.ex index b9d457b..969191b 100644 --- a/lib/ecto/adapters/sqlite3/connection.ex +++ b/lib/ecto/adapters/sqlite3/connection.ex @@ -748,6 +748,9 @@ defmodule Ecto.Adapters.SQLite3.Connection do defp conflict_target([]), do: "" + defp conflict_target({:unsafe_fragment, fragment}), + do: [fragment, ?\s] + defp conflict_target(targets) do [?(, intersperse_map(targets, ?,, "e_name/1), ?), ?\s] end diff --git a/test/ecto/adapters/sqlite3/connection/insert_test.exs b/test/ecto/adapters/sqlite3/connection/insert_test.exs index f95acca..166213f 100644 --- a/test/ecto/adapters/sqlite3/connection/insert_test.exs +++ b/test/ecto/adapters/sqlite3/connection/insert_test.exs @@ -60,6 +60,22 @@ defmodule Ecto.Adapters.SQLite3.Connection.InsertTest do assert query == ~s{INSERT INTO "schema" AS s0 ("x","y") VALUES (?,?) ON CONFLICT ("x","y") DO UPDATE SET "z" = 'foo' RETURNING "z"} + # For :unsafe_fragment + update = from("schema", update: [set: [z: "foo"]]) |> plan(:update_all) + + query = + insert( + nil, + "schema", + [:x, :y], + [[:x, :y]], + {update, [], {:unsafe_fragment, "foobar"}}, + [:z] + ) + + assert query == + ~s{INSERT INTO "schema" AS s0 ("x","y") VALUES (?,?) ON CONFLICT foobar DO UPDATE SET "z" = 'foo' RETURNING "z"} + assert_raise ArgumentError, "Upsert in SQLite3 requires :conflict_target", fn -> conflict_target = []