Skip to content

Commit

Permalink
more fixes related to schema in table ids
Browse files Browse the repository at this point in the history
  • Loading branch information
arcuri82 committed Dec 17, 2024
1 parent fa9fee1 commit 5c5a4e4
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 17 deletions.
66 changes: 54 additions & 12 deletions core/src/main/kotlin/org/evomaster/core/sql/SqlInsertBuilder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,11 @@ class SqlInsertBuilder(

for (fk in tableDto.foreignKeys) {

tableToColumns[fk.targetTable]
?: throw IllegalArgumentException("Foreign key for non-existent table ${fk.targetTable}")
val tableKey = getTableKey(tableToColumns.keys, fk.targetTable)

if(tableKey == null || tableToColumns[tableKey] == null) {
throw IllegalArgumentException("Foreign key for non-existent table ${fk.targetTable}")
}
val sourceColumns = mutableSetOf<Column>()

for (cname in fk.sourceColumns) {
Expand All @@ -196,7 +198,7 @@ class SqlInsertBuilder(
sourceColumns.add(c)
}

fks.add(ForeignKey(sourceColumns, fk.targetTable))
fks.add(ForeignKey(sourceColumns, tableKey))
}
return fks
}
Expand Down Expand Up @@ -616,19 +618,52 @@ class SqlInsertBuilder(
/**
* SQL is not case sensitivity.
* Therefore, table/column must ignore case sensitivity.
*
* No. This is not strictly true:
* https://docs.aws.amazon.com/dms/latest/sql-server-to-aurora-postgresql-migration-playbook/chap-sql-server-aurora-pg.sql.casesensitivity.html#:~:text=By%20default%2C%20SQL%20Server%20names,names%20in%20lowercase%20for%20PostgreSQL.
*
* quotes "" can be used to force case-sensitivity
*/
fun isTable(tableName: String) = tables.keys.any { it.equals(tableName, ignoreCase = true) }
fun isTable(tableName: String) = getTableKey(tables.keys, tableName) != null

fun getTable(tableName: String, useExtraConstraints: Boolean): Table {
private fun <T> getValueByTableNameKey(map: Map<String, T>, tableName: String) : T?{

val data = if (useExtraConstraints) extendedTables else tables
val key = getTableKey(map.keys, tableName)
return map[key]
}

private fun getTableKey(keys: Set<String>, tableName: String) : String?{
/*
* SQL is not case sensitivity, table/column must ignore case sensitivity.
* No, this is not really true...
* Usually, names are lowered-cased by the DB, unless quoted in "":
* https://docs.aws.amazon.com/dms/latest/sql-server-to-aurora-postgresql-migration-playbook/chap-sql-server-aurora-pg.sql.casesensitivity.html#:~:text=By%20default%2C%20SQL%20Server%20names,names%20in%20lowercase%20for%20PostgreSQL.
*
*/
val tableNameKey = data.keys.find { tableName.equals(it, ignoreCase = true) }
return data[tableNameKey] ?: throw IllegalArgumentException("No table called $tableName")
val tableNameKey = keys.find { tableName.equals(it, ignoreCase = true) }
if (!tableName.contains(".") && tableNameKey == null){
//input name might be without schema, so check for partial match
val candidates = keys.filter { it.endsWith(".${tableName}", true) }
if(candidates.size > 1){
throw IllegalArgumentException("Ambiguity." +
" More than one candidate of table called $tableName." +
" Values: ${candidates.joinToString(", ")}")
}
if(candidates.size == 1){
return candidates[0]
}
}
return tableNameKey
}

fun getTable(tableName: String, useExtraConstraints: Boolean): Table {

val data = if (useExtraConstraints) extendedTables else tables

val tableNameKey = getTableKey(data.keys, tableName)
?: throw IllegalArgumentException("No table called $tableName")

return data[tableNameKey] ?: throw IllegalArgumentException("No table called $tableName")
}

/**
Expand Down Expand Up @@ -1009,11 +1044,18 @@ class SqlInsertBuilder(

private fun formatNameInSql(name: String): String {

return name

/*
The handling of "" quotes is extremely tricky.
TODO if we really want to support it, would need to have a flag on each name (eg have
to pass them as pojo, not string)
*/
//TODO: why this??? needs explanation
return when {
databaseType == DatabaseType.MYSQL || name == SQLKey.ALL.key -> name
else -> "\"$name\""
}
// return when {
// databaseType == DatabaseType.MYSQL || name == SQLKey.ALL.key -> name
// else -> "\"$name\""
// }
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1067,9 +1067,9 @@ class SqlInsertBuilderTest {

// ABCD or ACBD
assertEquals(4, enabled.size)
assertEquals("ROOTA", enabled[0].table.name)
assertEquals("LEAFD", enabled[3].table.name)
assertTrue(enabled.subList(1,3).map { it.table.name }.containsAll(listOf("NODEB", "NODEC")))
assertEquals("PUBLIC.ROOTA", enabled[0].table.name)
assertEquals("PUBLIC.LEAFD", enabled[3].table.name)
assertTrue(enabled.subList(1,3).map { it.table.name }.containsAll(listOf("PUBLIC.NODEB", "PUBLIC.NODEC")))
}

////// Tests Numeric parsing for Min/Max Bounds
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ class CatwatchSqlExtractTest : ExtractTestBaseH2(){
SqlActionUtils.randomizeDbActionGenes(insertions.toMutableList(), Randomness())

assertEquals(2, insertions.size)
assert(insertions[0].table.name.equals("PROJECT", ignoreCase = true))
assert(insertions[1].table.name.equals("lANGUAGE_LIST", ignoreCase = true))
assert(insertions[0].table.name.equals("PUBLIC.PROJECT", ignoreCase = true))
assert(insertions[1].table.name.equals("PUBLIC.lANGUAGE_LIST", ignoreCase = true))

val projectId = (insertions[0].seeTopGenes().filterIsInstance<SqlPrimaryKeyGene>()).first().uniqueId

Expand Down

0 comments on commit 5c5a4e4

Please sign in to comment.