From f29ad9712d64cf9a8c4fcaf484c4433607b9fff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Wa=C5=9B?= Date: Mon, 18 Sep 2023 15:25:23 +0200 Subject: [PATCH] Fix inferring type of decimals with leading zeros in MongoDB --- .../src/main/java/io/trino/plugin/mongodb/MongoSession.java | 5 ++++- .../java/io/trino/plugin/mongodb/TestMongoTypeMapping.java | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/plugin/trino-mongodb/src/main/java/io/trino/plugin/mongodb/MongoSession.java b/plugin/trino-mongodb/src/main/java/io/trino/plugin/mongodb/MongoSession.java index 534ed695b93a..ad0986e01edb 100644 --- a/plugin/trino-mongodb/src/main/java/io/trino/plugin/mongodb/MongoSession.java +++ b/plugin/trino-mongodb/src/main/java/io/trino/plugin/mongodb/MongoSession.java @@ -922,7 +922,10 @@ else if (value instanceof Decimal128 decimal128) { catch (ArithmeticException e) { return Optional.empty(); } - typeSignature = createDecimalType(decimal.precision(), decimal.scale()).getTypeSignature(); + // Java's BigDecimal.precision() returns precision for the unscaled value, so it skips leading zeros for values lower than 1. + // Trino's (SQL) decimal precision must include leading zeros in values less than 1, and can never be lower than scale. + int precision = Math.max(decimal.precision(), decimal.scale()); + typeSignature = createDecimalType(precision, decimal.scale()).getTypeSignature(); } else if (value instanceof Date) { typeSignature = TIMESTAMP_MILLIS.getTypeSignature(); diff --git a/plugin/trino-mongodb/src/test/java/io/trino/plugin/mongodb/TestMongoTypeMapping.java b/plugin/trino-mongodb/src/test/java/io/trino/plugin/mongodb/TestMongoTypeMapping.java index afd6b5032b8a..5cbe1a3d893b 100644 --- a/plugin/trino-mongodb/src/test/java/io/trino/plugin/mongodb/TestMongoTypeMapping.java +++ b/plugin/trino-mongodb/src/test/java/io/trino/plugin/mongodb/TestMongoTypeMapping.java @@ -190,6 +190,8 @@ public void testDecimal() .addRoundTrip("NumberDecimal(\"2\")", "CAST('2' AS decimal(1, 0))") .addRoundTrip("NumberDecimal(\"2.3\")", "CAST('2.3' AS decimal(2, 1))") .addRoundTrip("NumberDecimal(\"-2.3\")", "CAST('-2.3' AS decimal(2, 1))") + .addRoundTrip("NumberDecimal(\"0.03\")", "CAST('0.03' AS decimal(2, 2))") + .addRoundTrip("NumberDecimal(\"-0.03\")", "CAST('-0.03' AS decimal(2, 2))") .addRoundTrip("NumberDecimal(\"1234567890123456789012345678901234\")", "CAST('1234567890123456789012345678901234' AS decimal(34, 0))") // 34 is the max precision in Decimal128 .addRoundTrip("NumberDecimal(\"1234567890123456.789012345678901234\")", "CAST('1234567890123456.789012345678901234' AS decimal(34, 18))") .execute(getQueryRunner(), mongoCreateAndInsert(getSession(), "tpch", "test_decimal"));