JetBrains / Exposed

Kotlin SQL Framework
http://jetbrains.github.io/Exposed/
Apache License 2.0
8.05k stars 674 forks source link

fix: EXPOSED-415 SchemaUtils incorrectly generates ALTER statements f… #2136

Open obabichevjb opened 1 week ago

obabichevjb commented 1 week ago

Here is the fix of generation update with SchemaUtils.statementsRequiredToActualizeScheme() for nullable columns.

The problem is that for MariaDB and MySql it's not possible to determine whether the default value of a nullable column was not defined or it was explicitly set to null. Also an issue that (if I'm right for MySql only) for some cases string default value "NULL" was recognized as null.

The main change that I made with this PR is treating any null-like value (non set null, or explicitly set null) as the same for DDL generation purposes. It means that if a user created a table with a nullable column and without a default value and then added explicit .default(null) Exposed will not offer to alter that column. Such a variant is not 100% accurate in terms of synchronization between actual DB and Exposed definitions but looks like follows to the same result.

It was suggested to check if we can take the information about the default values directly from DB (instead of JDBC), but looks like it's the same for MariaDB anyway.

obabichevjb commented 1 week ago

Probably, we could apply such a logic to MariaDB only, and still generate DDL with updating nullable columns for other DBs. But in this case I'd say the method JdbcDatabaseMetadataImpl::sanitizedDefault should return different values (if possible) for the cases when the value was not set at all, when it was set to null explicitly, and any other values.

It's definitely possible but would require to introduce at least one more constant (enum/object/..) like DB_EXPLICIT_NULL. But actually not sure that it's practically needed...