From ecf3c6a39d122704565ba1725a604940c280fd7b Mon Sep 17 00:00:00 2001 From: Jocelyne Date: Wed, 9 Aug 2023 23:44:15 +0200 Subject: [PATCH] fix: Change the way modifyColumn constructs its statements because the previous version was not including all necessary modifications Every alter statement will be a separate item in the list returned by the modifyColumn function. The statement to alter the default value of a column will combine both the DROP CONSTRAINT and ADD CONSTRAINT statements in one String item, separated by a semicolon. The statement to alter the type and nullability will be part of one String item since that syntax is allowed in SQL Server, but it seems like it's not allowed for adding and dropping constraints. --- .../exposed/sql/vendors/SQLServerDialect.kt | 58 +++++++++++++------ 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLServerDialect.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLServerDialect.kt index df28066b1c..3e3c113dcf 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLServerDialect.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLServerDialect.kt @@ -251,30 +251,52 @@ open class SQLServerDialect : VendorDialect(dialectName, SQLServerDataTypeProvid return columnDefault !in nonAcceptableDefaults } - override fun modifyColumn(column: Column<*>, columnDiff: ColumnDiff): List = - super.modifyColumn(column, columnDiff).map { statement -> - if (columnDiff.defaults) { - val transaction = TransactionManager.current() - val tableName = transaction.identity(column.table) - val colName = transaction.identity(column) - - val dropConstraint = "DROP CONSTRAINT IF EXISTS DF_${tableName}_$colName" - - column.dbDefaultValue?.let { - buildString { - append(statement.substringBefore("MODIFY COLUMN") + dropConstraint) + override fun modifyColumn(column: Column<*>, columnDiff: ColumnDiff): List { + val transaction = TransactionManager.current() + val tableName = transaction.identity(column.table) + val colName = transaction.identity(column) + + val alterTablePart = "ALTER TABLE $tableName " + + val statements = mutableListOf() + + statements.add( + buildString { + append(alterTablePart + "ALTER COLUMN $colName ${column.columnType.sqlType()}") + + if (columnDiff.nullability) { + val defaultValue = column.dbDefaultValue + val isPKColumn = column.table.primaryKey?.columns?.contains(column) == true + + if (column.columnType.nullable || + (defaultValue != null && column.defaultValueFun == null && !currentDialect.isAllowedAsColumnDefault(defaultValue))) { + append(" NULL") + } else if (!isPKColumn) { + append(" NOT NULL") + } + } + }) + + if (columnDiff.defaults) { + val dropConstraint = "DROP CONSTRAINT IF EXISTS DF_${tableName}_$colName" + + statements.add( + buildString { + column.dbDefaultValue?.let { + append(alterTablePart + dropConstraint) append("; ") append( - statement.substringBefore("MODIFY COLUMN") + + alterTablePart + "ADD CONSTRAINT DF_${tableName}_$colName DEFAULT ${SQLServerDataTypeProvider.processForDefaultValue(it)} for $colName" ) - } - } ?: (statement.substringBefore("MODIFY COLUMN") + dropConstraint) - } else { - statement.replace("MODIFY COLUMN", "ALTER COLUMN") - } + } ?: append(alterTablePart + dropConstraint) + } + ) } + return statements + } + override fun createDatabase(name: String): String = "CREATE DATABASE ${name.inProperCase()}" override fun dropDatabase(name: String) = "DROP DATABASE ${name.inProperCase()}"