-
-
Couldn't load subscription status.
- Fork 155
Description
Hello @vincentlauvlwj
I remember we implemented this feature in this PR.
In the feature of this commit, it was possible to do something like:
database.bulkInsert(Employees) {
item {
set(it.id, 1)
set(it.name, "vince")
set(it.job, "engineer")
set(it.salary, 1000)
set(it.hireDate, LocalDate.now())
set(it.departmentId, 1)
}
item {
set(it.id, 5)
set(it.name, "vince")
set(it.job, "engineer")
set(it.salary, 1000)
set(it.hireDate, LocalDate.now())
set(it.departmentId, 1)
}
onDuplicateKey(Employees.id) {
// I am leaving this intentionally empty, so Postgresql will ignore this error and proceed inserting the others
// INSERT INTO ... ON CONFLICT (employee_id) DO NOTHING
}
}This behavior was tested in ktorm-support-postgresql/src/test/kotlin/org/ktorm/support/postgresql/PostgreSqlTest.kt function testBulkInsertWithUpdate. And implemented here.
This is the visitor function as you have it now:
protected open fun visitInsertOrUpdate(expr: InsertOrUpdateExpression): InsertOrUpdateExpression {
writeKeyword("insert into ")
visitTable(expr.table)
writeInsertColumnNames(expr.assignments.map { it.column })
writeKeyword("values ")
writeInsertValues(expr.assignments)
if (expr.updateAssignments.isNotEmpty()) {
writeKeyword("on conflict ")
writeInsertColumnNames(expr.conflictColumns)
writeKeyword("do update set ")
visitColumnAssignments(expr.updateAssignments)
}
return expr
}This is how it should be in order to support the DO NOTHING feature that Postgresql provides, as we did in that PR:
protected open fun visitInsertOrUpdate(expr: InsertOrUpdateExpression): InsertOrUpdateExpression {
writeKeyword("insert into ")
visitTable(expr.table)
writeInsertColumnNames(expr.assignments.map { it.column })
writeKeyword("values ")
writeInsertValues(expr.assignments)
if (expr.conflictColumns.isNotEmpty()) {
writeKeyword("on conflict ")
writeInsertColumnNames(expr.conflictColumns)
if (expr.updateAssignments.isNotEmpty()) {
writeKeyword("do update set ")
visitColumnAssignments(expr.updateAssignments)
} else {
writeKeyword("do nothing ")
}
}
return expr
}Also, not forgetting now about the returning feature as well, so the final function for 3.4.0 would actually be:
protected open fun visitInsertOrUpdate(expr: InsertOrUpdateExpression): InsertOrUpdateExpression {
writeKeyword("insert into ")
visitTable(expr.table)
writeInsertColumnNames(expr.assignments.map { it.column })
writeKeyword("values ")
writeInsertValues(expr.assignments)
if (expr.conflictColumns.isNotEmpty()) {
writeKeyword("on conflict ")
writeInsertColumnNames(expr.conflictColumns)
if (expr.updateAssignments.isNotEmpty()) {
writeKeyword("do update set ")
visitColumnAssignments(expr.updateAssignments)
} else {
writeKeyword("do nothing ")
}
}
if (expr.returningColumns.isNotEmpty()) {
writeKeyword(" returning ")
expr.returningColumns.forEachIndexed { i, column ->
if (i > 0) write(", ")
checkColumnName(column.name)
write(column.name.quoted)
}
}
return expr
}Please can you fix this here and on the other Postgresql dialect functions where the DO NOTHING feature got removed?
I think it is only the visitBulkInsert function that needs this fix as well. Also the test that tested this feature (linked above) should be recovered as well.
PS. It doesn't seem like it, but this is an important feature which I see no reason to forbid Ktorm users from using it. As it is now, the user is always forced to unnecessarily update one column in order to get conflict errors ignored. This is not ideal in terms of performance.