This is an automated email from the ASF dual-hosted git repository. yiguolei pushed a commit to branch branch-2.1 in repository https://gitbox.apache.org/repos/asf/doris.git
commit 9c4708ee742340d9a984fd00ac000dc03587eb45 Author: Guangdong Liu <liug...@gmail.com> AuthorDate: Thu Feb 29 14:41:25 2024 +0800 [function](random_bytes)add random_bytes function (#31547) SELECT random_bytes(10); random_bytes(10) | ----------------------+ 0x9b8ea00b7d1084bc5b26| --- be/src/vec/functions/function_string.cpp | 1 + be/src/vec/functions/function_string.h | 58 ++++++++++++++++++ .../string-functions/random_bytes.md} | 18 +++--- docs/sidebars.json | 1 + .../{url-decode.md => random_bytes.md} | 20 +++--- .../sql-functions/string-functions/url-decode.md | 2 +- .../doris/catalog/BuiltinScalarFunctions.java | 2 + .../expressions/functions/scalar/RandomBytes.java | 71 ++++++++++++++++++++++ .../expressions/visitor/ScalarFunctionVisitor.java | 5 ++ gensrc/script/doris_builtins_functions.py | 4 +- .../data/nereids_function_p0/scalar_function/R.out | 3 + .../nereids_function_p0/scalar_function/R.groovy | 2 + 12 files changed, 166 insertions(+), 21 deletions(-) diff --git a/be/src/vec/functions/function_string.cpp b/be/src/vec/functions/function_string.cpp index ab4ac6c86ab..ce2c94b937b 100644 --- a/be/src/vec/functions/function_string.cpp +++ b/be/src/vec/functions/function_string.cpp @@ -1116,6 +1116,7 @@ void register_function_string(SimpleFunctionFactory& factory) { factory.register_function<FunctionExtractURLParameter>(); factory.register_function<FunctionStringParseUrl>(); factory.register_function<FunctionUrlDecode>(); + factory.register_function<FunctionRandomBytes>(); factory.register_function<FunctionMoneyFormat<MoneyFormatDoubleImpl>>(); factory.register_function<FunctionMoneyFormat<MoneyFormatInt64Impl>>(); factory.register_function<FunctionMoneyFormat<MoneyFormatInt128Impl>>(); diff --git a/be/src/vec/functions/function_string.h b/be/src/vec/functions/function_string.h index f57fe6d626a..c789345743e 100644 --- a/be/src/vec/functions/function_string.h +++ b/be/src/vec/functions/function_string.h @@ -26,8 +26,11 @@ #include <array> #include <boost/iterator/iterator_facade.hpp> #include <cstddef> +#include <iomanip> #include <memory> #include <ostream> +#include <random> +#include <sstream> #include <tuple> #include <utility> #include <vector> @@ -2879,6 +2882,61 @@ public: } }; +class FunctionRandomBytes : public IFunction { +public: + static constexpr auto name = "random_bytes"; + static FunctionPtr create() { return std::make_shared<FunctionRandomBytes>(); } + String get_name() const override { return name; } + size_t get_number_of_arguments() const override { return 1; } + bool is_variadic() const override { return false; } + + 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) const override { + auto res = ColumnString::create(); + auto& res_offsets = res->get_offsets(); + auto& res_chars = res->get_chars(); + res_offsets.resize(input_rows_count); + + ColumnPtr argument_column = + block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); + const auto* length_col = check_and_get_column<ColumnInt32>(argument_column.get()); + + if (!length_col) { + return Status::InternalError("Not supported input argument type"); + } + + std::vector<uint8_t> random_bytes; + std::random_device rd; + std::mt19937 gen(rd()); + + for (size_t i = 0; i < input_rows_count; ++i) { + UInt64 length = length_col->get64(i); + random_bytes.resize(length); + + std::uniform_int_distribution<uint8_t> distribution(0, 255); + for (auto& byte : random_bytes) { + byte = distribution(gen); + } + + std::ostringstream oss; + for (const auto& byte : random_bytes) { + oss << std::setw(2) << std::setfill('0') << std::hex << static_cast<int>(byte); + } + + StringOP::push_value_string("0x" + oss.str(), i, res_chars, res_offsets); + random_bytes.clear(); + } + + block.get_by_position(result).column = std::move(res); + + return Status::OK(); + } +}; + template <typename Impl> class FunctionMoneyFormat : public IFunction { public: diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/string-functions/url-decode.md b/docs/en/docs/sql-manual/sql-functions/string-functions/random_bytes.md similarity index 67% copy from docs/zh-CN/docs/sql-manual/sql-functions/string-functions/url-decode.md copy to docs/en/docs/sql-manual/sql-functions/string-functions/random_bytes.md index 8b171bf5735..0e54641d293 100644 --- a/docs/zh-CN/docs/sql-manual/sql-functions/string-functions/url-decode.md +++ b/docs/en/docs/sql-manual/sql-functions/string-functions/random_bytes.md @@ -1,6 +1,6 @@ --- { - "title": "url_decode", + "title": "random_bytes", "language": "en" } --- @@ -24,31 +24,31 @@ specific language governing permissions and limitations under the License. --> -## url_decode +## random_bytes ### description -将URL转换为解码字符串。 +The `random_bytes` function generates a sequence of random bytes. #### Syntax ```sql -VARCHAR url_decode(VARCHAR url) +VARCHAR random_bytes(INT len) ``` ### Parameters -- url: 待解码的url。 +- len: The `random_bytes` function takes a single argument, which specifies the length of the generated random byte sequence. ### example ``` -mysql> mysql> select url_decode('https%3A%2F%2Fdoris.apache.org%2Fzh-CN%2Fdocs%2Fsql-manual%2Fsql-functions%2Fstring-functions'); +mysql> select random_bytes(7); +------------------------------------------------+ -| url_decode('https%3A%2F%2Fdoris.apache.org%2Fzh-CN%2Fdocs%2Fsql-manual%2Fsql-functions%2Fstring-functions') | +| random_bytes(7) | +------------------------------------------------+ -| https://doris.apache.org/zh-CN/docs/sql-manual/sql-functions/string-functions | +| 0x53edd97401fb6d | +------------------------------------------------+ ``` ### keywords - URL DECODE + RANDOM BYTES diff --git a/docs/sidebars.json b/docs/sidebars.json index 44f226723f1..b44a593e384 100644 --- a/docs/sidebars.json +++ b/docs/sidebars.json @@ -520,6 +520,7 @@ "sql-manual/sql-functions/string-functions/space", "sql-manual/sql-functions/string-functions/sleep", "sql-manual/sql-functions/string-functions/esquery", + "sql-manual/sql-functions/string-functions/random_bytes", { "type": "category", "label": "Search in String", diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/string-functions/url-decode.md b/docs/zh-CN/docs/sql-manual/sql-functions/string-functions/random_bytes.md similarity index 66% copy from docs/zh-CN/docs/sql-manual/sql-functions/string-functions/url-decode.md copy to docs/zh-CN/docs/sql-manual/sql-functions/string-functions/random_bytes.md index 8b171bf5735..bceb2a88244 100644 --- a/docs/zh-CN/docs/sql-manual/sql-functions/string-functions/url-decode.md +++ b/docs/zh-CN/docs/sql-manual/sql-functions/string-functions/random_bytes.md @@ -1,7 +1,7 @@ --- { - "title": "url_decode", - "language": "en" + "title": "random_bytes", + "language": "zh-CN" } --- @@ -24,31 +24,31 @@ specific language governing permissions and limitations under the License. --> -## url_decode +## random_bytes ### description -将URL转换为解码字符串。 +random_bytes函数用于生成随机字节序列。 #### Syntax ```sql -VARCHAR url_decode(VARCHAR url) +VARCHAR random_bytes(INT len) ``` ### Parameters -- url: 待解码的url。 +- len: 该参数指定生成的随机字节序列的长度。 ### example ``` -mysql> mysql> select url_decode('https%3A%2F%2Fdoris.apache.org%2Fzh-CN%2Fdocs%2Fsql-manual%2Fsql-functions%2Fstring-functions'); +mysql> select random_bytes(7); +------------------------------------------------+ -| url_decode('https%3A%2F%2Fdoris.apache.org%2Fzh-CN%2Fdocs%2Fsql-manual%2Fsql-functions%2Fstring-functions') | +| random_bytes(7) | +------------------------------------------------+ -| https://doris.apache.org/zh-CN/docs/sql-manual/sql-functions/string-functions | +| 0x53edd97401fb6d | +------------------------------------------------+ ``` ### keywords - URL DECODE + RANDOM BYTES diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/string-functions/url-decode.md b/docs/zh-CN/docs/sql-manual/sql-functions/string-functions/url-decode.md index 8b171bf5735..01fb280db48 100644 --- a/docs/zh-CN/docs/sql-manual/sql-functions/string-functions/url-decode.md +++ b/docs/zh-CN/docs/sql-manual/sql-functions/string-functions/url-decode.md @@ -1,7 +1,7 @@ --- { "title": "url_decode", - "language": "en" + "language": "zh-CN" } --- 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 33f353503ab..9d19ea9e2e9 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 @@ -318,6 +318,7 @@ import org.apache.doris.nereids.trees.expressions.functions.scalar.QuantileState import org.apache.doris.nereids.trees.expressions.functions.scalar.Quarter; import org.apache.doris.nereids.trees.expressions.functions.scalar.Radians; import org.apache.doris.nereids.trees.expressions.functions.scalar.Random; +import org.apache.doris.nereids.trees.expressions.functions.scalar.RandomBytes; import org.apache.doris.nereids.trees.expressions.functions.scalar.RegexpExtract; import org.apache.doris.nereids.trees.expressions.functions.scalar.RegexpExtractAll; import org.apache.doris.nereids.trees.expressions.functions.scalar.RegexpReplace; @@ -796,6 +797,7 @@ public class BuiltinScalarFunctions implements FunctionHelper { scalar(SecondTimestamp.class, "second_timestamp"), scalar(MilliSecondTimestamp.class, "millisecond_timestamp"), scalar(MicroSecondTimestamp.class, "microsecond_timestamp"), + scalar(RandomBytes.class, "random_bytes"), scalar(Sha1.class, "sha1", "sha"), scalar(Sha2.class, "sha2"), scalar(Sign.class, "sign"), diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/RandomBytes.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/RandomBytes.java new file mode 100644 index 00000000000..f5906670f86 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/RandomBytes.java @@ -0,0 +1,71 @@ +// 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 'random_bytes'. This class is generated by GenerateFunction. + */ +public class RandomBytes extends ScalarFunction + implements ExplicitlyCastableSignature, PropagateNullable { + + public static final List<FunctionSignature> SIGNATURES = ImmutableList.of( + FunctionSignature.ret(StringType.INSTANCE).args(IntegerType.INSTANCE), + FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(IntegerType.INSTANCE) + ); + + /** + * constructor with 1 argument. + */ + public RandomBytes(Expression arg0) { + super("random_bytes", arg0); + } + + + /** + * withChildren. + */ + @Override + public RandomBytes withChildren(List<Expression> children) { + Preconditions.checkArgument(children.size() == 1); + return new RandomBytes(children.get(0)); + } + + @Override + public List<FunctionSignature> getSignatures() { + return SIGNATURES; + } + + @Override + public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) { + return visitor.visitRandomBytes(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 7bf020ad84d..7cef47557cc 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 @@ -317,6 +317,7 @@ import org.apache.doris.nereids.trees.expressions.functions.scalar.QuantileState import org.apache.doris.nereids.trees.expressions.functions.scalar.Quarter; import org.apache.doris.nereids.trees.expressions.functions.scalar.Radians; import org.apache.doris.nereids.trees.expressions.functions.scalar.Random; +import org.apache.doris.nereids.trees.expressions.functions.scalar.RandomBytes; import org.apache.doris.nereids.trees.expressions.functions.scalar.RegexpExtract; import org.apache.doris.nereids.trees.expressions.functions.scalar.RegexpExtractAll; import org.apache.doris.nereids.trees.expressions.functions.scalar.RegexpReplace; @@ -1592,6 +1593,10 @@ public interface ScalarFunctionVisitor<R, C> { return visitScalarFunction(urlDecode, context); } + default R visitRandomBytes(RandomBytes randomBytes, C context) { + return visitScalarFunction(randomBytes, context); + } + default R visitPassword(Password password, C context) { return visitScalarFunction(password, context); } diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index 0e96d3fa756..629f83f6a13 100644 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -1612,6 +1612,7 @@ visible_functions = { [['substring_index'], 'VARCHAR', ['VARCHAR', 'VARCHAR', 'INT'], 'DEPEND_ON_ARGUMENT'], [['extract_url_parameter'], 'VARCHAR', ['VARCHAR', 'VARCHAR'], ''], [['url_decode'], 'VARCHAR', ['VARCHAR'], ''], + [['random_bytes'], 'VARCHAR', ['INT'], ''], [['sub_replace'], 'VARCHAR', ['VARCHAR', 'VARCHAR', 'INT'], 'ALWAYS_NULLABLE'], [['sub_replace'], 'VARCHAR', ['VARCHAR', 'VARCHAR', 'INT', 'INT'], 'ALWAYS_NULLABLE'], @@ -1666,7 +1667,8 @@ visible_functions = { [['money_format'], 'STRING', ['DECIMAL128'], ''], [['split_part'], 'STRING', ['STRING', 'STRING', 'INT'], 'ALWAYS_NULLABLE'], [['substring_index'], 'STRING', ['STRING', 'STRING', 'INT'], 'DEPEND_ON_ARGUMENT'], - [['url_decode'], 'STRING', ['STRING'], ''] + [['url_decode'], 'STRING', ['STRING'], ''], + [['random_bytes'], 'STRING', ['INT'], ''] ], diff --git a/regression-test/data/nereids_function_p0/scalar_function/R.out b/regression-test/data/nereids_function_p0/scalar_function/R.out index 1aaff36e65b..7b8252223ad 100644 --- a/regression-test/data/nereids_function_p0/scalar_function/R.out +++ b/regression-test/data/nereids_function_p0/scalar_function/R.out @@ -1101,3 +1101,6 @@ string3 string3 string3 +-- !sql_random_bytes -- +\N + diff --git a/regression-test/suites/nereids_function_p0/scalar_function/R.groovy b/regression-test/suites/nereids_function_p0/scalar_function/R.groovy index 597841acdec..fa58e6d0cb2 100644 --- a/regression-test/suites/nereids_function_p0/scalar_function/R.groovy +++ b/regression-test/suites/nereids_function_p0/scalar_function/R.groovy @@ -99,4 +99,6 @@ suite("nereids_scalar_fn_R") { qt_sql_rtrim_Varchar_Varchar_notnull "select rtrim(kvchrs1, '1') from fn_test_not_nullable order by kvchrs1" qt_sql_rtrim_String_String "select rtrim(kstr, '1') from fn_test order by kstr" qt_sql_rtrim_String_String_notnull "select rtrim(kstr, '1') from fn_test_not_nullable order by kstr" + sql "SELECT random_bytes(7);" + qt_sql_random_bytes "SELECT random_bytes(null);" } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org