diff --git a/core/trino-main/src/main/java/io/trino/operator/scalar/ConcatFunction.java b/core/trino-main/src/main/java/io/trino/operator/scalar/ConcatFunction.java index 1f05a7651430..31a772d4a021 100644 --- a/core/trino-main/src/main/java/io/trino/operator/scalar/ConcatFunction.java +++ b/core/trino-main/src/main/java/io/trino/operator/scalar/ConcatFunction.java @@ -25,7 +25,6 @@ import java.lang.invoke.MethodHandle; import static io.trino.spi.StandardErrorCode.INVALID_FUNCTION_ARGUMENT; -import static io.trino.spi.StandardErrorCode.NOT_SUPPORTED; import static io.trino.spi.block.PageBuilderStatus.DEFAULT_MAX_PAGE_SIZE_IN_BYTES; import static io.trino.spi.function.InvocationConvention.InvocationArgumentConvention.NEVER_NULL; import static io.trino.spi.function.InvocationConvention.InvocationReturnConvention.FAIL_ON_NULL; @@ -43,7 +42,6 @@ public final class ConcatFunction public static final ConcatFunction VARBINARY_CONCAT = new ConcatFunction(VARBINARY.getTypeSignature(), "concatenates given varbinary values"); - private static final int MAX_INPUT_VALUES = 254; private static final int MAX_OUTPUT_LENGTH = DEFAULT_MAX_PAGE_SIZE_IN_BYTES; private ConcatFunction(TypeSignature type, String description) @@ -68,10 +66,6 @@ protected SpecializedSqlScalarFunction specialize(BoundSignature boundSignature) throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "There must be two or more concatenation arguments"); } - if (arity > MAX_INPUT_VALUES) { - throw new TrinoException(NOT_SUPPORTED, "Too many arguments for string concatenation"); - } - MethodHandle arrayMethodHandle = methodHandle(ConcatFunction.class, "concat", Slice[].class); MethodHandle customMethodHandle = arrayMethodHandle.asCollector(Slice[].class, arity); diff --git a/core/trino-main/src/main/java/io/trino/operator/scalar/ConcatWsFunction.java b/core/trino-main/src/main/java/io/trino/operator/scalar/ConcatWsFunction.java index f81c688d2693..298a2e254a9d 100644 --- a/core/trino-main/src/main/java/io/trino/operator/scalar/ConcatWsFunction.java +++ b/core/trino-main/src/main/java/io/trino/operator/scalar/ConcatWsFunction.java @@ -31,7 +31,6 @@ import java.util.Collections; import static io.trino.spi.StandardErrorCode.INVALID_FUNCTION_ARGUMENT; -import static io.trino.spi.StandardErrorCode.NOT_SUPPORTED; import static io.trino.spi.block.PageBuilderStatus.DEFAULT_MAX_PAGE_SIZE_IN_BYTES; import static io.trino.spi.function.InvocationConvention.InvocationArgumentConvention.BOXED_NULLABLE; import static io.trino.spi.function.InvocationConvention.InvocationArgumentConvention.NEVER_NULL; @@ -55,7 +54,6 @@ public final class ConcatWsFunction extends SqlScalarFunction { public static final ConcatWsFunction CONCAT_WS = new ConcatWsFunction(); - private static final int MAX_INPUT_VALUES = 254; private static final int MAX_OUTPUT_LENGTH = DEFAULT_MAX_PAGE_SIZE_IN_BYTES; @ScalarFunction("concat_ws") @@ -146,10 +144,6 @@ public int getCount() private static Slice concatWs(Slice separator, SliceArray values) { - if (values.getCount() > MAX_INPUT_VALUES) { - throw new TrinoException(NOT_SUPPORTED, "Too many arguments for string concatenation"); - } - // Validate size of output int length = 0; boolean requiresSeparator = false; diff --git a/core/trino-main/src/test/java/io/trino/operator/scalar/TestConcatWsFunction.java b/core/trino-main/src/test/java/io/trino/operator/scalar/TestConcatWsFunction.java index 1c7914f390c2..d4db01c01e0b 100644 --- a/core/trino-main/src/test/java/io/trino/operator/scalar/TestConcatWsFunction.java +++ b/core/trino-main/src/test/java/io/trino/operator/scalar/TestConcatWsFunction.java @@ -14,6 +14,7 @@ package io.trino.operator.scalar; import io.trino.sql.query.QueryAssertions; +import org.intellij.lang.annotations.Language; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -27,6 +28,8 @@ @TestInstance(PER_CLASS) public class TestConcatWsFunction { + private static final int MAX_INPUT_VALUES = 254; + private static final int MAX_CONCAT_VALUES = MAX_INPUT_VALUES - 1; private QueryAssertions assertions; @BeforeAll @@ -159,6 +162,16 @@ public void testArray() assertThat(assertions.function("concat_ws", "','", "ARRAY['abc', '', '', 'xyz','abcdefghi']")) .hasType(VARCHAR) .isEqualTo("abc,,,xyz,abcdefghi"); + + // array may exceed the limit + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < MAX_CONCAT_VALUES; i++) { + builder.append(i).append(','); + } + builder.append(MAX_CONCAT_VALUES); + assertThat(assertions.function("concat_ws", "','", "transform(sequence(0, " + MAX_CONCAT_VALUES + "), x -> cast(x as varchar))")) + .hasType(VARCHAR) + .isEqualTo(builder.toString()); } @Test @@ -175,6 +188,20 @@ public void testBadArguments() .hasMessageContaining("Unexpected parameters"); } + @Test + public void testTooManyArguments() + { + // all function arguments limit to 127 in io.trino.sql.analyzer.ExpressionAnalyzer.Visitor.visitFunctionCall + int argumentsLimit = 127; + @Language("SQL") String[] inputValues = new String[argumentsLimit + 1]; + inputValues[0] = "','"; + for (int i = 1; i <= argumentsLimit; i++) { + inputValues[i] = ("'" + i + "'"); + } + assertTrinoExceptionThrownBy(() -> assertions.function("concat_ws", inputValues).evaluate()) + .hasMessage("line 1:8: Too many arguments for function call concat_ws()"); + } + @Test public void testLowArguments() {