This is an automated email from the ASF dual-hosted git repository.
lihaopeng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 81e65f4a12 [feature](function) Support SHA family functions (#24342)
81e65f4a12 is described below
commit 81e65f4a12ea20518dd0ff3d2ca204d98c2be3e3
Author: zclllyybb <[email protected]>
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 0000000000..68099ff926
--- /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 0000000000..1545dd3c03
--- /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 5812c7badb..df9f28a579 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 32e373ffa0..37a21a3ea5 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 0000000000..8e9a4573c1
--- /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 0000000000..2f7f838b1f
--- /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 d44dc08e89..5bb5d7db51 100644
--- a/docs/sidebars.json
+++ b/docs/sidebars.json
@@ -713,7 +713,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 0000000000..1d0f4d5932
--- /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 0000000000..f4a55f3172
--- /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 310c6a6d3b..a161685dde 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
@@ -1704,6 +1704,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 0666d87b71..37f534d770 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
@@ -294,6 +294,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.Sleep;
@@ -690,6 +692,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(Sleep.class, "sleep"),
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 0000000000..b405e54408
--- /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 0000000000..2b37e66943
--- /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 c15f03f2bf..b0dde6aff2 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
@@ -290,6 +290,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.Sleep;
@@ -1434,6 +1436,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 0eaa570cdf..e58df6cb15 100644
--- a/gensrc/script/doris_builtins_functions.py
+++ b/gensrc/script/doris_builtins_functions.py
@@ -1920,6 +1920,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 0000000000..56d37cf1ea
--- /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 9bfed7153f..0000000000
--- 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 152baae5a0..ebd9bd7d1d 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: [email protected]
For additional commands, e-mail: [email protected]