diff --git a/sql/core/src/main/scala/org/apache/spark/sql/jdbc/DerbyDialect.scala b/sql/core/src/main/scala/org/apache/spark/sql/jdbc/DerbyDialect.scala index 36af0e6aeaf1..23da4dbb60a5 100644 --- a/sql/core/src/main/scala/org/apache/spark/sql/jdbc/DerbyDialect.scala +++ b/sql/core/src/main/scala/org/apache/spark/sql/jdbc/DerbyDialect.scala @@ -48,9 +48,15 @@ private case class DerbyDialect() extends JdbcDialect { case ByteType => Option(JdbcType("SMALLINT", java.sql.Types.SMALLINT)) case ShortType => Option(JdbcType("SMALLINT", java.sql.Types.SMALLINT)) case BooleanType => Option(JdbcType("BOOLEAN", java.sql.Types.BOOLEAN)) - // 31 is the maximum precision and 5 is the default scale for a Derby DECIMAL - case t: DecimalType if t.precision > 31 => - Option(JdbcType("DECIMAL(31,5)", java.sql.Types.DECIMAL)) + // 31 is the maximum precision + // https://db.apache.org/derby/docs/10.13/ref/rrefsqlj15260.html + case t: DecimalType => + val (p, s) = if (t.precision > 31) { + (31, math.max(t.scale - (t.precision - 31), 0)) + } else { + (t.precision, t.scale) + } + Option(JdbcType(s"DECIMAL($p,$s)", java.sql.Types.DECIMAL)) case _ => None } diff --git a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/v2/jdbc/DerbyTableCatalogSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/v2/jdbc/DerbyTableCatalogSuite.scala index e3714e604495..d793ef526c47 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/v2/jdbc/DerbyTableCatalogSuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/v2/jdbc/DerbyTableCatalogSuite.scala @@ -51,4 +51,12 @@ class DerbyTableCatalogSuite extends QueryTest with SharedSparkSession { checkAnswer(sql(s"SHOW TABLES IN derby.test1"), Row("test1", "TABLE2", false)) } } + + test("SPARK-48439: Calculate suitable precision and scale for DECIMAL type") { + withTable("derby.test1.table1") { + sql("CREATE TABLE derby.test1.table1 (c1 decimal(38, 18))") + sql("INSERT INTO derby.test1.table1 VALUES (1.123456789123456789)") + checkAnswer(sql("SELECT * FROM derby.test1.table1"), Row(1.12345678912)) + } + } }