diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/ColumnType.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/ColumnType.kt index 702ffaab6d..31b3de778d 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/ColumnType.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/ColumnType.kt @@ -440,6 +440,8 @@ class DoubleColumnType : ColumnType() { override fun sqlType(): String = currentDialect.dataTypeProvider.doubleType() override fun valueFromDB(value: Any): Double = when (value) { is Double -> value + // Cast as string to prevent precision loss + is Float -> value.toString().toDouble() is Number -> value.toDouble() is String -> value.toDouble() else -> error("Unexpected value of type Double: $value of ${value::class.qualifiedName}") diff --git a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/types/DoubleColumnTypeTests.kt b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/types/DoubleColumnTypeTests.kt new file mode 100644 index 0000000000..16f2b141b5 --- /dev/null +++ b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/types/DoubleColumnTypeTests.kt @@ -0,0 +1,49 @@ +package org.jetbrains.exposed.sql.tests.shared.types + +import org.jetbrains.exposed.dao.id.IntIdTable +import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.tests.DatabaseTestsBase +import org.jetbrains.exposed.sql.tests.shared.assertEquals +import org.junit.Test + +class DoubleColumnTypeTests : DatabaseTestsBase() { + object TestTable : IntIdTable("double_table") { + val amount = double("amount") + } + + @Test + fun testInsertAndSelectFromDoubleColumn() { + withTables(TestTable) { + val id = TestTable.insertAndGetId { + it[amount] = 9.23 + } + + TestTable.selectAll().where { TestTable.id eq id }.singleOrNull()?.let { + assertEquals(9.23, it[TestTable.amount]) + } + } + } + + @Test + fun testInsertAndSelectFromRealColumn() { + withDb { + val originalColumnDDL = TestTable.amount.descriptionDdl() + val realColumnDDL = originalColumnDDL.replace(" DOUBLE PRECISION ", " REAL ") + + // create table with double() column that uses SQL type REAL + TestTable.ddl + .map { it.replace(originalColumnDDL, realColumnDDL) } + .forEach { exec(it) } + + val id = TestTable.insertAndGetId { + it[amount] = 9.23 + } + + TestTable.selectAll().where { TestTable.id eq id }.singleOrNull()?.let { + assertEquals(9.23, it[TestTable.amount]) + } + + SchemaUtils.drop(TestTable) + } + } +}