Skip to content

Commit

Permalink
Add support for guessing Decimal128 in MongoDB
Browse files Browse the repository at this point in the history
  • Loading branch information
ebyhr committed Aug 18, 2023
1 parent 00272ae commit beb92ca
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
import org.bson.types.Decimal128;
import org.bson.types.ObjectId;

import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
Expand Down Expand Up @@ -98,6 +99,7 @@
import static io.trino.spi.type.Chars.padSpaces;
import static io.trino.spi.type.DateTimeEncoding.unpackMillisUtc;
import static io.trino.spi.type.DateType.DATE;
import static io.trino.spi.type.DecimalType.createDecimalType;
import static io.trino.spi.type.DoubleType.DOUBLE;
import static io.trino.spi.type.SmallintType.SMALLINT;
import static io.trino.spi.type.TimeType.TIME_MILLIS;
Expand Down Expand Up @@ -900,6 +902,16 @@ else if (value instanceof Boolean) {
else if (value instanceof Float || value instanceof Double) {
typeSignature = DOUBLE.getTypeSignature();
}
else if (value instanceof Decimal128 decimal128) {
BigDecimal decimal;
try {
decimal = decimal128.bigDecimalValue();
}
catch (ArithmeticException e) {
return Optional.empty();
}
typeSignature = createDecimalType(decimal.precision(), decimal.scale()).getTypeSignature();
}
else if (value instanceof Date) {
typeSignature = TIMESTAMP_MILLIS.getTypeSignature();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import io.trino.testing.TestingConnectorBehavior;
import io.trino.testing.sql.TestTable;
import org.bson.Document;
import org.bson.types.Decimal128;
import org.bson.types.ObjectId;
import org.testng.SkipException;
import org.testng.annotations.AfterClass;
Expand Down Expand Up @@ -524,6 +525,26 @@ public void testSkipUnknownTypes()
assertUpdate("DROP TABLE test." + allUnknownFieldTable);
}

@Test
public void testSkipUnsupportedDecimal128()
{
String tableName = "test_unsupported_decimal128" + randomNameSuffix();

Document document = new Document(ImmutableMap.<String, Object>builder()
.put("col", 1)
.put("nan", Decimal128.NaN)
.put("negative_nan", Decimal128.NEGATIVE_NaN)
.put("positive_infinity", Decimal128.POSITIVE_INFINITY)
.put("negative_infinity", Decimal128.NEGATIVE_INFINITY)
.put("negative_zero", Decimal128.NEGATIVE_ZERO)
.buildOrThrow());
client.getDatabase("test").getCollection(tableName).insertOne(document);
assertQuery("SHOW COLUMNS FROM test." + tableName, "SELECT 'col', 'bigint', '', ''");
assertQuery("SELECT col FROM test." + tableName, "SELECT 1");

assertUpdate("DROP TABLE test." + tableName);
}

@Test(dataProvider = "dbRefProvider")
public void testDBRef(Object objectId, String expectedValue, String expectedType)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,14 @@ public void testDecimal()
.addRoundTrip("decimal(38, 0)", "CAST(NULL AS decimal(38, 0))", createDecimalType(38, 0), "CAST(NULL AS decimal(38, 0))")
.execute(getQueryRunner(), trinoCreateAsSelect("test_decimal"))
.execute(getQueryRunner(), trinoCreateAndInsert("test_decimal"));

SqlDataTypeTest.create()
.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(\"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"));
}

@Test
Expand Down

0 comments on commit beb92ca

Please sign in to comment.