-
Notifications
You must be signed in to change notification settings - Fork 798
fix(plugin): EXPOSED-1033 Child tables that reference parent with index generate duplicate ALTER statements #2919
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ import kotlin.test.assertEquals | |
|
|
||
| object Parent : Table("issue_2897_parent") { | ||
| val id = integer("id") | ||
| val label = varchar("label", 255).uniqueIndex() | ||
| override val primaryKey = PrimaryKey(id) | ||
| } | ||
|
|
||
|
|
@@ -59,6 +60,7 @@ class MigrationGeneratorCollisionTest { | |
| ) | ||
|
|
||
| val generated = generator.generate() | ||
| val generatedFilenames = generated.map { it.substringAfter("__").substringBeforeLast('.') } | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test only covered the number of generated files and their SQL caused no issues because it's ok to execute |
||
| val expectedTables = setOf( | ||
| Parent.tableName, | ||
| ChildOne.tableName, | ||
|
|
@@ -74,6 +76,39 @@ class MigrationGeneratorCollisionTest { | |
|
|
||
| assertEquals(expectedTables.size, generated.size, "All table migrations must be preserved: $generated") | ||
| assertEquals(expectedTables.size, generatedFiles.size) | ||
| assertEquals(expectedTables.size, generatedFilenames.distinct().size) | ||
| assertEquals(expectedTables, createdTables, "All table DDL must be preserved") | ||
| } | ||
|
|
||
| @Test | ||
| fun testDependentTablesDoNotDuplicateParentConstraints() { | ||
| val generator = MigrationGenerator( | ||
| config = MigrationConfig( | ||
| tablesPackage = this::class.java.packageName, | ||
| classpathUrls = listOf(this::class.java.protectionDomain.codeSource.location), | ||
| fileDirectory = migrationsDirectory, | ||
| fileVersionFormat = VersionFormat.TIMESTAMP_WITHOUT_SECONDS, | ||
| databaseUrl = "jdbc:h2:mem:${UUID.randomUUID()}", | ||
| databaseUser = "", | ||
| databasePassword = "", | ||
| ), | ||
| logger = object : MigrationLogger { | ||
| override fun lifecycle(message: String) = Unit | ||
| override fun debug(message: String) = Unit | ||
| override val isDebugEnabled: Boolean = false | ||
| }, | ||
| ) | ||
|
|
||
| generator.generate() | ||
|
|
||
| val expectedTablesWithIndex = setOf(Parent.tableName) | ||
| val generatedFiles = migrationsDirectory.listFiles().orEmpty() | ||
| val alterTableRegex = Regex("""ALTER TABLE\s+"?([\w.]+)"?\s+ADD CONSTRAINT""", RegexOption.IGNORE_CASE) | ||
| val alteredTables = generatedFiles | ||
| .flatMap { file -> alterTableRegex.findAll(file.readText()).map { it.groupValues[1] }.toList() } | ||
| .map { it.substringAfterLast('.').lowercase() } | ||
|
|
||
| assertEquals(expectedTablesWithIndex.size, alteredTables.size, "Only files that generates table with index should contain its ALTER") | ||
| assertEquals(expectedTablesWithIndex, alteredTables.toSet()) | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The most ideal scenario would be to apply the output
statementsbelow to aTestContainerto ensure the next method call is run against an accurate state database.This solution covers the case when containers are not being used, by storing statements as they come for a future check. It might not be the most performant if there are many tables to check. But it should avoid more edge cases compared to calling the method once for all tables and attempting to separate the output logically (not all scripts will start with
CREATEfor example).An alternative could be to attempt to create a variant of
sortTablesByReferences()that returns grouped tables (that reference each other) to be handled together, for a potentially smaller temp store.