Skip to content

Commit 38c3aa8

Browse files
authored
test: EXPOSED-191 Flaky Oracle test on TC build (JetBrains#2098)
* test: EXPOSED-191 Flaky Oracle test on TC build
1 parent 1703407 commit 38c3aa8

File tree

3 files changed

+49
-8
lines changed
  • exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/statements
  • exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao
  • exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/entities

3 files changed

+49
-8
lines changed

exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/statements/InsertStatement.kt

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package org.jetbrains.exposed.sql.statements
22

33
import org.jetbrains.exposed.sql.*
44
import org.jetbrains.exposed.sql.statements.api.PreparedStatementApi
5+
import org.jetbrains.exposed.sql.transactions.TransactionManager
56
import org.jetbrains.exposed.sql.vendors.*
67
import org.jetbrains.exposed.sql.vendors.inProperCase
78
import java.sql.ResultSet
@@ -51,7 +52,7 @@ open class InsertStatement<Key : Any>(
5152
*/
5253
fun <T> getOrNull(column: Column<T>): T? = resultedValues?.firstOrNull()?.getOrNull(column)
5354

54-
@Suppress("NestedBlockDepth", "ComplexMethod")
55+
@Suppress("NestedBlockDepth", "ComplexMethod", "TooGenericExceptionCaught")
5556
private fun processResults(rs: ResultSet?, inserted: Int): List<ResultRow> {
5657
val autoGeneratedKeys = arrayListOf<MutableMap<Column<*>, Any?>>()
5758

@@ -68,9 +69,33 @@ open class InsertStatement<Key : Any>(
6869
val firstAutoIncColumn = autoIncColumns.firstOrNull { it.autoIncColumnType != null } ?: autoIncColumns.firstOrNull()
6970
if (firstAutoIncColumn != null || returnedColumns.isNotEmpty()) {
7071
while (rs?.next() == true) {
71-
val returnedValues = returnedColumns.associateTo(mutableMapOf()) { it.first to rs.getObject(it.second) }
72-
if (returnedValues.isEmpty() && firstAutoIncColumn != null) returnedValues[firstAutoIncColumn] = rs.getObject(1)
73-
autoGeneratedKeys.add(returnedValues)
72+
try {
73+
val returnedValues = returnedColumns.associateTo(mutableMapOf()) { it.first to rs.getObject(it.second) }
74+
if (returnedValues.isEmpty() && firstAutoIncColumn != null) {
75+
returnedValues[firstAutoIncColumn] = rs.getObject(1)
76+
}
77+
autoGeneratedKeys.add(returnedValues)
78+
} catch (cause: ArrayIndexOutOfBoundsException) {
79+
// EXPOSED-191 Flaky Oracle test on TC build
80+
// this try/catch should help to get information about the flaky test.
81+
// try/catch can be safely removed after the fixing the issue.
82+
// TooGenericExceptionCaught suppress also can be removed
83+
84+
val preparedSql = this.prepareSQL(TransactionManager.current(), prepared = true)
85+
86+
val returnedColumnsString = returnedColumns
87+
.mapIndexed { index, pair -> "column: ${pair.first.name}, index: ${pair.second} (columns-list-index: $index)" }
88+
.joinToString(prefix = "[", postfix = "]", separator = ", ")
89+
90+
exposedLogger.error(
91+
"ArrayIndexOutOfBoundsException on processResults. " +
92+
"Table: ${table.tableName}, firstAutoIncColumn: ${firstAutoIncColumn?.name}, " +
93+
"inserted: $inserted, returnedColumnsString: $returnedColumnsString. " +
94+
"Failed SQL: $preparedSql",
95+
cause
96+
)
97+
throw cause
98+
}
7499
}
75100

76101
if (inserted > 1 && firstAutoIncColumn != null && autoGeneratedKeys.isNotEmpty() && !currentDialect.supportsMultipleGeneratedKeys) {

exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/EntityCache.kt

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ class EntityCache(private val transaction: Transaction) {
226226
}
227227
}
228228

229+
@Suppress("TooGenericExceptionCaught")
229230
internal fun flushInserts(table: IdTable<*>) {
230231
var toFlush: List<Entity<*>> = inserts.remove(table)?.toList().orEmpty()
231232
while (toFlush.isNotEmpty()) {
@@ -236,12 +237,26 @@ class EntityCache(private val transaction: Transaction) {
236237
}
237238
}
238239
toFlush = partition.first
239-
val ids = executeAsPartOfEntityLifecycle {
240-
table.batchInsert(toFlush) { entry ->
241-
for ((c, v) in entry.writeValues) {
242-
this[c] = v
240+
val ids = try {
241+
executeAsPartOfEntityLifecycle {
242+
table.batchInsert(toFlush) { entry ->
243+
for ((c, v) in entry.writeValues) {
244+
this[c] = v
245+
}
243246
}
244247
}
248+
} catch (cause: ArrayIndexOutOfBoundsException) {
249+
// EXPOSED-191 Flaky Oracle test on TC build
250+
// this try/catch should help to get information about the flaky test.
251+
// try/catch can be safely removed after the fixing the issue
252+
// TooGenericExceptionCaught suppress also can be removed
253+
val toFlushString = toFlush.joinToString("; ") {
254+
entry ->
255+
entry.writeValues.map { writeValue -> "${writeValue.key.name}=${writeValue.value}" }.joinToString { ", " }
256+
}
257+
258+
exposedLogger.error("ArrayIndexOutOfBoundsException on attempt to make flush inserts. Table: ${table.tableName}, entries: ($toFlushString)", cause)
259+
throw cause
245260
}
246261

247262
for ((entry, genValues) in toFlush.zip(ids)) {

exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/entities/EntityTests.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ class EntityTests : DatabaseTestsBase() {
557557
@Test
558558
fun callLimitOnRelationDoesntMutateTheCachedValue() {
559559
withTables(Posts, Boards, Categories) {
560+
addLogger(StdOutSqlLogger)
560561
val category1 = Category.new {
561562
title = "cat1"
562563
}

0 commit comments

Comments
 (0)