in exposed-r2dbc/src/main/kotlin/org/jetbrains/exposed/v1/r2dbc/statements/api/R2dbcDatabaseMetadataImpl.kt [207:263]
override suspend fun existingIndices(vararg tables: Table): Map<Table, List<Index>> {
for (table in tables) {
val transaction = TransactionManager.current()
val (catalog, tableSchema) = tableCatalogAndSchema(table)
existingIndicesCache.getOrPut(table) {
val pkQuery = metadataProvider.getPrimaryKeys(catalog, tableSchema, table.nameInDatabaseCaseUnquoted())
val pkNames = connection.executeSQL(pkQuery) { row, _ ->
row.getString("PK_NAME")
}?.filterNotNull().orEmpty()
val storedIndexTable = if (
(tableSchema == getCurrentSchema() && currentDialect is OracleDialect) ||
currentDialect is SQLServerDialect
) {
table.nameInDatabaseCase()
} else {
table.nameInDatabaseCaseUnquoted()
}
val indexQuery = metadataProvider.getIndexInfo(catalog, tableSchema, storedIndexTable)
val tmpIndices = hashMapOf<Triple<String, Boolean, Op.TRUE?>, MutableList<String>>()
connection.executeSQL(indexQuery) { row, _ ->
row.getString("INDEX_NAME")?.let { indexName ->
val columnNameMetadata = row.getString("COLUMN_NAME") ?: when (currentDialect) {
is MysqlDialect -> "\"\""
else -> null
}
columnNameMetadata?.let { columnName ->
val column = transaction.db.identifierManager
.quoteIdentifierWhenWrongCaseOrNecessary(columnName)
val isUnique = !row.getBoolean("NON_UNIQUE")
val isPartial = if (row.getString("FILTER_CONDITION").isNullOrEmpty()) null else Op.TRUE
tmpIndices.getOrPut(Triple(indexName, isUnique, isPartial)) { arrayListOf() }.add(column)
}
}
}
val tColumns = table.columns.associateBy { transaction.identity(it) }
tmpIndices.filterNot { it.key.first in pkNames }.mapNotNull { (index, columns) ->
val (functionBased, columnBased) = columns.distinct().partition { cn -> tColumns[cn] == null }
columnBased.map { cn -> tColumns[cn]!! }.takeIf { c -> c.size + functionBased.size == columns.size }?.let { c ->
Index(
c,
index.second,
index.first,
filterCondition = index.third,
functions = functionBased.map { stringLiteral(it) }.ifEmpty { null },
functionsTable = if (functionBased.isNotEmpty()) table else null
)
}
}
}
}
return HashMap(existingIndicesCache)
}