From 8980265aad6fd50f4070ad973e00c8e1b1d28113 Mon Sep 17 00:00:00 2001 From: linrrarity Date: Sun, 28 Sep 2025 16:24:59 +0800 Subject: [PATCH] [feature](func) Support MID function (#56446) --- be/src/vec/functions/function_string.cpp | 1 + .../org/apache/doris/nereids/DorisLexer.g4 | 1 + .../org/apache/doris/nereids/DorisParser.g4 | 3 +- .../doris/catalog/BuiltinScalarFunctions.java | 2 +- .../string_functions/test_string_function.out | Bin 5386 -> 5959 bytes .../fold_constant_string_arithmatic.groovy | 30 +++++++++++++++ .../test_string_function.groovy | 35 ++++++++++++++++++ 7 files changed, 70 insertions(+), 2 deletions(-) diff --git a/be/src/vec/functions/function_string.cpp b/be/src/vec/functions/function_string.cpp index f6a94ce94b80e6..1a0e576c40b9ef 100644 --- a/be/src/vec/functions/function_string.cpp +++ b/be/src/vec/functions/function_string.cpp @@ -1480,6 +1480,7 @@ void register_function_string(SimpleFunctionFactory& factory) { factory.register_alias(FunctionLeft::name, "strleft"); factory.register_alias(FunctionRight::name, "strright"); factory.register_alias(SubstringUtil::name, "substr"); + factory.register_alias(SubstringUtil::name, "mid"); factory.register_alias(FunctionToLower::name, "lcase"); factory.register_alias(FunctionToUpper::name, "ucase"); factory.register_alias(FunctionStringDigestOneArg::name, "md5"); diff --git a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4 b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4 index 0e1dc32b32e0ea..1ae0cc0e075ced 100644 --- a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4 +++ b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4 @@ -351,6 +351,7 @@ MAX: 'MAX'; MAXVALUE: 'MAXVALUE'; MEMO:'MEMO'; MERGE: 'MERGE'; +MID: 'MID'; MIGRATE: 'MIGRATE'; MIGRATIONS: 'MIGRATIONS'; MIN: 'MIN'; diff --git a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 index 11bf78caa2b107..005271cf4808f5 100644 --- a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 +++ b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 @@ -1603,7 +1603,7 @@ primaryExpression (OVER windowSpec)? #groupConcat | TRIM LEFT_PAREN ((BOTH | LEADING | TRAILING) expression? | expression) FROM expression RIGHT_PAREN #trim - | (SUBSTR | SUBSTRING) LEFT_PAREN + | (SUBSTR | SUBSTRING | MID) LEFT_PAREN expression FROM expression (FOR expression)? RIGHT_PAREN #substring | POSITION LEFT_PAREN expression IN expression RIGHT_PAREN #position | functionCallExpression #functionCall @@ -2059,6 +2059,7 @@ nonReserved | MAX | MEMO | MERGE + | MID | MIGRATE | MIGRATIONS | MIN diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java index c53d493f3c107d..d514e0692e2ec9 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java @@ -968,7 +968,7 @@ public class BuiltinScalarFunctions implements FunctionHelper { scalar(StrToMap.class, "str_to_map"), scalar(SubBitmap.class, "sub_bitmap"), scalar(SubReplace.class, "sub_replace"), - scalar(Substring.class, "substr", "substring"), + scalar(Substring.class, "substr", "substring", "mid"), scalar(SubstringIndex.class, "substring_index"), scalar(Tan.class, "tan"), scalar(Tanh.class, "tanh"), diff --git a/regression-test/data/query_p0/sql_functions/string_functions/test_string_function.out b/regression-test/data/query_p0/sql_functions/string_functions/test_string_function.out index c34470a3ff4e6bc272d5b6c8d672d873dbbd0860..4c3478b764b2b30f25010185a318a6f70477ffa2 100644 GIT binary patch delta 582 zcmZ9|K?=e!5QSlMV+nNS1=6h$ai*!-OLzi7#45P(4B5N&B0>+*YiZvmd9(b7fqawq zX4-xib$UIAi}(V9`IKL4p{0rV?*BfG SK&A=MG>M;PwH~W_S^WTpoPB5j delta 16 XcmX@E*QK?Ak$3WcCicy){7f7GGt>nX 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 48914b59ef852b..6e68587f8fefc3 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 @@ -1338,6 +1338,36 @@ suite("fold_constant_string_arithmatic") { testFoldConst("select substring('abcdef' FROM 3)") testFoldConst("select substring('' FROM 3)") + // mid + testFoldConst("select mid('a',0,1)") + testFoldConst("select mid('a',-1,1)") + testFoldConst("select mid('a',1,1)") + testFoldConst("select mid('a',-2,1)") + testFoldConst("select mid('a',2,1)") + testFoldConst("select mid('a',-3,1)") + testFoldConst("select mid('a',3,1)") + testFoldConst("select mid('abcdef',-3,-1)") + testFoldConst("select mid('abcdef',3,-1)") + testFoldConst("select mid('',3,-1)") + testFoldConst("select mid('abcdef',3,10)") + testFoldConst("select mid('abcdef',-3)") + testFoldConst("select mid('abcdef',3)") + testFoldConst("select mid('',3)") + testFoldConst("select mid('a' FROM 0 FOR 1)") + testFoldConst("select mid('a' FROM -1 FOR 1)") + testFoldConst("select mid('a' FROM 1 FOR 1)") + testFoldConst("select mid('a' FROM -2 FOR 1)") + testFoldConst("select mid('a' FROM 2 FOR 1)") + testFoldConst("select mid('a' FROM -3 FOR 1)") + testFoldConst("select mid('a' FROM 3 FOR 1)") + testFoldConst("select mid('abcdef' FROM -3 FOR -1)") + testFoldConst("select mid('abcdef' FROM 3 FOR -1)") + testFoldConst("select mid('' FROM 3 FOR -1)") + testFoldConst("select mid('abcdef' FROM 3 FOR 10)") + testFoldConst("select mid('abcdef' FROM -3)") + testFoldConst("select mid('abcdef' FROM 3)") + testFoldConst("select mid('' FROM 3)") + // substring_index testFoldConst("select substring_index('a,b,c', ',', 2)") testFoldConst("select substring_index('a,b,c', '', 2)") diff --git a/regression-test/suites/query_p0/sql_functions/string_functions/test_string_function.groovy b/regression-test/suites/query_p0/sql_functions/string_functions/test_string_function.groovy index 9d8662a4f48aea..07122b80d7eec5 100644 --- a/regression-test/suites/query_p0/sql_functions/string_functions/test_string_function.groovy +++ b/regression-test/suites/query_p0/sql_functions/string_functions/test_string_function.groovy @@ -288,6 +288,41 @@ suite("test_string_function", "arrow_flight_sql") { qt_sql "select substr('abcdef',3,-1);" qt_sql "select substr('abcdef',-3,-1);" + qt_mid_1 "select mid('a',0,1);" + qt_mid_2 "select mid('a',-1,1);" + qt_mid_3 "select mid('a',1,1);" + qt_mid_4 "select mid('a',-2,1);" + qt_mid_5 "select mid('a',2,1);" + qt_mid_6 "select mid('a',-3,1);" + qt_mid_7 "select mid('a',3,1);" + qt_mid_8 "select mid('abcdef',-3,-1);" + qt_mid_9 "select mid('abcdef',3,-1);" + qt_mid_10 "select mid('',3,-1);" + qt_mid_11 "select mid('abcdef',3,10);" + qt_mid_12 "select mid('abcdef',-3);" + qt_mid_13 "select mid('abcdef',3);" + qt_mid_14 "select mid('',3);" + qt_mid_15 "select mid('a' FROM 0 FOR 1);" + qt_mid_16 "select mid('a' FROM -1 FOR 1);" + qt_mid_17 "select mid('a' FROM 1 FOR 1);" + qt_mid_18 "select mid('a' FROM -2 FOR 1);" + qt_mid_19 "select mid('a' FROM 2 FOR 1);" + qt_mid_20 "select mid('a' FROM -3 FOR 1);" + qt_mid_21 "select mid('a' FROM 3 FOR 1);" + qt_mid_22 "select mid('abcdef' FROM -3 FOR -1);" + qt_mid_23 "select mid('abcdef' FROM 3 FOR -1);" + qt_mid_24 "select mid('' FROM 3 FOR -1);" + qt_mid_25 "select mid('abcdef' FROM 3 FOR 10);" + qt_mid_26 "select mid('abcdef' FROM -3);" + qt_mid_27 "select mid('abcdef' FROM 3);" + qt_mid_28 "select mid('' FROM 3);" + qt_mid_29 "select mid(NULL, 2);" + qt_mid_30 "select mid(NULL, 2, 3)" + qt_mid_31 "select mid(NULL FROM 2);" + qt_mid_32 "select mid(NULL FROM 2 FOR 3);" + qt_mid_33 "select mid('hello', NULL);" + qt_mid_34 "select mid('hello', 2, NULL);" + qt_sql "select sub_replace(\"this is origin str\",\"NEW-STR\",1);" qt_sql "select sub_replace(\"doris\",\"***\",1,2);"