[feature](function) Support SHA family functions (#24342)

This commit is contained in:
zclllyybb
2023-09-20 17:21:45 +08:00
committed by GitHub
parent 5eb8fe3d6e
commit 81e65f4a12
18 changed files with 781 additions and 16 deletions

118
be/src/util/sha.cpp Normal file
View File

@ -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

75
be/src/util/sha.h Normal file
View File

@ -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

View File

@ -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>();

View File

@ -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";

View File

@ -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

View File

@ -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

View File

@ -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"
]
},
{

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"),

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"))
}
}