From 55eeea7a1e2b0c15a0b19a0a474c77d07d17fdd9 Mon Sep 17 00:00:00 2001
From: NPCRUS <npcrus@gmail.com>
Date: Mon, 10 Feb 2025 15:09:41 +0100
Subject: [PATCH 1/2] adjusted InsertSelect to support onConflict

---
 scalasql/query/src/InsertSelect.scala         |  4 +-
 scalasql/src/dialects/OnConflictOps.scala     |  4 +-
 scalasql/test/src/query/OnConflictTests.scala | 54 ++++++++++++++++++-
 3 files changed, 57 insertions(+), 5 deletions(-)

diff --git a/scalasql/query/src/InsertSelect.scala b/scalasql/query/src/InsertSelect.scala
index 65016846..7c6bb1c1 100644
--- a/scalasql/query/src/InsertSelect.scala
+++ b/scalasql/query/src/InsertSelect.scala
@@ -7,7 +7,7 @@ import scalasql.core.SqlStr.{Renderable, SqlStringSyntax}
  * A SQL `INSERT SELECT` query
  */
 trait InsertSelect[V[_[_]], C, R, R2]
-    extends Returning.InsertBase[V[Expr]]
+    extends Returning.InsertBase[V[Column]]
     with Query.ExecuteUpdate[Int]
 
 object InsertSelect {
@@ -15,7 +15,7 @@ object InsertSelect {
       implicit dialect: DialectTypeMappers
   ) extends InsertSelect[V, C, R, R2] {
     import dialect.{dialectSelf => _, _}
-    protected def expr = WithSqlExpr.get(insert).asInstanceOf[V[Expr]]
+    protected def expr = WithSqlExpr.get(insert)
 
     def table = insert.table
 
diff --git a/scalasql/src/dialects/OnConflictOps.scala b/scalasql/src/dialects/OnConflictOps.scala
index 6948b5c4..9a5f1836 100644
--- a/scalasql/src/dialects/OnConflictOps.scala
+++ b/scalasql/src/dialects/OnConflictOps.scala
@@ -16,8 +16,8 @@ trait OnConflictOps {
 
   implicit def OnConflictableInsertSelect[V[_[_]], C, R, R2](
       query: InsertSelect[V, C, R, R2]
-  ): OnConflict[V[Expr], Int] = {
-    new OnConflict[V[Expr], Int](query, WithSqlExpr.get(query), query.table)
+  ): OnConflict[V[Column], Int] = {
+    new OnConflict[V[Column], Int](query, WithSqlExpr.get(query), query.table)
   }
 
 }
diff --git a/scalasql/test/src/query/OnConflictTests.scala b/scalasql/test/src/query/OnConflictTests.scala
index 32afe170..6296133a 100644
--- a/scalasql/test/src/query/OnConflictTests.scala
+++ b/scalasql/test/src/query/OnConflictTests.scala
@@ -54,6 +54,31 @@ trait OnConflictTests extends ScalaSqlSuite {
         docs = "with `insert.values`"
       )
 
+      checker(
+        query = Text {
+          Buyer.insert
+            .select(
+              identity,
+              Buyer.select
+                .filter(_.id === 1)
+                .map(b => b.copy(name = b.name + "."))
+            )
+            .onConflictIgnore(_.id)
+        },
+        sql = """INSERT INTO
+            buyer (id, name, date_of_birth)
+          SELECT
+            buyer0.id AS id,
+            (buyer0.name || ?) AS name,
+            buyer0.date_of_birth AS date_of_birth
+          FROM
+            buyer buyer0
+          WHERE
+            (buyer0.id = ?) ON CONFLICT (id) DO NOTHING""",
+        value = 0,
+        docs = "with `insert.select`"
+      )
+
       test("returningEmpty") - {
         checker(
           query = Text {
@@ -179,10 +204,37 @@ trait OnConflictTests extends ScalaSqlSuite {
         docs = "with `insert.values`"
       )
 
+      checker(
+        query = Text {
+          Buyer.insert
+            .select(
+              identity,
+              Buyer.select
+                .filter(_.id === 1)
+                .map(b => b.copy(name = b.name + "."))
+            )
+            .onConflictUpdate(_.id)(_.dateOfBirth := LocalDate.parse("2023-10-09"))
+        },
+        sql = """INSERT INTO
+            buyer (id, name, date_of_birth)
+          SELECT
+            buyer1.id AS id,
+            (buyer1.name || ?) AS name,
+            buyer1.date_of_birth AS date_of_birth
+          FROM
+            buyer buyer1 
+          WHERE
+            (buyer1.id = ?) ON CONFLICT (id) DO 
+          UPDATE
+          SET date_of_birth = ?""",
+        value = 1,
+        docs = "with `insert.select`"
+      )
+
       checker(
         query = Text { Buyer.select },
         value = Seq(
-          Buyer[Sc](1, "TEST BUYER CONFLICT", LocalDate.parse("2023-10-10")),
+          Buyer[Sc](1, "TEST BUYER CONFLICT", LocalDate.parse("2023-10-09")),
           Buyer[Sc](2, "叉烧包", LocalDate.parse("1923-11-12")),
           Buyer[Sc](3, "Li Haoyi", LocalDate.parse("1965-08-09"))
         ),

From 264a838adeb6f865d9fcb46c208e05ab74877b65 Mon Sep 17 00:00:00 2001
From: NPCRUS <npcrus@gmail.com>
Date: Mon, 10 Feb 2025 15:15:33 +0100
Subject: [PATCH 2/2] gen reference

---
 docs/reference.md | 82 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 81 insertions(+), 1 deletion(-)

diff --git a/docs/reference.md b/docs/reference.md
index 37f25361..f27b5826 100644
--- a/docs/reference.md
+++ b/docs/reference.md
@@ -4587,6 +4587,45 @@ Buyer.insert
 
 
 
+----
+
+with `insert.select`
+
+```scala
+Buyer.insert
+  .select(
+    identity,
+    Buyer.select
+      .filter(_.id === 1)
+      .map(b => b.copy(name = b.name + "."))
+  )
+  .onConflictIgnore(_.id)
+```
+
+
+*
+    ```sql
+    INSERT INTO
+                buyer (id, name, date_of_birth)
+              SELECT
+                buyer0.id AS id,
+                (buyer0.name || ?) AS name,
+                buyer0.date_of_birth AS date_of_birth
+              FROM
+                buyer buyer0
+              WHERE
+                (buyer0.id = ?) ON CONFLICT (id) DO NOTHING
+    ```
+
+
+
+*
+    ```scala
+    0
+    ```
+
+
+
 ### OnConflict.ignore.returningEmpty
 
 
@@ -4779,6 +4818,47 @@ Buyer.insert
 
 
 
+----
+
+with `insert.select`
+
+```scala
+Buyer.insert
+  .select(
+    identity,
+    Buyer.select
+      .filter(_.id === 1)
+      .map(b => b.copy(name = b.name + "."))
+  )
+  .onConflictUpdate(_.id)(_.dateOfBirth := LocalDate.parse("2023-10-09"))
+```
+
+
+*
+    ```sql
+    INSERT INTO
+                buyer (id, name, date_of_birth)
+              SELECT
+                buyer1.id AS id,
+                (buyer1.name || ?) AS name,
+                buyer1.date_of_birth AS date_of_birth
+              FROM
+                buyer buyer1 
+              WHERE
+                (buyer1.id = ?) ON CONFLICT (id) DO 
+              UPDATE
+              SET date_of_birth = ?
+    ```
+
+
+
+*
+    ```scala
+    1
+    ```
+
+
+
 ----
 
 
@@ -4793,7 +4873,7 @@ Buyer.select
 *
     ```scala
     Seq(
-      Buyer[Sc](1, "TEST BUYER CONFLICT", LocalDate.parse("2023-10-10")),
+      Buyer[Sc](1, "TEST BUYER CONFLICT", LocalDate.parse("2023-10-09")),
       Buyer[Sc](2, "叉烧包", LocalDate.parse("1923-11-12")),
       Buyer[Sc](3, "Li Haoyi", LocalDate.parse("1965-08-09"))
     )