This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git

commit 31984bb4f0175c2cfc9a10685cbe3db306c03749
Author: Uniqueyou <[email protected]>
AuthorDate: Wed Apr 10 10:05:58 2024 +0800

    [feature](function) support quote string function #33055
---
 be/src/vec/functions/function_string.cpp           | 28 +++++++++
 be/test/vec/function/function_string_test.cpp      | 12 ++++
 .../sql-functions/string-functions/quote.md        | 47 +++++++++++++++
 .../sql-functions/string-functions/quote.md        | 47 +++++++++++++++
 .../doris/catalog/BuiltinScalarFunctions.java      |  2 +
 .../trees/expressions/functions/scalar/Quote.java  | 69 ++++++++++++++++++++++
 .../expressions/visitor/ScalarFunctionVisitor.java |  5 ++
 gensrc/script/doris_builtins_functions.py          |  2 +
 8 files changed, 212 insertions(+)

diff --git a/be/src/vec/functions/function_string.cpp 
b/be/src/vec/functions/function_string.cpp
index 8aee837ac63..69f8699b5c8 100644
--- a/be/src/vec/functions/function_string.cpp
+++ b/be/src/vec/functions/function_string.cpp
@@ -21,6 +21,7 @@
 #include <math.h>
 #include <re2/stringpiece.h>
 
+#include <cstddef>
 #include <string_view>
 
 #include "common/status.h"
@@ -57,6 +58,30 @@ struct StringASCII {
     }
 };
 
+struct NameQuote {
+    static constexpr auto name = "quote";
+};
+
+struct NameQuoteImpl {
+    static Status vector(const ColumnString::Chars& data, const 
ColumnString::Offsets& offsets,
+                         ColumnString::Chars& res_data, ColumnString::Offsets& 
res_offsets) {
+        size_t offset_size = offsets.size();
+        size_t pos = 0;
+        res_offsets.resize(offset_size);
+        res_data.resize(data.size() + offset_size * 2);
+        for (int i = 0; i < offset_size; i++) {
+            const unsigned char* raw_str = &data[offsets[i - 1]];
+            ColumnString::Offset size = offsets[i] - offsets[i - 1];
+            res_data[pos] = '\'';
+            std::memcpy(res_data.data() + pos + 1, raw_str, size);
+            res_data[pos + size + 1] = '\'';
+            pos += size + 2;
+            res_offsets[i] = pos;
+        }
+        return Status::OK();
+    }
+};
+
 struct NameStringLenght {
     static constexpr auto name = "length";
 };
@@ -1052,6 +1077,8 @@ using FunctionStringLocate =
 using FunctionStringFindInSet =
         FunctionBinaryToType<DataTypeString, DataTypeString, 
StringFindInSetImpl, NameFindInSet>;
 
+using FunctionQuote = FunctionStringToString<NameQuoteImpl, NameQuote>;
+
 using FunctionToLower = FunctionStringToString<TransferImpl<NameToLower>, 
NameToLower>;
 
 using FunctionToUpper = FunctionStringToString<TransferImpl<NameToUpper>, 
NameToUpper>;
@@ -1082,6 +1109,7 @@ void register_function_string(SimpleFunctionFactory& 
factory) {
     factory.register_function<FunctionStringFindInSet>();
     factory.register_function<FunctionStringLocate>();
     factory.register_function<FunctionStringLocatePos>();
+    factory.register_function<FunctionQuote>();
     factory.register_function<FunctionReverseCommon>();
     factory.register_function<FunctionUnHex>();
     factory.register_function<FunctionToLower>();
diff --git a/be/test/vec/function/function_string_test.cpp 
b/be/test/vec/function/function_string_test.cpp
index d8d1a57b8eb..2c0fecbb300 100644
--- a/be/test/vec/function/function_string_test.cpp
+++ b/be/test/vec/function/function_string_test.cpp
@@ -215,6 +215,18 @@ TEST(function_string_test, function_string_length_test) {
     static_cast<void>(check_function<DataTypeInt32, true>(func_name, 
input_types, data_set));
 }
 
+TEST(function_string_test, function_string_quote_test) {
+    std::string func_name = "quote";
+    InputTypeSet input_types = {TypeIndex::String};
+    DataSet data_set = {{{std::string("hello")}, std::string(R"('hello')")},
+                        {{std::string("hello\t\n\nworld")}, 
std::string("'hello\t\n\nworld'")},
+                        {{std::string("HELLO,!^%")}, 
std::string("'HELLO,!^%'")},
+                        {{std::string("MYtestStr\\t\\n")}, 
std::string("'MYtestStr\\t\\n'")},
+                        {{std::string("")}, std::string("''")},
+                        {{Null()}, Null()}};
+    static_cast<void>(check_function<DataTypeString, true>(func_name, 
input_types, data_set));
+}
+
 TEST(function_string_test, function_append_trailing_char_if_absent_test) {
     std::string func_name = "append_trailing_char_if_absent";
 
diff --git a/docs/en/docs/sql-manual/sql-functions/string-functions/quote.md 
b/docs/en/docs/sql-manual/sql-functions/string-functions/quote.md
new file mode 100644
index 00000000000..06246341bd5
--- /dev/null
+++ b/docs/en/docs/sql-manual/sql-functions/string-functions/quote.md
@@ -0,0 +1,47 @@
+---
+{
+    "title": "QUOTE",
+    "language": "en"
+}
+---
+
+<!-- 
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+## quote
+### description
+#### Syntax
+
+`VARCHAR quote(VARCHAR str)`
+
+
+Output all the strings in the argument as is and wrap them with ''
+
+### example
+
+```
+mysql> select quote('hello world!\\t');
++-------------------------+
+| quote('hello world!\t') |
++-------------------------+
+| 'hello world!\t'        |
++-------------------------+
+```
+### keywords
+    QUOTE
diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/string-functions/quote.md 
b/docs/zh-CN/docs/sql-manual/sql-functions/string-functions/quote.md
new file mode 100644
index 00000000000..ecc0c7d40d4
--- /dev/null
+++ b/docs/zh-CN/docs/sql-manual/sql-functions/string-functions/quote.md
@@ -0,0 +1,47 @@
+---
+{
+    "title": "QUOTE",
+    "language": "zh-CN"
+}
+---
+
+<!-- 
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+## quote
+### description
+#### Syntax
+
+`VARCHAR quote(VARCHAR str)`
+
+
+将参数中所有的字符串按原样输出,并用''套起来
+
+### example
+
+```
+mysql> select quote('hello world!\\t');
++-------------------------+
+| quote('hello world!\t') |
++-------------------------+
+| 'hello world!\t'        |
++-------------------------+
+```
+### keywords
+    QUOTE
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 d28cb751eaa..d27b0f3a311 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
@@ -317,6 +317,7 @@ import 
org.apache.doris.nereids.trees.expressions.functions.scalar.Protocol;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.QuantilePercent;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.QuantileStateEmpty;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Quarter;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.Quote;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Radians;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Random;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.RandomBytes;
@@ -868,6 +869,7 @@ public class BuiltinScalarFunctions implements 
FunctionHelper {
             scalar(Unhex.class, "unhex"),
             scalar(UnixTimestamp.class, "unix_timestamp"),
             scalar(Upper.class, "ucase", "upper"),
+            scalar(Quote.class, "quote"),
             scalar(UrlDecode.class, "url_decode"),
             scalar(User.class, "user"),
             scalar(UtcTimestamp.class, "utc_timestamp"),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Quote.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Quote.java
new file mode 100644
index 00000000000..25f97e6e395
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Quote.java
@@ -0,0 +1,69 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.functions.scalar;
+
+import org.apache.doris.catalog.FunctionSignature;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
+import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
+import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.StringType;
+import org.apache.doris.nereids.types.VarcharType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/**
+ * ScalarFunction 'quote'. This class is not generated by GenerateFunction.
+ */
+public class Quote extends ScalarFunction
+        implements UnaryExpression, ExplicitlyCastableSignature, 
PropagateNullable {
+
+    public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(VarcharType.SYSTEM_DEFAULT),
+            
FunctionSignature.ret(StringType.INSTANCE).args(StringType.INSTANCE));
+
+    /**
+     * constructor with 1 argument.
+     */
+    public Quote(Expression arg) {
+        super("quote", arg);
+    }
+
+    /**
+     * withChildren.
+     */
+    @Override
+    public Quote withChildren(List<Expression> children) {
+        Preconditions.checkArgument(children.size() == 1);
+        return new Quote(children.get(0));
+    }
+
+    @Override
+    public List<FunctionSignature> getSignatures() {
+        return SIGNATURES;
+    }
+
+    @Override
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitQuote(this, context);
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
index 83a4a2aa027..baa801f7786 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
@@ -316,6 +316,7 @@ import 
org.apache.doris.nereids.trees.expressions.functions.scalar.Protocol;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.QuantilePercent;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.QuantileStateEmpty;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Quarter;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.Quote;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Radians;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Random;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.RandomBytes;
@@ -1987,6 +1988,10 @@ public interface ScalarFunctionVisitor<R, C> {
         return visitScalarFunction(upper, context);
     }
 
+    default R visitQuote(Quote quote, C context) {
+        return visitScalarFunction(quote, context);
+    }
+
     default R visitUser(User user, C context) {
         return visitScalarFunction(user, context);
     }
diff --git a/gensrc/script/doris_builtins_functions.py 
b/gensrc/script/doris_builtins_functions.py
index 3d87ab86fd2..0e7615829d9 100644
--- a/gensrc/script/doris_builtins_functions.py
+++ b/gensrc/script/doris_builtins_functions.py
@@ -1576,6 +1576,7 @@ visible_functions = {
         [['char_length', 'character_length'], 'INT', ['VARCHAR'], ''],
         [['lower', 'lcase'], 'VARCHAR', ['VARCHAR'], ''],
         [['upper', 'ucase'], 'VARCHAR', ['VARCHAR'], ''],
+        [['quote'], 'VARCHAR', ['VARCHAR'], ''],
         [['initcap'], 'VARCHAR', ['VARCHAR'], ''],
         [['trim'], 'VARCHAR', ['VARCHAR','VARCHAR'], ''],
         [['trim'], 'VARCHAR', ['VARCHAR'], ''],
@@ -1638,6 +1639,7 @@ visible_functions = {
         [['char_length', 'character_length'], 'INT', ['STRING'], ''],
         [['lower', 'lcase'], 'STRING', ['STRING'], ''],
         [['upper', 'ucase'], 'STRING', ['STRING'], ''],
+        [['quote'], 'STRING', ['STRING'], ''],
         [['trim'], 'STRING', ['STRING'], ''],
         [['trim'], 'STRING', ['STRING','STRING'], ''],
         [['ltrim'], 'STRING', ['STRING'], ''],


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to