diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/ExecutableFunctions.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/ExecutableFunctions.java index a86e933c9ffe93..8195d456cc7cb0 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/ExecutableFunctions.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/ExecutableFunctions.java @@ -28,9 +28,7 @@ import org.apache.doris.nereids.trees.expressions.literal.LargeIntLiteral; import org.apache.doris.nereids.trees.expressions.literal.NullLiteral; import org.apache.doris.nereids.trees.expressions.literal.SmallIntLiteral; -import org.apache.doris.nereids.trees.expressions.literal.StringLikeLiteral; import org.apache.doris.nereids.trees.expressions.literal.TinyIntLiteral; -import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral; import org.apache.doris.nereids.types.DoubleType; import java.math.BigInteger; @@ -105,15 +103,6 @@ public static Expression acos(DoubleLiteral literal) { } } - @ExecFunction(name = "append_trailing_char_if_absent") - public static Expression appendTrailingIfCharAbsent(StringLikeLiteral literal, StringLikeLiteral chr) { - if (literal.getValue().length() != 1) { - return null; - } - return literal.getValue().endsWith(chr.getValue()) ? literal - : new VarcharLiteral(literal.getValue() + chr.getValue()); - } - @ExecFunction(name = "e") public static Expression e() { // CHECKSTYLE IGNORE THIS LINE return new DoubleLiteral(Math.E); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/StringArithmetic.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/StringArithmetic.java index bc9cc29e7d06a0..5cf375aa3bb34a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/StringArithmetic.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/StringArithmetic.java @@ -794,6 +794,9 @@ public static Expression urlDecode(StringLikeLiteral first) { */ @ExecFunction(name = "append_trailing_char_if_absent") public static Expression appendTrailingCharIfAbsent(StringLikeLiteral first, StringLikeLiteral second) { + if (second.getValue().length() != 1) { + return new NullLiteral(first.getDataType()); + } if (first.getValue().endsWith(second.getValue())) { return first; } else { diff --git a/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_string_arithmatic.groovy b/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_string_arithmatic.groovy index 2bcdfc2fd24068..02cf78f1cc6f4a 100644 --- a/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_string_arithmatic.groovy +++ b/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_string_arithmatic.groovy @@ -197,6 +197,7 @@ suite("fold_constant_string_arithmatic") { testFoldConst("select append_trailing_char_if_absent('a','c')") testFoldConst("select append_trailing_char_if_absent('ac','c')") + testFoldConst("select append_trailing_char_if_absent('it','a')") testFoldConst("select ascii('1')") testFoldConst("select ascii('a')") @@ -684,4 +685,91 @@ suite("fold_constant_string_arithmatic") { // fix problem of cast date and time function exception testFoldConst("select ifnull(date_format(CONCAT_WS('', '9999-07', '-00'), '%Y-%m'),3)") + // Normal Usage Test Cases + + // Test Case 1: Append missing trailing character + testFoldConst("select append_trailing_char_if_absent('hello', '!')") + // Expected Output: 'hello!' + + // Test Case 2: Trailing character already present + testFoldConst("select append_trailing_char_if_absent('hello!', '!')") + // Expected Output: 'hello!' + + // Test Case 3: Append trailing space + testFoldConst("select append_trailing_char_if_absent('hello', ' ')") + // Expected Output: 'hello ' + + // Test Case 4: Empty string input + testFoldConst("select append_trailing_char_if_absent('', '!')") + // Expected Output: '!' + + // Test Case 5: Append different character + testFoldConst("select append_trailing_char_if_absent('hello', '?')") + // Expected Output: 'hello?' + + // Test Case 6: String ends with a different character + testFoldConst("select append_trailing_char_if_absent('hello?', '!')") + // Expected Output: 'hello?!' + + // Edge and Unusual Usage Test Cases + + // Test Case 7: Input is NULL + testFoldConst("select append_trailing_char_if_absent(NULL, '!')") + // Expected Output: NULL + + // Test Case 8: Trailing character is NULL + testFoldConst("select append_trailing_char_if_absent('hello', NULL)") + // Expected Output: NULL + + // Test Case 9: Empty trailing character + testFoldConst("select append_trailing_char_if_absent('hello', '')") + // Expected Output: Error or no change depending on implementation + + // Test Case 10: Trailing character is more than 1 character long + testFoldConst("select append_trailing_char_if_absent('hello', 'ab')") + // Expected Output: Error + + // Test Case 11: Input string is a number + testFoldConst("select append_trailing_char_if_absent(12345, '!')") + // Expected Output: Error or '12345!' + + // Test Case 12: Trailing character is a number + testFoldConst("select append_trailing_char_if_absent('hello', '1')") + // Expected Output: 'hello1' + + // Test Case 13: Input is a single character + testFoldConst("select append_trailing_char_if_absent('h', '!')") + // Expected Output: 'h!' + + // Test Case 14: Unicode character as input and trailing character + testFoldConst("select append_trailing_char_if_absent('こんにちは', '!')") + // Expected Output: 'こんにちは!' + + // Test Case 15: Multibyte character as trailing character + testFoldConst("select append_trailing_char_if_absent('hello', '😊')") + // Expected Output: 'hello😊' + + // Test Case 16: Long string input + testFoldConst("select append_trailing_char_if_absent('This is a very long string', '.')") + // Expected Output: 'This is a very long string.' + + // Error Handling Test Cases + + // Test Case 17: Invalid trailing character data type (numeric) + testFoldConst("select append_trailing_char_if_absent('hello', 1)") + // Expected Output: Error + + // Test Case 18: Invalid input data type (integer) + testFoldConst("select append_trailing_char_if_absent(12345, '!')") + // Expected Output: Error or '12345!' + + // Test Case 19: Non-ASCII characters + testFoldConst("select append_trailing_char_if_absent('Привет', '!')") + // Expected Output: 'Привет!' + + // Test Case 20: Trailing character with whitespace + testFoldConst("select append_trailing_char_if_absent('hello', ' ')") + // Expected Output: 'hello ' + + }