Skip to content

Commit

Permalink
fix: EXPOSED-128 Update with Join and Where clause fails in Oracle
Browse files Browse the repository at this point in the history
The following test fails when run on Oracle:

UpdateTests/testUpdateWithJoinAndWhere()

Fails with an assertion error because the arguments passed to PreparedStatement
are in the wrong positions.

This happens because Oracle is the only supported database to use a subquery directly
in the UPDATE syntax to represent the join part and the WHERE clause together.
And, unlike other DB, this WHERE clause also comes before the UPDATE set clause.

Fixed by reversing the order of arguments in the UpdateStatement query builder,
specifically when an update-with-join operation is executed.
  • Loading branch information
bog-walk committed Aug 7, 2023
1 parent f732f99 commit 6c087a4
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.statements.api.PreparedStatementApi
import org.jetbrains.exposed.sql.vendors.H2Dialect.H2CompatibilityMode
import org.jetbrains.exposed.sql.vendors.H2FunctionProvider
import org.jetbrains.exposed.sql.vendors.OracleDialect
import org.jetbrains.exposed.sql.vendors.currentDialect
import org.jetbrains.exposed.sql.vendors.h2Mode

open class UpdateStatement(val targetsSet: ColumnSet, val limit: Int?, val where: Op<Boolean>? = null) :
Expand Down Expand Up @@ -35,10 +37,17 @@ open class UpdateStatement(val targetsSet: ColumnSet, val limit: Int?, val where
}

override fun arguments(): Iterable<Iterable<Pair<IColumnType, Any?>>> = QueryBuilder(true).run {
values.forEach {
registerArgument(it.key, it.value)
if (targetsSet is Join && currentDialect is OracleDialect) {
where?.toQueryBuilder(this)
values.forEach {
registerArgument(it.key, it.value)
}
} else {
values.forEach {
registerArgument(it.key, it.value)
}
where?.toQueryBuilder(this)
}
where?.toQueryBuilder(this)
if (args.isNotEmpty()) listOf(args) else emptyList()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ internal object OracleFunctionProvider : FunctionProvider() {
}

limit?.let {
"WHERE ROWNUM <= $it"
+" WHERE ROWNUM <= $it"
}

toString()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class UpdateTests : DatabaseTestsBase() {
}
}
}

@Test
fun testUpdateWithJoin02() {
withCitiesAndUsers(exclude = TestDB.allH2TestDB + TestDB.SQLITE) { cities, users, userData ->
Expand Down

0 comments on commit 6c087a4

Please sign in to comment.