From b5936e871efa29379a69430ff5059eeac1ec74f0 Mon Sep 17 00:00:00 2001 From: "Mateusz \"Serafin\" Gajewski" Date: Mon, 30 Mar 2026 13:08:13 +0200 Subject: [PATCH 1/2] Revert "Improve DynamicSliceOutput usage" This reverts commit c30dd5dc5d2b5c601ab55484a39f100b9d87ea5d. --- .../plugin/functions/python/TrinoTypes.java | 50 ++++++++----------- .../functions/python/TestPythonFunctions.java | 12 ----- 2 files changed, 22 insertions(+), 40 deletions(-) diff --git a/plugin/trino-functions-python/src/main/java/io/trino/plugin/functions/python/TrinoTypes.java b/plugin/trino-functions-python/src/main/java/io/trino/plugin/functions/python/TrinoTypes.java index 11701ef6b495..95c825e8462d 100644 --- a/plugin/trino-functions-python/src/main/java/io/trino/plugin/functions/python/TrinoTypes.java +++ b/plugin/trino-functions-python/src/main/java/io/trino/plugin/functions/python/TrinoTypes.java @@ -17,7 +17,6 @@ import io.airlift.slice.Slice; import io.airlift.slice.SliceInput; import io.airlift.slice.SliceOutput; -import io.airlift.slice.Slices; import io.trino.spi.TrinoException; import io.trino.spi.block.Block; import io.trino.spi.block.SqlMap; @@ -52,8 +51,6 @@ import io.trino.spi.type.Type; import io.trino.spi.type.VarcharType; -import java.io.IOException; -import java.io.UncheckedIOException; import java.math.BigDecimal; import java.util.List; @@ -113,7 +110,7 @@ public static void validateReturnType(Type type) public static Slice toRowTypeDescriptor(List types) { if (types.isEmpty()) { - SliceOutput output = Slices.allocate(8).getOutput(); + SliceOutput output = new DynamicSliceOutput(8); output.writeInt(TrinoType.ROW.id()); output.writeInt(0); return output.slice(); @@ -124,13 +121,9 @@ public static Slice toRowTypeDescriptor(List types) public static Slice toTypeDescriptor(Type type) { - try (SliceOutput output = new DynamicSliceOutput(64)) { - toTypeDescriptor(type, output); - return output.slice(); - } - catch (IOException e) { - throw new UncheckedIOException(e); - } + SliceOutput output = new DynamicSliceOutput(64); + toTypeDescriptor(type, output); + return output.slice(); } private static void toTypeDescriptor(Type type, SliceOutput output) @@ -214,13 +207,14 @@ private static void javaToBinary(Type type, Object value, SliceOutput output) case NumberType _ -> { TrinoNumber number = (TrinoNumber) value; - Slice slice = switch (number.toBigDecimal()) { - case TrinoNumber.BigDecimalValue(BigDecimal bigDecimal) -> utf8Slice(bigDecimal.toString()); - case TrinoNumber.Infinity(boolean negative) -> negative ? utf8Slice("-Infinity") : utf8Slice("Infinity"); - case TrinoNumber.NotANumber() -> utf8Slice("NaN"); - }; - - writeVariableSlice(slice, output); + switch (number.toBigDecimal()) { + case TrinoNumber.BigDecimalValue bigDecimalValue -> + writeVariableSlice(utf8Slice(bigDecimalValue.toString()), output); + case TrinoNumber.Infinity infinity -> + writeVariableSlice(infinity.negative() ? utf8Slice("-Infinity") : utf8Slice("Infinity"), output); + case TrinoNumber.NotANumber _ -> + writeVariableSlice(utf8Slice("NaN"), output); + } } case TimeWithTimeZoneType timeType -> { if (timeType.isShort()) { @@ -306,12 +300,14 @@ private static void blockToBinary(Type type, Block block, int position, SliceOut } case NumberType numberType -> { SqlNumber value = (SqlNumber) numberType.getObjectValue(block, position); - Slice slice = switch (value.value()) { - case TrinoNumber.BigDecimalValue(BigDecimal bigDecimal) -> utf8Slice(bigDecimal.toString()); - case TrinoNumber.Infinity(boolean negative) -> negative ? utf8Slice("-Infinity") : utf8Slice("Infinity"); - case TrinoNumber.NotANumber _ -> utf8Slice("NaN"); - }; - writeVariableSlice(slice, output); + switch (value.value()) { + case TrinoNumber.BigDecimalValue bigDecimalValue -> + writeVariableSlice(utf8Slice(bigDecimalValue.toString()), output); + case TrinoNumber.Infinity infinity -> + writeVariableSlice(infinity.negative() ? utf8Slice("-Infinity") : utf8Slice("Infinity"), output); + case TrinoNumber.NotANumber _ -> + writeVariableSlice(utf8Slice("NaN"), output); + } } case DateType dateType -> output.writeInt(dateType.getInt(block, position)); case TimeType timeType -> output.writeLong(picosToMicros(timeType.getLong(block, position))); @@ -418,14 +414,12 @@ public static Object binaryToJava(Type type, SliceInput input) case NumberType _ -> { String stringUtf8 = input.readSlice(input.readInt()).toStringUtf8(); - TrinoNumber.AsBigDecimal number = switch (stringUtf8) { + yield switch (stringUtf8) { case "NaN" -> new TrinoNumber.NotANumber(); case "Infinity" -> new TrinoNumber.Infinity(false); case "-Infinity" -> new TrinoNumber.Infinity(true); - default -> new TrinoNumber.BigDecimalValue(new BigDecimal(stringUtf8)); + default -> TrinoNumber.from(new BigDecimal(stringUtf8)); }; - - yield TrinoNumber.from(number); } case TimeType timeType -> { long micros = roundMicros(input.readLong(), timeType.getPrecision()) % MICROSECONDS_PER_DAY; diff --git a/plugin/trino-functions-python/src/test/java/io/trino/plugin/functions/python/TestPythonFunctions.java b/plugin/trino-functions-python/src/test/java/io/trino/plugin/functions/python/TestPythonFunctions.java index df5ef341f5ad..9882c5c8b64c 100644 --- a/plugin/trino-functions-python/src/test/java/io/trino/plugin/functions/python/TestPythonFunctions.java +++ b/plugin/trino-functions-python/src/test/java/io/trino/plugin/functions/python/TestPythonFunctions.java @@ -35,7 +35,6 @@ import static io.trino.testing.TestingHandles.TEST_CATALOG_NAME; import static io.trino.testing.TestingSession.testSessionBuilder; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS; import static org.junit.jupiter.api.parallel.ExecutionMode.CONCURRENT; @@ -771,17 +770,6 @@ def multiply(x, y): assertThat(assertions.query( query + "SELECT multiply(NUMBER '1.12345', NUMBER '2.54321')")) .matches("VALUES NUMBER '2.8571692745E+20'"); - - // TODO: https://github.com/trinodb/trino-wasm-python/pull/11 - assertThatThrownBy(() -> assertThat(assertions.query( - query + "SELECT multiply(NUMBER 'NaN', NUMBER '2.54321')")) - .matches("VALUES NUMBER 'NaN'")) - .hasMessageContaining("ValueError: Decimal is not finite: NaN"); - - assertThatThrownBy(() -> assertThat(assertions.query( - query + "SELECT multiply(NUMBER '-Infinity', NUMBER '2.54321')")) - .matches("VALUES NUMBER 'NaN'")) - .hasMessageContaining("ValueError: Decimal is not finite: -Infinity"); } @Test From d8cef8f18953829e5d3e89a09615a15d6825b088 Mon Sep 17 00:00:00 2001 From: "Mateusz \"Serafin\" Gajewski" Date: Mon, 30 Mar 2026 13:08:30 +0200 Subject: [PATCH 2/2] Revert "Add support to NUMBER to Python UDFs" This reverts commit a09030403e025620c56b8033afa971d4794a80fa. --- .../plugin/functions/python/TrinoTypes.java | 38 +------------------ .../functions/python/TestPythonFunctions.java | 21 ---------- 2 files changed, 1 insertion(+), 58 deletions(-) diff --git a/plugin/trino-functions-python/src/main/java/io/trino/plugin/functions/python/TrinoTypes.java b/plugin/trino-functions-python/src/main/java/io/trino/plugin/functions/python/TrinoTypes.java index 95c825e8462d..ef72d30550a6 100644 --- a/plugin/trino-functions-python/src/main/java/io/trino/plugin/functions/python/TrinoTypes.java +++ b/plugin/trino-functions-python/src/main/java/io/trino/plugin/functions/python/TrinoTypes.java @@ -35,11 +35,9 @@ import io.trino.spi.type.LongTimestamp; import io.trino.spi.type.LongTimestampWithTimeZone; import io.trino.spi.type.MapType; -import io.trino.spi.type.NumberType; import io.trino.spi.type.RealType; import io.trino.spi.type.RowType; import io.trino.spi.type.SmallintType; -import io.trino.spi.type.SqlNumber; import io.trino.spi.type.StandardTypes; import io.trino.spi.type.TimeType; import io.trino.spi.type.TimeWithTimeZoneType; @@ -47,7 +45,6 @@ import io.trino.spi.type.TimestampType; import io.trino.spi.type.TimestampWithTimeZoneType; import io.trino.spi.type.TinyintType; -import io.trino.spi.type.TrinoNumber; import io.trino.spi.type.Type; import io.trino.spi.type.VarcharType; @@ -159,7 +156,7 @@ private static TrinoType singletonType(Type type) case StandardTypes.TINYINT -> TrinoType.TINYINT; case StandardTypes.DOUBLE -> TrinoType.DOUBLE; case StandardTypes.REAL -> TrinoType.REAL; - case StandardTypes.DECIMAL, StandardTypes.NUMBER -> TrinoType.DECIMAL; + case StandardTypes.DECIMAL -> TrinoType.DECIMAL; case StandardTypes.VARCHAR -> TrinoType.VARCHAR; case StandardTypes.VARBINARY -> TrinoType.VARBINARY; case StandardTypes.DATE -> TrinoType.DATE; @@ -204,18 +201,6 @@ private static void javaToBinary(Type type, Object value, SliceOutput output) : Decimals.toString((Int128) value, decimalType.getScale()); writeVariableSlice(utf8Slice(decimalString), output); } - case NumberType _ -> { - TrinoNumber number = (TrinoNumber) value; - - switch (number.toBigDecimal()) { - case TrinoNumber.BigDecimalValue bigDecimalValue -> - writeVariableSlice(utf8Slice(bigDecimalValue.toString()), output); - case TrinoNumber.Infinity infinity -> - writeVariableSlice(infinity.negative() ? utf8Slice("-Infinity") : utf8Slice("Infinity"), output); - case TrinoNumber.NotANumber _ -> - writeVariableSlice(utf8Slice("NaN"), output); - } - } case TimeWithTimeZoneType timeType -> { if (timeType.isShort()) { long time = (long) value; @@ -298,17 +283,6 @@ private static void blockToBinary(Type type, Block block, int position, SliceOut : Decimals.toString((Int128) decimalType.getObject(block, position), decimalType.getScale()); writeVariableSlice(utf8Slice(decimalString), output); } - case NumberType numberType -> { - SqlNumber value = (SqlNumber) numberType.getObjectValue(block, position); - switch (value.value()) { - case TrinoNumber.BigDecimalValue bigDecimalValue -> - writeVariableSlice(utf8Slice(bigDecimalValue.toString()), output); - case TrinoNumber.Infinity infinity -> - writeVariableSlice(infinity.negative() ? utf8Slice("-Infinity") : utf8Slice("Infinity"), output); - case TrinoNumber.NotANumber _ -> - writeVariableSlice(utf8Slice("NaN"), output); - } - } case DateType dateType -> output.writeInt(dateType.getInt(block, position)); case TimeType timeType -> output.writeLong(picosToMicros(timeType.getLong(block, position))); case TimeWithTimeZoneType timeType -> { @@ -411,16 +385,6 @@ public static Object binaryToJava(Type type, SliceInput input) ? encodeShortScaledValue(decimal, decimalType.getScale(), HALF_UP) : encodeScaledValue(decimal, decimalType.getScale(), HALF_UP); } - case NumberType _ -> { - String stringUtf8 = input.readSlice(input.readInt()).toStringUtf8(); - - yield switch (stringUtf8) { - case "NaN" -> new TrinoNumber.NotANumber(); - case "Infinity" -> new TrinoNumber.Infinity(false); - case "-Infinity" -> new TrinoNumber.Infinity(true); - default -> TrinoNumber.from(new BigDecimal(stringUtf8)); - }; - } case TimeType timeType -> { long micros = roundMicros(input.readLong(), timeType.getPrecision()) % MICROSECONDS_PER_DAY; yield micros * PICOSECONDS_PER_MICROSECOND; diff --git a/plugin/trino-functions-python/src/test/java/io/trino/plugin/functions/python/TestPythonFunctions.java b/plugin/trino-functions-python/src/test/java/io/trino/plugin/functions/python/TestPythonFunctions.java index 9882c5c8b64c..c8dc1779a3d6 100644 --- a/plugin/trino-functions-python/src/test/java/io/trino/plugin/functions/python/TestPythonFunctions.java +++ b/plugin/trino-functions-python/src/test/java/io/trino/plugin/functions/python/TestPythonFunctions.java @@ -751,27 +751,6 @@ SELECT bad_bigint_return() "TypeError: 'str' object cannot be interpreted as an integer"); } - @Test - public void testTypeNumber() - { - String query = - """ - WITH FUNCTION multiply(x number, y number) - RETURNS number - LANGUAGE PYTHON - WITH (handler = 'multiply') - AS $$ - from decimal import Decimal - def multiply(x, y): - return x * y * Decimal("100000000000000000000.000000000000000000000000000000000000001") - $$ - """; - - assertThat(assertions.query( - query + "SELECT multiply(NUMBER '1.12345', NUMBER '2.54321')")) - .matches("VALUES NUMBER '2.8571692745E+20'"); - } - @Test public void testTypeInteger() {