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

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

commit bd3ee3ebdca08743c14ac62f971929f7d98aee68
Author: zclllyybb <zhaochan...@selectdb.com>
AuthorDate: Wed Sep 20 17:21:45 2023 +0800

    [feature](function) Support SHA family functions (#24342)
---
 be/src/util/sha.cpp                                | 118 +++++++++++++++++++++
 be/src/util/sha.h                                  |  75 +++++++++++++
 be/src/vec/functions/function_string.cpp           |  11 +-
 be/src/vec/functions/function_string.h             | 107 ++++++++++++++++++-
 .../sql-functions/encrypt-digest-functions/sha.md  |  53 +++++++++
 .../sql-functions/encrypt-digest-functions/sha2.md |  70 ++++++++++++
 docs/sidebars.json                                 |   4 +-
 .../sql-functions/encrypt-digest-functions/sha.md  |  54 ++++++++++
 .../sql-functions/encrypt-digest-functions/sha2.md |  70 ++++++++++++
 .../apache/doris/analysis/FunctionCallExpr.java    |  13 +++
 .../doris/catalog/BuiltinScalarFunctions.java      |   4 +
 .../trees/expressions/functions/scalar/Sha1.java   |  68 ++++++++++++
 .../trees/expressions/functions/scalar/Sha2.java   |  69 ++++++++++++
 .../expressions/visitor/ScalarFunctionVisitor.java |  10 ++
 gensrc/script/doris_builtins_functions.py          |   7 ++
 .../encryption_digest/test_digest.out              |  39 +++++++
 .../sql_functions/encryption_digest/test_md5.out   |   6 --
 .../{test_md5.groovy => test_digest.groovy}        |  19 +++-
 18 files changed, 781 insertions(+), 16 deletions(-)

diff --git a/be/src/util/sha.cpp b/be/src/util/sha.cpp
new file mode 100644
index 00000000000..68099ff9269
--- /dev/null
+++ b/be/src/util/sha.cpp
@@ -0,0 +1,118 @@
+// 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.
+
+#include "util/sha.h"
+
+#include <openssl/sha.h>
+
+#include <string_view>
+
+namespace doris {
+
+constexpr static char dig_vec_lower[] = "0123456789abcdef";
+
+void SHA1Digest::reset(const void* data, size_t length) {
+    SHA1_Init(&_sha_ctx);
+    SHA1_Update(&_sha_ctx, data, length);
+}
+
+std::string_view SHA1Digest::digest() {
+    unsigned char buf[SHA_DIGEST_LENGTH];
+    SHA1_Final(buf, &_sha_ctx);
+
+    char* to = _reuse_hex;
+    for (int i = 0; i < SHA_DIGEST_LENGTH; ++i) {
+        *to++ = dig_vec_lower[buf[i] >> 4];
+        *to++ = dig_vec_lower[buf[i] & 0x0F];
+    }
+
+    return std::string_view {_reuse_hex, _reuse_hex + 2 * SHA_DIGEST_LENGTH};
+}
+
+void SHA224Digest::reset(const void* data, size_t length) {
+    SHA224_Init(&_sha224_ctx);
+    SHA224_Update(&_sha224_ctx, data, length);
+}
+
+std::string_view SHA224Digest::digest() {
+    unsigned char buf[SHA224_DIGEST_LENGTH];
+    SHA224_Final(buf, &_sha224_ctx);
+
+    char* to = _reuse_hex;
+    for (int i = 0; i < SHA224_DIGEST_LENGTH; ++i) {
+        *to++ = dig_vec_lower[buf[i] >> 4];
+        *to++ = dig_vec_lower[buf[i] & 0x0F];
+    }
+
+    return std::string_view {_reuse_hex, _reuse_hex + 2 * 
SHA224_DIGEST_LENGTH};
+}
+
+void SHA256Digest::reset(const void* data, size_t length) {
+    SHA256_Init(&_sha256_ctx);
+    SHA256_Update(&_sha256_ctx, data, length);
+}
+
+std::string_view SHA256Digest::digest() {
+    unsigned char buf[SHA256_DIGEST_LENGTH];
+    SHA256_Final(buf, &_sha256_ctx);
+
+    char* to = _reuse_hex;
+    for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
+        *to++ = dig_vec_lower[buf[i] >> 4];
+        *to++ = dig_vec_lower[buf[i] & 0x0F];
+    }
+
+    return std::string_view {_reuse_hex, _reuse_hex + 2 * 
SHA256_DIGEST_LENGTH};
+}
+
+void SHA384Digest::reset(const void* data, size_t length) {
+    SHA384_Init(&_sha384_ctx);
+    SHA384_Update(&_sha384_ctx, data, length);
+}
+
+std::string_view SHA384Digest::digest() {
+    unsigned char buf[SHA384_DIGEST_LENGTH];
+    SHA384_Final(buf, &_sha384_ctx);
+
+    char* to = _reuse_hex;
+    for (int i = 0; i < SHA384_DIGEST_LENGTH; ++i) {
+        *to++ = dig_vec_lower[buf[i] >> 4];
+        *to++ = dig_vec_lower[buf[i] & 0x0F];
+    }
+
+    return std::string_view {_reuse_hex, _reuse_hex + 2 * 
SHA384_DIGEST_LENGTH};
+}
+
+void SHA512Digest::reset(const void* data, size_t length) {
+    SHA512_Init(&_sha512_ctx);
+    SHA512_Update(&_sha512_ctx, data, length);
+}
+
+std::string_view SHA512Digest::digest() {
+    unsigned char buf[SHA512_DIGEST_LENGTH];
+    SHA512_Final(buf, &_sha512_ctx);
+
+    char* to = _reuse_hex;
+    for (int i = 0; i < SHA512_DIGEST_LENGTH; ++i) {
+        *to++ = dig_vec_lower[buf[i] >> 4];
+        *to++ = dig_vec_lower[buf[i] & 0x0F];
+    }
+
+    return std::string_view {_reuse_hex, _reuse_hex + 2 * 
SHA512_DIGEST_LENGTH};
+}
+
+} // namespace doris
diff --git a/be/src/util/sha.h b/be/src/util/sha.h
new file mode 100644
index 00000000000..1545dd3c031
--- /dev/null
+++ b/be/src/util/sha.h
@@ -0,0 +1,75 @@
+// 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.
+
+#pragma once
+
+#include <openssl/sha.h>
+
+#include <string_view>
+
+namespace doris {
+
+class SHA1Digest {
+public:
+    void reset(const void* data, size_t length);
+    std::string_view digest();
+
+private:
+    SHA_CTX _sha_ctx;
+    char _reuse_hex[2 * SHA_DIGEST_LENGTH];
+};
+
+class SHA224Digest {
+public:
+    void reset(const void* data, size_t length);
+    std::string_view digest();
+
+private:
+    SHA256_CTX _sha224_ctx;
+    char _reuse_hex[2 * SHA224_DIGEST_LENGTH];
+};
+
+class SHA256Digest {
+public:
+    void reset(const void* data, size_t length);
+    std::string_view digest();
+
+private:
+    SHA256_CTX _sha256_ctx;
+    char _reuse_hex[2 * SHA256_DIGEST_LENGTH];
+};
+
+class SHA384Digest {
+public:
+    void reset(const void* data, size_t length);
+    std::string_view digest();
+
+private:
+    SHA512_CTX _sha384_ctx;
+    char _reuse_hex[2 * SHA384_DIGEST_LENGTH];
+};
+
+class SHA512Digest {
+public:
+    void reset(const void* data, size_t length);
+    std::string_view digest();
+
+private:
+    SHA512_CTX _sha512_ctx;
+    char _reuse_hex[2 * SHA512_DIGEST_LENGTH];
+};
+} // namespace doris
diff --git a/be/src/vec/functions/function_string.cpp 
b/be/src/vec/functions/function_string.cpp
index 5812c7badbf..df9f28a5798 100644
--- a/be/src/vec/functions/function_string.cpp
+++ b/be/src/vec/functions/function_string.cpp
@@ -972,7 +972,6 @@ void register_function_string(SimpleFunctionFactory& 
factory) {
     factory.register_function<FunctionFromBase64>();
     factory.register_function<FunctionSplitPart>();
     factory.register_function<FunctionSplitByString>();
-    factory.register_function<FunctionStringMd5AndSM3<MD5Sum>>();
     factory.register_function<FunctionSubstringIndex>();
     factory.register_function<FunctionExtractURLParameter>();
     factory.register_function<FunctionStringParseUrl>();
@@ -980,7 +979,10 @@ void register_function_string(SimpleFunctionFactory& 
factory) {
     factory.register_function<FunctionMoneyFormat<MoneyFormatInt64Impl>>();
     factory.register_function<FunctionMoneyFormat<MoneyFormatInt128Impl>>();
     factory.register_function<FunctionMoneyFormat<MoneyFormatDecimalImpl>>();
-    factory.register_function<FunctionStringMd5AndSM3<SM3Sum>>();
+    factory.register_function<FunctionStringDigestOneArg<SM3Sum>>();
+    factory.register_function<FunctionStringDigestOneArg<MD5Sum>>();
+    factory.register_function<FunctionStringDigestSHA1>();
+    factory.register_function<FunctionStringDigestSHA2>();
     factory.register_function<FunctionReplace>();
     factory.register_function<FunctionMask>();
     factory.register_function<FunctionMaskPartial<true>>();
@@ -993,9 +995,10 @@ void register_function_string(SimpleFunctionFactory& 
factory) {
     factory.register_alias(SubstringUtil::name, "substr");
     factory.register_alias(FunctionToLower::name, "lcase");
     factory.register_alias(FunctionToUpper::name, "ucase");
-    factory.register_alias(FunctionStringMd5AndSM3<MD5Sum>::name, "md5");
+    factory.register_alias(FunctionStringDigestOneArg<MD5Sum>::name, "md5");
     factory.register_alias(FunctionStringUTF8Length::name, "character_length");
-    factory.register_alias(FunctionStringMd5AndSM3<SM3Sum>::name, "sm3");
+    factory.register_alias(FunctionStringDigestOneArg<SM3Sum>::name, "sm3");
+    factory.register_alias(FunctionStringDigestSHA1::name, "sha");
 
     /// @TEMPORARY: for be_exec_version=2
     factory.register_alternative_function<FunctionStringEltOld>();
diff --git a/be/src/vec/functions/function_string.h 
b/be/src/vec/functions/function_string.h
index 32e373ffa05..37a21a3ea5b 100644
--- a/be/src/vec/functions/function_string.h
+++ b/be/src/vec/functions/function_string.h
@@ -41,6 +41,7 @@
 #include "runtime/decimalv2_value.h"
 #include "runtime/runtime_state.h"
 #include "runtime/string_search.hpp"
+#include "util/sha.h"
 #include "util/string_util.h"
 #include "util/utf8_check.h"
 #include "vec/aggregate_functions/aggregate_function.h"
@@ -1980,10 +1981,10 @@ struct MD5Sum {
 };
 
 template <typename Impl>
-class FunctionStringMd5AndSM3 : public IFunction {
+class FunctionStringDigestOneArg : public IFunction {
 public:
     static constexpr auto name = Impl::name;
-    static FunctionPtr create() { return 
std::make_shared<FunctionStringMd5AndSM3>(); }
+    static FunctionPtr create() { return 
std::make_shared<FunctionStringDigestOneArg>(); }
     String get_name() const override { return name; }
     size_t get_number_of_arguments() const override { return 0; }
     bool is_variadic() const override { return true; }
@@ -1991,7 +1992,6 @@ public:
     DataTypePtr get_return_type_impl(const DataTypes& arguments) const 
override {
         return std::make_shared<DataTypeString>();
     }
-    bool use_default_implementation_for_nulls() const override { return true; }
 
     Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
                         size_t result, size_t input_rows_count) override {
@@ -2045,6 +2045,107 @@ public:
     }
 };
 
+class FunctionStringDigestSHA1 : public IFunction {
+public:
+    static constexpr auto name = "sha1";
+    static FunctionPtr create() { return 
std::make_shared<FunctionStringDigestSHA1>(); }
+    String get_name() const override { return name; }
+    size_t get_number_of_arguments() const override { return 1; }
+    bool is_variadic() const override { return true; }
+
+    DataTypePtr get_return_type_impl(const DataTypes& arguments) const 
override {
+        return std::make_shared<DataTypeString>();
+    }
+
+    Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
+                        size_t result, size_t input_rows_count) override {
+        DCHECK_EQ(arguments.size(), 1);
+
+        ColumnPtr str_col = block.get_by_position(arguments[0]).column;
+        auto& data = assert_cast<const 
ColumnString*>(str_col.get())->get_chars();
+        auto& offset = assert_cast<const 
ColumnString*>(str_col.get())->get_offsets();
+
+        auto res_col = ColumnString::create();
+        auto& res_data = res_col->get_chars();
+        auto& res_offset = res_col->get_offsets();
+        res_offset.resize(input_rows_count);
+
+        SHA1Digest digest;
+        for (size_t i = 0; i < input_rows_count; ++i) {
+            int size = offset[i] - offset[i - 1];
+            digest.reset(&data[offset[i - 1]], size);
+            std::string_view ans = digest.digest();
+
+            StringOP::push_value_string(ans, i, res_data, res_offset);
+        }
+
+        block.replace_by_position(result, std::move(res_col));
+        return Status::OK();
+    }
+};
+
+class FunctionStringDigestSHA2 : public IFunction {
+public:
+    static constexpr auto name = "sha2";
+    static FunctionPtr create() { return 
std::make_shared<FunctionStringDigestSHA2>(); }
+    String get_name() const override { return name; }
+    size_t get_number_of_arguments() const override { return 2; }
+    bool is_variadic() const override { return true; }
+
+    DataTypePtr get_return_type_impl(const DataTypes& arguments) const 
override {
+        return std::make_shared<DataTypeString>();
+    }
+
+    Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
+                        size_t result, size_t input_rows_count) override {
+        DCHECK(!is_column_const(*block.get_by_position(arguments[0]).column));
+
+        ColumnPtr str_col = block.get_by_position(arguments[0]).column;
+        auto& data = assert_cast<const 
ColumnString*>(str_col.get())->get_chars();
+        auto& offset = assert_cast<const 
ColumnString*>(str_col.get())->get_offsets();
+
+        [[maybe_unused]] const auto& [right_column, right_const] =
+                unpack_if_const(block.get_by_position(arguments[1]).column);
+        auto digest_length = assert_cast<const 
ColumnInt32*>(right_column.get())->get_data()[0];
+
+        auto res_col = ColumnString::create();
+        auto& res_data = res_col->get_chars();
+        auto& res_offset = res_col->get_offsets();
+        res_offset.resize(input_rows_count);
+
+        if (digest_length == 224) {
+            execute_base<SHA224Digest>(data, offset, input_rows_count, 
res_data, res_offset);
+        } else if (digest_length == 256) {
+            execute_base<SHA256Digest>(data, offset, input_rows_count, 
res_data, res_offset);
+        } else if (digest_length == 384) {
+            execute_base<SHA384Digest>(data, offset, input_rows_count, 
res_data, res_offset);
+        } else if (digest_length == 512) {
+            execute_base<SHA512Digest>(data, offset, input_rows_count, 
res_data, res_offset);
+        } else {
+            return Status::InvalidArgument(
+                    "sha2's digest length only support 224/256/384/512 but 
meet {}", digest_length);
+        }
+
+        block.replace_by_position(result, std::move(res_col));
+        return Status::OK();
+    }
+
+private:
+    template <typename T>
+    void execute_base(const ColumnString::Chars& data, const 
ColumnString::Offsets& offset,
+                      int input_rows_count, ColumnString::Chars& res_data,
+                      ColumnString::Offsets& res_offset) {
+        T digest;
+        for (size_t i = 0; i < input_rows_count; ++i) {
+            int size = offset[i] - offset[i - 1];
+            digest.reset(&data[offset[i - 1]], size);
+            std::string_view ans = digest.digest();
+
+            StringOP::push_value_string(ans, i, res_data, res_offset);
+        }
+    }
+};
+
 class FunctionExtractURLParameter : public IFunction {
 public:
     static constexpr auto name = "extract_url_parameter";
diff --git 
a/docs/en/docs/sql-manual/sql-functions/encrypt-digest-functions/sha.md 
b/docs/en/docs/sql-manual/sql-functions/encrypt-digest-functions/sha.md
new file mode 100644
index 00000000000..8e9a4573c1c
--- /dev/null
+++ b/docs/en/docs/sql-manual/sql-functions/encrypt-digest-functions/sha.md
@@ -0,0 +1,53 @@
+---
+{
+"title": "SHA",
+"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.
+-->
+
+## SHA
+
+### description
+
+Use SHA1 to digest the message.
+
+#### Syntax
+
+`SHA(str)` or `SHA1(str)`
+
+#### Arguments
+
+- `str`: content to be encrypted
+
+### example
+
+```SQL
+mysql> select sha("123");
++------------------------------------------+
+| sha1('123')                              |
++------------------------------------------+
+| 40bd001563085fc35165329ea1ff5c5ecbdbbeef |
++------------------------------------------+
+1 row in set (0.13 sec)
+```
+
+### keywords
+
+    SHA,SHA1
diff --git 
a/docs/en/docs/sql-manual/sql-functions/encrypt-digest-functions/sha2.md 
b/docs/en/docs/sql-manual/sql-functions/encrypt-digest-functions/sha2.md
new file mode 100644
index 00000000000..2f7f838b1ff
--- /dev/null
+++ b/docs/en/docs/sql-manual/sql-functions/encrypt-digest-functions/sha2.md
@@ -0,0 +1,70 @@
+---
+{
+"title": "SHA2",
+"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.
+-->
+
+## SHA2
+
+### description
+
+Use SHA2 to digest the message.
+
+#### Syntax
+
+`SHA2(str, digest_length)`
+
+#### Arguments
+
+- `str`: content to be encrypted
+- `digest_length`: the length of the digest
+
+### example
+
+```SQL
+mysql> select sha2('abc', 224);
++----------------------------------------------------------+
+| sha2('abc', 224)                                         |
++----------------------------------------------------------+
+| 23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7 |
++----------------------------------------------------------+
+1 row in set (0.13 sec)
+
+mysql> select sha2('abc', 384);
++--------------------------------------------------------------------------------------------------+
+| sha2('abc', 384)                                                             
                    |
++--------------------------------------------------------------------------------------------------+
+| 
cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7
 |
++--------------------------------------------------------------------------------------------------+
+1 row in set (0.13 sec)
+
+mysql> select sha2(NULL, 512);
++-----------------+
+| sha2(NULL, 512) |
++-----------------+
+| NULL            |
++-----------------+
+1 row in set (0.09 sec)
+```
+
+### keywords
+
+    SHA2
diff --git a/docs/sidebars.json b/docs/sidebars.json
index 089f0022d75..c6acf27aea3 100644
--- a/docs/sidebars.json
+++ b/docs/sidebars.json
@@ -690,7 +690,9 @@
                                 
"sql-manual/sql-functions/encrypt-digest-functions/md5sum",
                                 
"sql-manual/sql-functions/encrypt-digest-functions/sm4",
                                 
"sql-manual/sql-functions/encrypt-digest-functions/sm3",
-                                
"sql-manual/sql-functions/encrypt-digest-functions/sm3sum"
+                                
"sql-manual/sql-functions/encrypt-digest-functions/sm3sum",
+                                
"sql-manual/sql-functions/encrypt-digest-functions/sha",
+                                
"sql-manual/sql-functions/encrypt-digest-functions/sha2"
                             ]
                         },
                         {
diff --git 
a/docs/zh-CN/docs/sql-manual/sql-functions/encrypt-digest-functions/sha.md 
b/docs/zh-CN/docs/sql-manual/sql-functions/encrypt-digest-functions/sha.md
new file mode 100644
index 00000000000..1d0f4d59324
--- /dev/null
+++ b/docs/zh-CN/docs/sql-manual/sql-functions/encrypt-digest-functions/sha.md
@@ -0,0 +1,54 @@
+---
+{
+"title": "SHA",
+"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.
+-->
+
+## SHA
+
+### description
+
+使用SHA1算法对信息进行摘要处理。
+
+#### Syntax
+
+`SHA(str)` 或 `SHA1(str)`
+
+#### Arguments
+
+- `str`: 待加密的内容
+
+### example
+
+```SQL
+mysql> select sha("123");
++------------------------------------------+
+| sha1('123')                              |
++------------------------------------------+
+| 40bd001563085fc35165329ea1ff5c5ecbdbbeef |
++------------------------------------------+
+1 row in set (0.13 sec)
+```
+
+### keywords
+
+    SHA,SHA1
+
diff --git 
a/docs/zh-CN/docs/sql-manual/sql-functions/encrypt-digest-functions/sha2.md 
b/docs/zh-CN/docs/sql-manual/sql-functions/encrypt-digest-functions/sha2.md
new file mode 100644
index 00000000000..f4a55f31724
--- /dev/null
+++ b/docs/zh-CN/docs/sql-manual/sql-functions/encrypt-digest-functions/sha2.md
@@ -0,0 +1,70 @@
+---
+{
+"title": "SHA2",
+"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.
+-->
+
+## SHA2
+
+### description
+
+使用SHA2对信息进行摘要处理。
+
+#### Syntax
+
+`SHA2(str, digest_length)`
+
+#### Arguments
+
+- `str`: 待加密的内容
+- `digest_length`: 摘要长度
+
+### example
+
+```SQL
+mysql> select sha2('abc', 224);
++----------------------------------------------------------+
+| sha2('abc', 224)                                         |
++----------------------------------------------------------+
+| 23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7 |
++----------------------------------------------------------+
+1 row in set (0.13 sec)
+
+mysql> select sha2('abc', 384);
++--------------------------------------------------------------------------------------------------+
+| sha2('abc', 384)                                                             
                    |
++--------------------------------------------------------------------------------------------------+
+| 
cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7
 |
++--------------------------------------------------------------------------------------------------+
+1 row in set (0.13 sec)
+
+mysql> select sha2(NULL, 512);
++-----------------+
+| sha2(NULL, 512) |
++-----------------+
+| NULL            |
++-----------------+
+1 row in set (0.09 sec)
+```
+
+### keywords
+
+    SHA2
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java
index c551250063e..e6dd768267c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java
@@ -1743,6 +1743,19 @@ public class FunctionCallExpr extends Expr {
             }
         }
 
+        if (fn.getFunctionName().getFunction().equals("sha2")) {
+            if ((children.size() != 2) || (getChild(1).isConstant() == false)
+                    || !(getChild(1) instanceof IntLiteral)) {
+                throw new AnalysisException(
+                        fnName.getFunction() + " needs two params, and the 
second is must be a integer constant: "
+                                + this.toSql());
+            }
+            final Integer constParam = (int) ((IntLiteral) 
getChild(1)).getValue();
+            if (!Lists.newArrayList(224, 256, 384, 512).contains(constParam)) {
+                throw new AnalysisException("sha2 functions only support 
digest length of 224/256/384/512");
+            }
+        }
+
         if (isAggregateFunction()) {
             final String functionName = fnName.getFunction();
             // subexprs must not contain aggregates
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 71647def182..e87f1ebaa96 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
@@ -281,6 +281,8 @@ import 
org.apache.doris.nereids.trees.expressions.functions.scalar.SecondTimesta
 import org.apache.doris.nereids.trees.expressions.functions.scalar.SecondsAdd;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.SecondsDiff;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.SecondsSub;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.Sha1;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.Sha2;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Sign;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Sin;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Size;
@@ -644,6 +646,8 @@ public class BuiltinScalarFunctions implements 
FunctionHelper {
             scalar(SecondTimestamp.class, "second_timestamp"),
             scalar(MilliSecondTimestamp.class, "millisecond_timestamp"),
             scalar(MicroSecondTimestamp.class, "microsecond_timestamp"),
+            scalar(Sha1.class, "sha1", "sha"),
+            scalar(Sha2.class, "sha2"),
             scalar(Sign.class, "sign"),
             scalar(Sin.class, "sin"),
             scalar(Size.class, "size"),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Sha1.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Sha1.java
new file mode 100644
index 00000000000..b405e544086
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Sha1.java
@@ -0,0 +1,68 @@
+// 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.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 'sha1'. This class is not generated by GenerateFunction.
+ */
+public class Sha1 extends ScalarFunction
+        implements ExplicitlyCastableSignature, PropagateNullable {
+
+    public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(VarcharType.SYSTEM_DEFAULT),
+            
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(StringType.INSTANCE));
+
+    /**
+     * constructor with 1 arguments.
+     */
+    public Sha1(Expression arg0) {
+        super("sha1", arg0);
+    }
+
+    /**
+     * withChildren.
+     */
+    @Override
+    public Sha1 withChildren(List<Expression> children) {
+        Preconditions.checkArgument(children.size() == 1);
+        return new Sha1(children.get(0));
+    }
+
+    @Override
+    public List<FunctionSignature> getSignatures() {
+        return SIGNATURES;
+    }
+
+    @Override
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitSha1(this, context);
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Sha2.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Sha2.java
new file mode 100644
index 00000000000..2b37e66943d
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Sha2.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.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.IntegerType;
+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 'sha2'. This class is not generated by GenerateFunction.
+ */
+public class Sha2 extends ScalarFunction
+        implements ExplicitlyCastableSignature, PropagateNullable {
+
+    public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(VarcharType.SYSTEM_DEFAULT,
 IntegerType.INSTANCE),
+            
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(StringType.INSTANCE, 
IntegerType.INSTANCE));
+
+    /**
+     * constructor with 2 arguments.
+     */
+    public Sha2(Expression arg0, Expression arg1) {
+        super("sha2", arg0, arg1);
+    }
+
+    /**
+     * withChildren.
+     */
+    @Override
+    public Sha2 withChildren(List<Expression> children) {
+        Preconditions.checkArgument(children.size() == 2);
+        return new Sha2(children.get(0), children.get(1));
+    }
+
+    @Override
+    public List<FunctionSignature> getSignatures() {
+        return SIGNATURES;
+    }
+
+    @Override
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitSha2(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 75f1ea6ae31..5a12d755c50 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
@@ -276,6 +276,8 @@ import 
org.apache.doris.nereids.trees.expressions.functions.scalar.SecondFloor;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.SecondsAdd;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.SecondsDiff;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.SecondsSub;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.Sha1;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.Sha2;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Sign;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Sin;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Size;
@@ -1396,6 +1398,14 @@ public interface ScalarFunctionVisitor<R, C> {
         return visitScalarFunction(secondsDiff, context);
     }
 
+    default R visitSha1(Sha1 sha1, C context) {
+        return visitScalarFunction(sha1, context);
+    }
+
+    default R visitSha2(Sha2 sha2, C context) {
+        return visitScalarFunction(sha2, context);
+    }
+
     default R visitMilliSecondsDiff(MilliSecondsDiff milliSecondsDiff, C 
context) {
         return visitScalarFunction(milliSecondsDiff, context);
     }
diff --git a/gensrc/script/doris_builtins_functions.py 
b/gensrc/script/doris_builtins_functions.py
index 8e5ed56d0ff..f9b1c883313 100644
--- a/gensrc/script/doris_builtins_functions.py
+++ b/gensrc/script/doris_builtins_functions.py
@@ -1895,6 +1895,13 @@ visible_functions = {
         [['sm3sum'], 'VARCHAR', ['VARCHAR', '...'], ''],
         [['sm3'], 'VARCHAR', ['STRING'], ''],
         [['sm3sum'], 'VARCHAR', ['STRING', '...'], ''],
+
+        [['sha'], 'VARCHAR', ['VARCHAR'], ''],
+        [['sha'], 'VARCHAR', ['STRING'], ''],
+        [['sha1'], 'VARCHAR', ['VARCHAR'], ''],
+        [['sha1'], 'VARCHAR', ['STRING'], ''],
+        [['sha2'], 'VARCHAR', ['VARCHAR', 'INT'], ''],
+        [['sha2'], 'VARCHAR', ['STRING', 'INT'], ''],
     ],
 
     # geo functions
diff --git 
a/regression-test/data/query_p0/sql_functions/encryption_digest/test_digest.out 
b/regression-test/data/query_p0/sql_functions/encryption_digest/test_digest.out
new file mode 100644
index 00000000000..56d37cf1ea9
--- /dev/null
+++ 
b/regression-test/data/query_p0/sql_functions/encryption_digest/test_digest.out
@@ -0,0 +1,39 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !md5 --
+68934a3e9455fa72420237eb05902327
+68934a3e9455fa72420237eb05902327
+b326b5062b2f0e69046810717534cb09
+
+-- !sha1_1 --
+40bd001563085fc35165329ea1ff5c5ecbdbbeef
+
+-- !sha1_2 --
+01b61f61abb0108346025d913eba241ec600da51       
01b61f61abb0108346025d913eba241ec600da51
+e20afd4c8d2f7966348494bc4a8b3ba2406479c3       
e20afd4c8d2f7966348494bc4a8b3ba2406479c3
+ecfb6e9d7b67d81c6f4a11c6df1bd5cc7d38d21e       
ecfb6e9d7b67d81c6f4a11c6df1bd5cc7d38d21e
+
+-- !sha1_3 --
+da39a3ee5e6b4b0d3255bfef95601890afd80709
+
+-- !sha1_4 --
+\N
+
+-- !sha2_1 --
+be504c074c5a9e0a461d8dd6e1160ac8343e5d70bbd05082868e09edc9b17c50
+86aa74b42da827c630e4a3efaeb660823af67e540828576e8413e31ac95fd494
+86d137f8ee3da44ded006c55a3b6f3460121711df8a789bf146a6d2ce3995311
+
+-- !sha2_2 --
+10a699b0850fad1c219f933f821e472630eac91cc34b2e8d254b2326ab8ca025ea9fdaa1db5e7b4c1d6b84a525524f8f3100e9847e1504b199728ddf0ce3e134
+a0296b74d1f31c0ce956f793efeb003c5e987b8f4546c8a02dcadf19073ff717d86fca57bdd0f532067b4757a7d0b924bcf4c471c05f671d775bac4f00638152
+6f2c68ec336dab0e4eb4746053bd4040b181cf75a4189dff729c6ac9a8e5062440bf5b6dc0f8ae3ed8859e1aa2a55626b1ae36191c34d41362766bcac9bc2ace
+
+-- !sha2_3 --
+23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7
+
+-- !sha2_4 --
+cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7
+
+-- !sha2_5 --
+\N
+
diff --git 
a/regression-test/data/query_p0/sql_functions/encryption_digest/test_md5.out 
b/regression-test/data/query_p0/sql_functions/encryption_digest/test_md5.out
deleted file mode 100644
index 9bfed7153fa..00000000000
--- a/regression-test/data/query_p0/sql_functions/encryption_digest/test_md5.out
+++ /dev/null
@@ -1,6 +0,0 @@
--- This file is automatically generated. You should know what you did if you 
want to edit this
--- !select --
-68934a3e9455fa72420237eb05902327
-68934a3e9455fa72420237eb05902327
-b326b5062b2f0e69046810717534cb09
-
diff --git 
a/regression-test/suites/query_p0/sql_functions/encryption_digest/test_md5.groovy
 
b/regression-test/suites/query_p0/sql_functions/encryption_digest/test_digest.groovy
similarity index 53%
rename from 
regression-test/suites/query_p0/sql_functions/encryption_digest/test_md5.groovy
rename to 
regression-test/suites/query_p0/sql_functions/encryption_digest/test_digest.groovy
index 152baae5a04..ebd9bd7d1db 100644
--- 
a/regression-test/suites/query_p0/sql_functions/encryption_digest/test_md5.groovy
+++ 
b/regression-test/suites/query_p0/sql_functions/encryption_digest/test_digest.groovy
@@ -15,6 +15,21 @@
 // specific language governing permissions and limitations
 // under the License.
 
-suite("test_md5") {
-    qt_select "select md5(k6) from test_query_db.test order by k6"
+suite("test_digest") {
+    qt_md5 "select md5(k6) from test_query_db.test order by k6"
+    qt_sha1_1 "select sha1(\"123\")"
+    qt_sha1_2 "select sha(k7), sha1(k7) from test_query_db.test order by k7"
+    qt_sha1_3 "select sha1(\"\")"
+    qt_sha1_4 "select sha1(NULL)"
+    qt_sha2_1 "select sha2(k7, 256) from test_query_db.test order by k7"
+    qt_sha2_2 "select sha2(k7, 512) from test_query_db.test order by k7"
+    qt_sha2_3 "select sha2('abc', 224)"
+    qt_sha2_4 "select sha2('abc', 384)"
+    qt_sha2_5 "select sha2(NULL, 384)"
+
+    try {
+        result = sql """ select sha2("123", 255) """
+    } catch (Exception e) {
+        assertTrue(e.getMessage().contains("only support 224/256/384/512"))
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org


Reply via email to