Skip to content

Commit 4f36771

Browse files
authored
Generate update set on conflict for upserts (#145)
When upserting to tables with only key columns, typo would generate `do nothing` as a conflict resolution. This has the disadvantage of making the query not execute the `returning` part, which meant that in cases where an upsert was executed targeting a single row, no rows would return and the generated code would cause an error. As a workaround, we generate `update set k = excluded.k` for an arbitrary key column k instead. This causes the `returning` part of the query to run but shouldn't change the value of the row as typo sees it. - Add failing test case for upserting on an existing row - Make the test case work by generating `update set` instead of `do nothing`
1 parent 2f44343 commit 4f36771

100 files changed

Lines changed: 1292 additions & 78 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.bleep/generated-sources/typo-tester-anorm@jvm213/scripts.GenHardcodedFiles/testdb/hardcoded/myschema/marital_status/MaritalStatusRepoImpl.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class MaritalStatusRepoImpl extends MaritalStatusRepo {
9898
${ParameterValue(unsaved.id, null, MaritalStatusId.toStatement)}::int8
9999
)
100100
on conflict ("id")
101-
do nothing
101+
do update set "id" = EXCLUDED."id"
102102
returning "id"
103103
"""
104104
.executeInsert(MaritalStatusRow.rowParser(1).single)

.bleep/generated-sources/typo-tester-anorm@jvm213/scripts.GenHardcodedFiles/testdb/hardcoded/package.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ package object hardcoded {
2929
case "VARCHAR" => "text[]"
3030
case other => s"${other}[]"
3131
}
32-
32+
3333
override def jdbcType: scala.Int = java.sql.Types.ARRAY
3434
}
3535
}

.bleep/generated-sources/typo-tester-anorm@jvm3/scripts.GenHardcodedFiles/testdb/hardcoded/myschema/marital_status/MaritalStatusRepoImpl.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class MaritalStatusRepoImpl extends MaritalStatusRepo {
9898
${ParameterValue(unsaved.id, null, MaritalStatusId.toStatement)}::int8
9999
)
100100
on conflict ("id")
101-
do nothing
101+
do update set "id" = EXCLUDED."id"
102102
returning "id"
103103
"""
104104
.executeInsert(MaritalStatusRow.rowParser(1).single)

.bleep/generated-sources/typo-tester-anorm@jvm3/scripts.GenHardcodedFiles/testdb/hardcoded/package.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ package object hardcoded {
2929
case "VARCHAR" => "text[]"
3030
case other => s"${other}[]"
3131
}
32-
32+
3333
override def jdbcType: scala.Int = java.sql.Types.ARRAY
3434
}
3535
}

.bleep/generated-sources/typo-tester-doobie@jvm213/scripts.GenHardcodedFiles/testdb/hardcoded/myschema/marital_status/MaritalStatusRepoImpl.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class MaritalStatusRepoImpl extends MaritalStatusRepo {
7676
${fromWrite(unsaved.id)(Write.fromPut(MaritalStatusId.put))}::int8
7777
)
7878
on conflict ("id")
79-
do nothing
79+
do update set "id" = EXCLUDED."id"
8080
returning "id"
8181
""".query(using MaritalStatusRow.read).unique
8282
}

.bleep/generated-sources/typo-tester-doobie@jvm3/scripts.GenHardcodedFiles/testdb/hardcoded/myschema/marital_status/MaritalStatusRepoImpl.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class MaritalStatusRepoImpl extends MaritalStatusRepo {
7676
${fromWrite(unsaved.id)(Write.fromPut(MaritalStatusId.put))}::int8
7777
)
7878
on conflict ("id")
79-
do nothing
79+
do update set "id" = EXCLUDED."id"
8080
returning "id"
8181
""".query(using MaritalStatusRow.read).unique
8282
}

.bleep/generated-sources/typo-tester-zio-jdbc@jvm213/scripts.GenHardcodedFiles/testdb/hardcoded/myschema/marital_status/MaritalStatusRepoImpl.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class MaritalStatusRepoImpl extends MaritalStatusRepo {
7878
${Segment.paramSegment(unsaved.id)(MaritalStatusId.setter)}::int8
7979
)
8080
on conflict ("id")
81-
do nothing
81+
do update set "id" = EXCLUDED."id"
8282
returning "id"""".insertReturning(using MaritalStatusRow.jdbcDecoder)
8383
}
8484
/* NOTE: this functionality is not safe if you use auto-commit mode! it runs 3 SQL statements */

.bleep/generated-sources/typo-tester-zio-jdbc@jvm3/scripts.GenHardcodedFiles/testdb/hardcoded/myschema/marital_status/MaritalStatusRepoImpl.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class MaritalStatusRepoImpl extends MaritalStatusRepo {
7878
${Segment.paramSegment(unsaved.id)(MaritalStatusId.setter)}::int8
7979
)
8080
on conflict ("id")
81-
do nothing
81+
do update set "id" = EXCLUDED."id"
8282
returning "id"""".insertReturning(using MaritalStatusRow.jdbcDecoder)
8383
}
8484
/* NOTE: this functionality is not safe if you use auto-commit mode! it runs 3 SQL statements */

init/data/test-tables.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,3 +273,9 @@ INSERT INTO issue142 (tabellkode)
273273
VALUES ('aa'),
274274
('bb')
275275
;
276+
277+
create table only_pk_columns(
278+
key_column_1 text not null,
279+
key_column_2 int not null,
280+
constraint only_pk_columns_pk primary key (key_column_1, key_column_2)
281+
);

typo-tester-anorm/generated-and-checked-in/adventureworks/humanresources/employeedepartmenthistory/EmployeedepartmenthistoryRepoImpl.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class EmployeedepartmenthistoryRepoImpl extends EmployeedepartmenthistoryRepo {
111111
val shiftid = compositeIds.map(_.shiftid)
112112
SQL"""select "businessentityid", "departmentid", "shiftid", "startdate"::text, "enddate"::text, "modifieddate"::text
113113
from "humanresources"."employeedepartmenthistory"
114-
where ("businessentityid", "startdate", "departmentid", "shiftid")
114+
where ("businessentityid", "startdate", "departmentid", "shiftid")
115115
in (select unnest(${businessentityid}), unnest(${startdate}), unnest(${departmentid}), unnest(${shiftid}))
116116
""".as(EmployeedepartmenthistoryRow.rowParser(1).*)
117117

0 commit comments

Comments
 (0)