override fun tableConstraints()

in exposed-jdbc/src/main/kotlin/org/jetbrains/exposed/v1/jdbc/statements/jdbc/JdbcDatabaseMetadataImpl.kt [433:483]


    override fun tableConstraints(tables: List<Table>): Map<String, List<ForeignKeyConstraint>> {
        val allTables = SchemaUtils.sortTablesByReferences(tables).associateBy { it.nameInDatabaseCaseUnquoted() }

        val dialect = currentDialect

        return if (dialect is MysqlDialect) {
            val inTableList = allTables.keys.joinToString("','", prefix = " ku.TABLE_NAME IN ('", postfix = "')")
            val tableSchema = "'${tables.mapNotNull { it.schemaName }.toSet().singleOrNull() ?: currentSchema}'"
            val constraintsToLoad = HashMap<String, MutableMap<String, ForeignKeyConstraint>>()
            metadata.connection.executeSQL(
                """
                    SELECT
                      rc.CONSTRAINT_NAME AS FK_NAME,
                      ku.TABLE_NAME AS FKTABLE_NAME,
                      ku.COLUMN_NAME AS FKCOLUMN_NAME,
                      ku.REFERENCED_TABLE_NAME AS PKTABLE_NAME,
                      ku.REFERENCED_COLUMN_NAME AS PKCOLUMN_NAME,
                      rc.UPDATE_RULE,
                      rc.DELETE_RULE
                    FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
                      INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ku
                        ON ku.TABLE_SCHEMA = rc.CONSTRAINT_SCHEMA AND rc.CONSTRAINT_NAME = ku.CONSTRAINT_NAME
                    WHERE ku.TABLE_SCHEMA = $tableSchema
                      AND ku.CONSTRAINT_SCHEMA = $tableSchema
                      AND rc.CONSTRAINT_SCHEMA = $tableSchema
                      AND $inTableList
                    ORDER BY ku.ORDINAL_POSITION
                """.trimIndent()
            ) { rs ->
                while (rs.next()) {
                    rs.extractForeignKeys(allTables, true)?.let { (fromTableName, fk) ->
                        constraintsToLoad.getOrPut(fromTableName) { mutableMapOf() }
                            .merge(fk.fkName, fk, ForeignKeyConstraint::plus)
                    }
                }
            }
            // This ensures MySQL/MariaDB have same behavior as before: a map entry for every table even if no FKs
            allTables.keys.forEach { constraintsToLoad.putIfAbsent(it, mutableMapOf()) }
            constraintsToLoad.mapValues { (_, v) -> v.values.toList() }
        } else {
            allTables.keys.associateWith { table ->
                val (catalog, tableSchema) = tableCatalogAndSchema(allTables[table]!!)
                metadata.getImportedKeys(catalog, identifierManager.inProperCase(tableSchema), table)
                    .iterate { extractForeignKeys(allTables, false) }
                    .filterNotNull()
                    .unzip().second
                    .groupBy { it.fkName }.values
                    .map { it.reduce(ForeignKeyConstraint::plus) }
            }
        }
    }