diff --git a/docs/reference.md b/docs/reference.md
index 6fdb8ee4..37f25361 100644
--- a/docs/reference.md
+++ b/docs/reference.md
@@ -4556,6 +4556,37 @@ Buyer.insert
 
 
 
+----
+
+with `insert.values`
+
+```scala
+Buyer.insert
+  .values(
+    Buyer[Sc](
+      id = 1,
+      name = "test buyer",
+      dateOfBirth = LocalDate.parse("2023-09-09")
+    )
+  )
+  .onConflictIgnore(_.id)
+```
+
+
+*
+    ```sql
+    INSERT INTO buyer (id, name, date_of_birth) VALUES (?, ?, ?) ON CONFLICT (id) DO NOTHING
+    ```
+
+
+
+*
+    ```scala
+    0
+    ```
+
+
+
 ### OnConflict.ignore.returningEmpty
 
 
@@ -4588,6 +4619,40 @@ Buyer.insert
 
 
 
+----
+
+with `insert.values`
+
+```scala
+Buyer.insert
+  .values(
+    Buyer[Sc](
+      id = 1,
+      name = "test buyer",
+      dateOfBirth = LocalDate.parse("2023-09-09")
+    )
+  )
+  .onConflictIgnore(_.id)
+  .returning(_.name)
+```
+
+
+*
+    ```sql
+    INSERT INTO buyer (id, name, date_of_birth) VALUES (?, ?, ?)
+    ON CONFLICT (id) DO NOTHING
+    RETURNING buyer.name AS res
+    ```
+
+
+
+*
+    ```scala
+    Seq.empty[String]
+    ```
+
+
+
 ### OnConflict.ignore.returningOne
 
 
@@ -4597,7 +4662,7 @@ Buyer.insert
   .columns(
     _.name := "test buyer",
     _.dateOfBirth := LocalDate.parse("2023-09-09"),
-    _.id := 4 // This should cause a primary key conflict
+    _.id := 4
   )
   .onConflictIgnore(_.id)
   .returning(_.name)
@@ -4620,6 +4685,40 @@ Buyer.insert
 
 
 
+----
+
+with `insert.values`
+
+```scala
+Buyer.insert
+  .values(
+    Buyer[Sc](
+      id = 5,
+      name = "test buyer",
+      dateOfBirth = LocalDate.parse("2023-09-09")
+    )
+  )
+  .onConflictIgnore(_.id)
+  .returning(_.name)
+```
+
+
+*
+    ```sql
+    INSERT INTO buyer (id, name, date_of_birth) VALUES (?, ?, ?)
+    ON CONFLICT (id) DO NOTHING
+    RETURNING buyer.name AS res
+    ```
+
+
+
+*
+    ```scala
+    Seq("test buyer")
+    ```
+
+
+
 ### OnConflict.update
 
 ScalaSql's `.onConflictUpdate` translates into SQL's `ON CONFLICT DO UPDATE`
@@ -4649,6 +4748,37 @@ Buyer.insert
 
 
 
+----
+
+with `insert.values`
+
+```scala
+Buyer.insert
+  .values(
+    Buyer[Sc](
+      id = 1,
+      name = "test buyer",
+      dateOfBirth = LocalDate.parse("2023-09-09")
+    )
+  )
+  .onConflictUpdate(_.id)(_.dateOfBirth := LocalDate.parse("2023-10-10"))
+```
+
+
+*
+    ```sql
+    INSERT INTO buyer (id, name, date_of_birth) VALUES (?, ?, ?) ON CONFLICT (id) DO UPDATE SET date_of_birth = ?
+    ```
+
+
+
+*
+    ```scala
+    1
+    ```
+
+
+
 ----
 
 
@@ -4663,7 +4793,7 @@ Buyer.select
 *
     ```scala
     Seq(
-      Buyer[Sc](1, "TEST BUYER CONFLICT", LocalDate.parse("2001-02-03")),
+      Buyer[Sc](1, "TEST BUYER CONFLICT", LocalDate.parse("2023-10-10")),
       Buyer[Sc](2, "叉烧包", LocalDate.parse("1923-11-12")),
       Buyer[Sc](3, "Li Haoyi", LocalDate.parse("1965-08-09"))
     )
@@ -4700,6 +4830,37 @@ Buyer.insert
 
 
 
+----
+
+with `insert.values`
+
+```scala
+Buyer.insert
+  .values(
+    Buyer[Sc](
+      id = 3,
+      name = "test buyer",
+      dateOfBirth = LocalDate.parse("2023-09-09")
+    )
+  )
+  .onConflictUpdate(_.id)(v => v.name := v.name.toUpperCase)
+```
+
+
+*
+    ```sql
+    INSERT INTO buyer (id, name, date_of_birth) VALUES (?, ?, ?) ON CONFLICT (id) DO UPDATE SET name = UPPER(buyer.name)
+    ```
+
+
+
+*
+    ```scala
+    1
+    ```
+
+
+
 ----
 
 
@@ -4716,7 +4877,7 @@ Buyer.select
     Seq(
       Buyer[Sc](1, "JAMES BOND", LocalDate.parse("2001-02-03")),
       Buyer[Sc](2, "叉烧包", LocalDate.parse("1923-11-12")),
-      Buyer[Sc](3, "Li Haoyi", LocalDate.parse("1965-08-09"))
+      Buyer[Sc](3, "LI HAOYI", LocalDate.parse("1965-08-09"))
     )
     ```
 
@@ -4756,6 +4917,42 @@ Buyer.insert
 
 
 
+----
+
+with `insert.values`
+
+```scala
+Buyer.insert
+  .values(
+    Buyer[Sc](
+      id = 1,
+      name = "test buyer",
+      dateOfBirth = LocalDate.parse("2023-09-09")
+    )
+  )
+  .onConflictUpdate(_.id)(v => v.name := v.name.toLowerCase)
+  .returning(_.name)
+  .single
+```
+
+
+*
+    ```sql
+    INSERT INTO buyer (id, name, date_of_birth) VALUES (?, ?, ?)
+    ON CONFLICT (id) DO UPDATE
+    SET name = LOWER(buyer.name)
+    RETURNING buyer.name AS res
+    ```
+
+
+
+*
+    ```scala
+    "james bond"
+    ```
+
+
+
 ## Values
 Basic `VALUES` operations
 ### Values.basic
diff --git a/scalasql/query/src/InsertValues.scala b/scalasql/query/src/InsertValues.scala
index a2146527..686160fd 100644
--- a/scalasql/query/src/InsertValues.scala
+++ b/scalasql/query/src/InsertValues.scala
@@ -3,7 +3,9 @@ package scalasql.query
 import scalasql.core.{Context, DialectTypeMappers, Expr, Queryable, SqlStr, WithSqlExpr}
 import scalasql.core.SqlStr.SqlStringSyntax
 
-trait InsertValues[V[_[_]], R] extends Returning.InsertBase[V[Expr]] with Query.ExecuteUpdate[Int] {
+trait InsertValues[V[_[_]], R]
+    extends Returning.InsertBase[V[Column]]
+    with Query.ExecuteUpdate[Int] {
   def skipColumns(x: (V[Column] => Column[?])*): InsertValues[V, R]
 }
 object InsertValues {
@@ -16,7 +18,7 @@ object InsertValues {
   ) extends InsertValues[V, R] {
 
     def table = insert.table
-    protected def expr = WithSqlExpr.get(insert).asInstanceOf[V[Expr]]
+    protected def expr: V[Column] = WithSqlExpr.get(insert)
     override protected def queryConstruct(args: Queryable.ResultSetIterator): Int =
       args.get(dialect.IntType)
 
diff --git a/scalasql/src/dialects/OnConflictOps.scala b/scalasql/src/dialects/OnConflictOps.scala
index 877771a0..6948b5c4 100644
--- a/scalasql/src/dialects/OnConflictOps.scala
+++ b/scalasql/src/dialects/OnConflictOps.scala
@@ -4,11 +4,16 @@ import scalasql.core.{Expr, WithSqlExpr}
 import scalasql.query._
 
 trait OnConflictOps {
-  implicit def OnConflictableInsertValues[V[_[_]], R](
+  implicit def OnConflictableInsertColumns[V[_[_]], R](
       query: InsertColumns[V, R]
   ): OnConflict[V[Column], Int] =
     new OnConflict[V[Column], Int](query, WithSqlExpr.get(query), query.table)
 
+  implicit def OnConflictableInsertValues[V[_[_]], R](
+      query: InsertValues[V, R]
+  ): OnConflict[V[Column], Int] =
+    new OnConflict[V[Column], Int](query, WithSqlExpr.get(query), query.table)
+
   implicit def OnConflictableInsertSelect[V[_[_]], C, R, R2](
       query: InsertSelect[V, C, R, R2]
   ): OnConflict[V[Expr], Int] = {
diff --git a/scalasql/test/src/query/OnConflictTests.scala b/scalasql/test/src/query/OnConflictTests.scala
index aa0e1e2b..32afe170 100644
--- a/scalasql/test/src/query/OnConflictTests.scala
+++ b/scalasql/test/src/query/OnConflictTests.scala
@@ -36,6 +36,24 @@ trait OnConflictTests extends ScalaSqlSuite {
         """
       )
 
+      checker(
+        query = Text {
+          Buyer.insert
+            .values(
+              Buyer[Sc](
+                id = 1,
+                name = "test buyer",
+                dateOfBirth = LocalDate.parse("2023-09-09")
+              )
+            )
+            .onConflictIgnore(_.id)
+        },
+        sql =
+          "INSERT INTO buyer (id, name, date_of_birth) VALUES (?, ?, ?) ON CONFLICT (id) DO NOTHING",
+        value = 0,
+        docs = "with `insert.values`"
+      )
+
       test("returningEmpty") - {
         checker(
           query = Text {
@@ -55,6 +73,28 @@ trait OnConflictTests extends ScalaSqlSuite {
           """,
           value = Seq.empty[String]
         )
+
+        checker(
+          query = Text {
+            Buyer.insert
+              .values(
+                Buyer[Sc](
+                  id = 1,
+                  name = "test buyer",
+                  dateOfBirth = LocalDate.parse("2023-09-09")
+                )
+              )
+              .onConflictIgnore(_.id)
+              .returning(_.name)
+          },
+          sql = """
+            INSERT INTO buyer (id, name, date_of_birth) VALUES (?, ?, ?)
+            ON CONFLICT (id) DO NOTHING
+            RETURNING buyer.name AS res
+          """,
+          value = Seq.empty[String],
+          docs = "with `insert.values`"
+        )
       }
 
       test("returningOne") - {
@@ -64,7 +104,7 @@ trait OnConflictTests extends ScalaSqlSuite {
               .columns(
                 _.name := "test buyer",
                 _.dateOfBirth := LocalDate.parse("2023-09-09"),
-                _.id := 4 // This should cause a primary key conflict
+                _.id := 4
               )
               .onConflictIgnore(_.id)
               .returning(_.name)
@@ -76,6 +116,28 @@ trait OnConflictTests extends ScalaSqlSuite {
           """,
           value = Seq("test buyer")
         )
+
+        checker(
+          query = Text {
+            Buyer.insert
+              .values(
+                Buyer[Sc](
+                  id = 5,
+                  name = "test buyer",
+                  dateOfBirth = LocalDate.parse("2023-09-09")
+                )
+              )
+              .onConflictIgnore(_.id)
+              .returning(_.name)
+          },
+          sql = """
+            INSERT INTO buyer (id, name, date_of_birth) VALUES (?, ?, ?)
+            ON CONFLICT (id) DO NOTHING
+            RETURNING buyer.name AS res
+          """,
+          value = Seq("test buyer"),
+          docs = "with `insert.values`"
+        )
       }
 
     }
@@ -99,10 +161,28 @@ trait OnConflictTests extends ScalaSqlSuite {
         """
       )
 
+      checker(
+        query = Text {
+          Buyer.insert
+            .values(
+              Buyer[Sc](
+                id = 1,
+                name = "test buyer",
+                dateOfBirth = LocalDate.parse("2023-09-09")
+              )
+            )
+            .onConflictUpdate(_.id)(_.dateOfBirth := LocalDate.parse("2023-10-10"))
+        },
+        sql =
+          "INSERT INTO buyer (id, name, date_of_birth) VALUES (?, ?, ?) ON CONFLICT (id) DO UPDATE SET date_of_birth = ?",
+        value = 1,
+        docs = "with `insert.values`"
+      )
+
       checker(
         query = Text { Buyer.select },
         value = Seq(
-          Buyer[Sc](1, "TEST BUYER CONFLICT", LocalDate.parse("2001-02-03")),
+          Buyer[Sc](1, "TEST BUYER CONFLICT", LocalDate.parse("2023-10-10")),
           Buyer[Sc](2, "叉烧包", LocalDate.parse("1923-11-12")),
           Buyer[Sc](3, "Li Haoyi", LocalDate.parse("1965-08-09"))
         ),
@@ -126,12 +206,30 @@ trait OnConflictTests extends ScalaSqlSuite {
         value = 1
       )
 
+      checker(
+        query = Text {
+          Buyer.insert
+            .values(
+              Buyer[Sc](
+                id = 3,
+                name = "test buyer",
+                dateOfBirth = LocalDate.parse("2023-09-09")
+              )
+            )
+            .onConflictUpdate(_.id)(v => v.name := v.name.toUpperCase)
+        },
+        sql =
+          "INSERT INTO buyer (id, name, date_of_birth) VALUES (?, ?, ?) ON CONFLICT (id) DO UPDATE SET name = UPPER(buyer.name)",
+        value = 1,
+        docs = "with `insert.values`"
+      )
+
       checker(
         query = Text { Buyer.select },
         value = Seq(
           Buyer[Sc](1, "JAMES BOND", LocalDate.parse("2001-02-03")),
           Buyer[Sc](2, "叉烧包", LocalDate.parse("1923-11-12")),
-          Buyer[Sc](3, "Li Haoyi", LocalDate.parse("1965-08-09"))
+          Buyer[Sc](3, "LI HAOYI", LocalDate.parse("1965-08-09"))
         ),
         normalize = (x: Seq[Buyer[Sc]]) => x.sortBy(_.id)
       )
@@ -158,6 +256,30 @@ trait OnConflictTests extends ScalaSqlSuite {
         """,
         value = "JAMES BOND"
       )
+
+      checker(
+        query = Text {
+          Buyer.insert
+            .values(
+              Buyer[Sc](
+                id = 1,
+                name = "test buyer",
+                dateOfBirth = LocalDate.parse("2023-09-09")
+              )
+            )
+            .onConflictUpdate(_.id)(v => v.name := v.name.toLowerCase)
+            .returning(_.name)
+            .single
+        },
+        sql = """
+          INSERT INTO buyer (id, name, date_of_birth) VALUES (?, ?, ?)
+          ON CONFLICT (id) DO UPDATE
+          SET name = LOWER(buyer.name)
+          RETURNING buyer.name AS res
+        """,
+        value = "james bond",
+        docs = "with `insert.values`"
+      )
     }
   }
 }