diff --git a/exposed-java-time/src/test/kotlin/org/jetbrains/exposed/v1/javatime/JavaTimeTests.kt b/exposed-java-time/src/test/kotlin/org/jetbrains/exposed/v1/javatime/JavaTimeTests.kt index 051a27610a..495e755042 100644 --- a/exposed-java-time/src/test/kotlin/org/jetbrains/exposed/v1/javatime/JavaTimeTests.kt +++ b/exposed-java-time/src/test/kotlin/org/jetbrains/exposed/v1/javatime/JavaTimeTests.kt @@ -25,6 +25,7 @@ import org.jetbrains.exposed.v1.tests.shared.expectException import org.junit.jupiter.api.Assertions.fail import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertNull import java.math.BigDecimal import java.math.RoundingMode import java.time.* @@ -544,20 +545,26 @@ class JavaTimeTests : DatabaseTestsBase() { val defaultDateTimes = listOf(LocalDateTime.now().asJdk8()) val tester = object : Table("array_tester") { val dates = array("dates", JavaLocalDateColumnType()).default(defaultDates) + val optDates = array("opt_dates", JavaLocalDateColumnType()).nullable() val datetimes = array("datetimes", JavaLocalDateTimeColumnType()).default(defaultDateTimes) + val optDatetimes = array("opt_datetimes", JavaLocalDateTimeColumnType()).nullable() } withTables(excludeSettings = TestDB.entries - TestDB.POSTGRESQL - TestDB.H2_V2, tester) { tester.insert { } val result1 = tester.selectAll().single() assertEqualLists(result1[tester.dates], defaultDates) + assertNull(result1[tester.optDates]) assertEqualLists(result1[tester.datetimes], defaultDateTimes) + assertNull(result1[tester.optDatetimes]) val datesInput = List(3) { LocalDate.of(2020 + it, 5, 4) } val datetimeInput = List(3) { LocalDateTime.of(2020 + it, 5, 4, 9, 9, 9) } tester.insert { it[dates] = datesInput + it[optDates] = null it[datetimes] = datetimeInput + it[optDatetimes] = null } val lastDate = tester.dates[3] diff --git a/exposed-jodatime/src/test/kotlin/org/jetbrains/exposed/v1/jodatime/JodaTimeTests.kt b/exposed-jodatime/src/test/kotlin/org/jetbrains/exposed/v1/jodatime/JodaTimeTests.kt index 4ade451426..cfb3beea79 100644 --- a/exposed-jodatime/src/test/kotlin/org/jetbrains/exposed/v1/jodatime/JodaTimeTests.kt +++ b/exposed-jodatime/src/test/kotlin/org/jetbrains/exposed/v1/jodatime/JodaTimeTests.kt @@ -37,6 +37,7 @@ import org.joda.time.DateTime import org.joda.time.DateTimeZone import org.joda.time.LocalTime import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertNull import kotlin.test.assertEquals class JodaTimeTests : DatabaseTestsBase() { @@ -418,20 +419,26 @@ class JodaTimeTests : DatabaseTestsBase() { val defaultDateTimes = listOf(DateTime.now()) val tester = object : Table("array_tester") { val dates = array("dates", JodaLocalDateColumnType()).default(defaultDates) + val optDates = array("opt_dates", JodaLocalDateColumnType()).nullable() val datetimes = array("datetimes", JodaLocalDateTimeColumnType()).default(defaultDateTimes) + val optDatetimes = array("opt_datetimes", JodaLocalDateTimeColumnType()).nullable() } withTables(excludeSettings = TestDB.ALL - TestDB.POSTGRESQL - TestDB.H2_V2 - TestDB.H2_V2_PSQL, tester) { tester.insert { } val result1 = tester.selectAll().single() assertEqualLists(result1[tester.dates], defaultDates) + assertNull(result1[tester.optDates]) assertEqualLists(result1[tester.datetimes], defaultDateTimes) + assertNull(result1[tester.optDatetimes]) val datesInput = List(3) { DateTime.parse("${2020 + it}-5-4") } val datetimeInput = List(3) { DateTime(2020 + it, 5, 4, 9, 9, 9) } tester.insert { it[dates] = datesInput + it[optDates] = null it[datetimes] = datetimeInput + it[optDatetimes] = null } val lastDate = tester.dates[3] diff --git a/exposed-kotlin-datetime/src/test/kotlin/org/jetbrains/exposed/v1/datetime/KotlinTimeTests.kt b/exposed-kotlin-datetime/src/test/kotlin/org/jetbrains/exposed/v1/datetime/KotlinTimeTests.kt index 46b24fbd49..4c4709faff 100644 --- a/exposed-kotlin-datetime/src/test/kotlin/org/jetbrains/exposed/v1/datetime/KotlinTimeTests.kt +++ b/exposed-kotlin-datetime/src/test/kotlin/org/jetbrains/exposed/v1/datetime/KotlinTimeTests.kt @@ -19,6 +19,7 @@ import org.jetbrains.exposed.v1.tests.shared.assertTrue import org.jetbrains.exposed.v1.tests.shared.expectException import org.junit.jupiter.api.Assertions.fail import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertNull import java.math.BigDecimal import java.math.RoundingMode import java.time.OffsetDateTime @@ -604,20 +605,26 @@ class KotlinTimeTests : DatabaseTestsBase() { val defaultDateTimes = listOf(now()) val tester = object : Table("array_tester") { val dates = array("dates", KotlinLocalDateColumnType()).default(defaultDates) + val optDates = array("opt_dates", KotlinLocalDateColumnType()).nullable() val datetimes = array("datetimes", KotlinLocalDateTimeColumnType()).default(defaultDateTimes) + val optDatetimes = array("opt_datetimes", KotlinLocalDateTimeColumnType()).nullable() } withTables(excludeSettings = TestDB.entries - TestDB.POSTGRESQL - TestDB.H2_V2, tester) { tester.insert { } val result1 = tester.selectAll().single() assertEqualLists(result1[tester.dates], defaultDates) + assertNull(result1[tester.optDates]) assertEqualLists(result1[tester.datetimes], defaultDateTimes) + assertNull(result1[tester.optDatetimes]) val datesInput = List(3) { LocalDate(2020 + it, 5, 4) } val datetimeInput = List(3) { LocalDateTime(2020 + it, 5, 4, 9, 9, 9) } tester.insert { it[dates] = datesInput + it[optDates] = null it[datetimes] = datetimeInput + it[optDatetimes] = null } val lastDate = tester.dates[3] diff --git a/exposed-r2dbc-tests/src/test/kotlin/org/jetbrains/exposed/v1/r2dbc/sql/tests/javatime/JavaTimeTests.kt b/exposed-r2dbc-tests/src/test/kotlin/org/jetbrains/exposed/v1/r2dbc/sql/tests/javatime/JavaTimeTests.kt index daa5ea0d6f..1574028e1b 100644 --- a/exposed-r2dbc-tests/src/test/kotlin/org/jetbrains/exposed/v1/r2dbc/sql/tests/javatime/JavaTimeTests.kt +++ b/exposed-r2dbc-tests/src/test/kotlin/org/jetbrains/exposed/v1/r2dbc/sql/tests/javatime/JavaTimeTests.kt @@ -29,6 +29,7 @@ import org.jetbrains.exposed.v1.r2dbc.tests.shared.assertEquals import org.jetbrains.exposed.v1.r2dbc.tests.shared.assertTrue import org.jetbrains.exposed.v1.r2dbc.tests.shared.expectException import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertNull import org.junit.jupiter.api.fail import java.math.BigDecimal import java.math.RoundingMode @@ -398,20 +399,26 @@ class JavaTimeTests : R2dbcDatabaseTestsBase() { val defaultDateTimes = listOf(LocalDateTime.now().asJdk8()) val tester = object : Table("array_tester") { val dates = array("dates", JavaLocalDateColumnType()).default(defaultDates) + val optDates = array("opt_dates", JavaLocalDateColumnType()).nullable() val datetimes = array("datetimes", JavaLocalDateTimeColumnType()).default(defaultDateTimes) + val optDatetimes = array("opt_datetimes", JavaLocalDateTimeColumnType()).nullable() } withTables(excludeSettings = TestDB.entries - TestDB.POSTGRESQL - TestDB.H2_V2, tester) { tester.insert { } val result1 = tester.selectAll().single() assertEqualLists(result1[tester.dates], defaultDates) + assertNull(result1[tester.optDates]) assertEqualLists(result1[tester.datetimes], defaultDateTimes) + assertNull(result1[tester.optDatetimes]) val datesInput = List(3) { LocalDate.of(2020 + it, 5, 4) } val datetimeInput = List(3) { LocalDateTime.of(2020 + it, 5, 4, 9, 9, 9) } tester.insert { it[dates] = datesInput + it[optDates] = null it[datetimes] = datetimeInput + it[optDatetimes] = null } val lastDate = tester.dates[3] diff --git a/exposed-r2dbc-tests/src/test/kotlin/org/jetbrains/exposed/v1/r2dbc/sql/tests/jodatime/JodaTimeTests.kt b/exposed-r2dbc-tests/src/test/kotlin/org/jetbrains/exposed/v1/r2dbc/sql/tests/jodatime/JodaTimeTests.kt index b7d6459684..32d872063b 100644 --- a/exposed-r2dbc-tests/src/test/kotlin/org/jetbrains/exposed/v1/r2dbc/sql/tests/jodatime/JodaTimeTests.kt +++ b/exposed-r2dbc-tests/src/test/kotlin/org/jetbrains/exposed/v1/r2dbc/sql/tests/jodatime/JodaTimeTests.kt @@ -41,6 +41,7 @@ import org.joda.time.DateTime import org.joda.time.DateTimeZone import org.joda.time.LocalTime import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertNull import kotlin.test.assertEquals class JodaTimeTests : R2dbcDatabaseTestsBase() { @@ -322,20 +323,26 @@ class JodaTimeTests : R2dbcDatabaseTestsBase() { val defaultDateTimes = listOf(DateTime.now()) val tester = object : Table("array_tester") { val dates = array("dates", JodaLocalDateColumnType()).default(defaultDates) + val optDates = array("opt_dates", JodaLocalDateColumnType()).nullable() val datetimes = array("datetimes", JodaLocalDateTimeColumnType()).default(defaultDateTimes) + val optDatetimes = array("opt_datetimes", JodaLocalDateTimeColumnType()).nullable() } withTables(excludeSettings = TestDB.ALL - TestDB.POSTGRESQL - TestDB.H2_V2 - TestDB.H2_V2_PSQL, tester) { tester.insert { } val result1 = tester.selectAll().single() assertEqualLists(result1[tester.dates], defaultDates) + assertNull(result1[tester.optDates]) assertEqualLists(result1[tester.datetimes], defaultDateTimes) + assertNull(result1[tester.optDatetimes]) val datesInput = List(3) { DateTime.parse("${2020 + it}-5-4") } val datetimeInput = List(3) { DateTime(2020 + it, 5, 4, 9, 9, 9) } tester.insert { it[dates] = datesInput + it[optDates] = null it[datetimes] = datetimeInput + it[optDatetimes] = null } val lastDate = tester.dates[3] diff --git a/exposed-r2dbc-tests/src/test/kotlin/org/jetbrains/exposed/v1/r2dbc/sql/tests/kotlindatetime/KotlinTimeTests.kt b/exposed-r2dbc-tests/src/test/kotlin/org/jetbrains/exposed/v1/r2dbc/sql/tests/kotlindatetime/KotlinTimeTests.kt index f3bc9b49ff..dbded7b60c 100644 --- a/exposed-r2dbc-tests/src/test/kotlin/org/jetbrains/exposed/v1/r2dbc/sql/tests/kotlindatetime/KotlinTimeTests.kt +++ b/exposed-r2dbc-tests/src/test/kotlin/org/jetbrains/exposed/v1/r2dbc/sql/tests/kotlindatetime/KotlinTimeTests.kt @@ -25,6 +25,7 @@ import org.jetbrains.exposed.v1.r2dbc.tests.shared.assertTrue import org.jetbrains.exposed.v1.r2dbc.tests.shared.expectException import org.junit.jupiter.api.Assertions.fail import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertNull import java.math.BigDecimal import java.math.RoundingMode import java.time.OffsetDateTime @@ -445,20 +446,26 @@ class KotlinTimeTests : R2dbcDatabaseTestsBase() { val defaultDateTimes = listOf(now()) val tester = object : Table("array_tester") { val dates = array("dates", KotlinLocalDateColumnType()).default(defaultDates) + val optDates = array("opt_dates", KotlinLocalDateColumnType()).nullable() val datetimes = array("datetimes", KotlinLocalDateTimeColumnType()).default(defaultDateTimes) + val optDatetimes = array("opt_datetimes", KotlinLocalDateTimeColumnType()).nullable() } withTables(excludeSettings = TestDB.entries - TestDB.POSTGRESQL - TestDB.H2_V2, tester) { tester.insert { } val result1 = tester.selectAll().single() assertEqualLists(result1[tester.dates], defaultDates) + assertNull(result1[tester.optDates]) assertEqualLists(result1[tester.datetimes], defaultDateTimes) + assertNull(result1[tester.optDatetimes]) val datesInput = List(3) { LocalDate(2020 + it, 5, 4) } val datetimeInput = List(3) { LocalDateTime(2020 + it, 5, 4, 9, 9, 9) } tester.insert { it[dates] = datesInput + it[optDates] = null it[datetimes] = datetimeInput + it[optDatetimes] = null } val lastDate = tester.dates[3] diff --git a/exposed-r2dbc/src/main/kotlin/org/jetbrains/exposed/v1/r2dbc/mappers/ArrayTypeMapper.kt b/exposed-r2dbc/src/main/kotlin/org/jetbrains/exposed/v1/r2dbc/mappers/ArrayTypeMapper.kt index 03651c41af..d26d4cf9c7 100644 --- a/exposed-r2dbc/src/main/kotlin/org/jetbrains/exposed/v1/r2dbc/mappers/ArrayTypeMapper.kt +++ b/exposed-r2dbc/src/main/kotlin/org/jetbrains/exposed/v1/r2dbc/mappers/ArrayTypeMapper.kt @@ -35,7 +35,7 @@ class ArrayTypeMapper : TypeMapper { if (columnType !is ArrayColumnType<*, *>) return false if (value == null) { - statement.bindNull(index - 1, columnType.arrayDeclaration()) + statement.bindNull(index - 1, columnType.arrayDeclaration(dialect)) return true } @@ -201,7 +201,7 @@ private fun java.sql.Timestamp.toLocalDateTime(): LocalDateTime = toInstant().at * Extension function to get the Java class type for an array column type. */ @OptIn(ExperimentalUuidApi::class) -private fun ArrayColumnType<*, *>.arrayDeclaration(): Class> = when (delegate) { +private fun ArrayColumnType<*, *>.arrayDeclaration(dialect: DatabaseDialect): Class> = when (delegate) { is ByteColumnType -> Array::class.java is UByteColumnType -> Array::class.java is ShortColumnType -> Array::class.java @@ -220,11 +220,13 @@ private fun ArrayColumnType<*, *>.arrayDeclaration(): Class> is CharacterColumnType -> Array::class.java is BooleanColumnType -> Array::class.java is IDateColumnType -> { + val hasTimePart = (delegate as IDateColumnType).hasTimePart // For date/time types, use Date or Timestamp arrays depending on whether the column type has a time part - if ((delegate as IDateColumnType).hasTimePart) { - Array::class.java - } else { - Array::class.java + when { + hasTimePart && dialect is PostgreSQLDialect -> Array::class.java + hasTimePart -> Array::class.java + dialect is PostgreSQLDialect -> Array::class.java + else -> Array::class.java } } else -> Array::class.java