From d6d5f1145dbb2b1dccffa904fc08275168fe4d40 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 10 Oct 2023 14:55:25 -0400 Subject: [PATCH] improvement: support `{:unsafe_fragment, ".."}` as a conflict target this is supported by other sql data layers, for example. This is necessary for AshSqlite3's upsert behavior. Postgres adapter implementation: https://github.com/elixir-ecto/ecto_sql/blob/v3.10.2/lib/ecto/adapters/postgres/connection.ex#L212C4-L213C26 --- lib/ecto/adapters/sqlite3/connection.ex | 3 +++ .../adapters/sqlite3/connection/insert_test.exs | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) 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 = []