JetBrains / Exposed

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

fix: EXPOSED-407 compositeMoney() nullability definition issues #2137

Closed bog-walk closed 14 hours ago

bog-walk commented 1 week ago

Defining a composite money column as nullable returns a different type:

// non-nullable column
val money: CompositeMoneyColumn<BigDecimal, CurrencyUnit, MonetaryAmount> = compositeMoney()

// actual nullable column
val nullableMoney: CompositeMoneyColumn<MonetaryAmount?> = compositeMoney().nullable()

// expected nullable column
val money: CompositeMoneyColumn<BigDecimal?, CurrencyUnit?, MonetaryAmount?> = compositeMoney().nullable()

The current setup works as long as the insert value is a composite Money value, as the individual columns will not be able to be resolved.

If the component values (BigDecimal and CurrencyUnit) are inserted individually into the component columns, it will only work for either a non-nullable column or a nullable column with a non-null value. This happens because each component column is correctly nullable, but not the actual composite expression itself, resulting in the error:

Can't set null value to non-nullable CompositeMoneyColumn column

This fix adds an overload so that compositeMoney().nullable() returns the expected type and adds the ability to modify the internal nullable property in BiCompositeColumns.

None of the current tests included inserts/updates that targeted the individual component columns, so this has been included too.