This is an automated email from the ASF dual-hosted git repository. morningman pushed a commit to branch dev-1.0.1 in repository https://gitbox.apache.org/repos/asf/incubator-doris.git
commit 6c0e78bac939a3933b2047bbde14210a83dd953c Author: Pxl <[email protected]> AuthorDate: Tue Mar 22 11:38:00 2022 +0800 [feature][vectorized] support table function explode_numbers() (#8509) --- .../exprs/table_function/dummy_table_functions.cpp | 14 ++-- .../exprs/table_function/dummy_table_functions.h | 18 +++-- be/src/exprs/table_function/explode_bitmap.cpp | 22 ++---- be/src/exprs/table_function/explode_bitmap.h | 5 -- be/src/exprs/table_function/explode_json_array.cpp | 29 -------- be/src/exprs/table_function/explode_json_array.h | 4 - be/src/exprs/table_function/explode_split.cpp | 25 ------- be/src/exprs/table_function/explode_split.h | 4 - be/src/exprs/table_function/table_function.h | 30 ++++++-- .../table_function/table_function_factory.cpp | 6 +- be/src/vec/CMakeLists.txt | 1 + .../vec/exprs/table_function/vexplode_numbers.cpp | 87 ++++++++++++++++++++++ .../{vexplode_split.h => vexplode_numbers.h} | 21 ++---- be/src/vec/exprs/table_function/vexplode_split.cpp | 4 +- be/src/vec/exprs/table_function/vexplode_split.h | 8 +- be/src/vec/functions/function_fake.cpp | 1 + be/src/vec/functions/function_fake.h | 7 ++ docs/.vuepress/sidebar/en.js | 3 +- docs/.vuepress/sidebar/zh-CN.js | 3 +- .../table-functions/explode-numbers.md | 56 ++++++++++++++ .../table-functions/explode-numbers.md | 57 ++++++++++++++ .../apache/doris/analysis/FunctionCallExpr.java | 7 +- .../java/org/apache/doris/catalog/FunctionSet.java | 9 +++ 23 files changed, 292 insertions(+), 129 deletions(-) diff --git a/be/src/exprs/table_function/dummy_table_functions.cpp b/be/src/exprs/table_function/dummy_table_functions.cpp index bb64100..40923bf 100644 --- a/be/src/exprs/table_function/dummy_table_functions.cpp +++ b/be/src/exprs/table_function/dummy_table_functions.cpp @@ -22,28 +22,32 @@ namespace doris { void DummyTableFunctions::init() {} StringVal DummyTableFunctions::explode_split(FunctionContext* context, const StringVal& str, - const StringVal& sep) { + const StringVal& sep) { return StringVal(); } BigIntVal DummyTableFunctions::explode_bitmap(doris_udf::FunctionContext* context, - const doris_udf::StringVal& bitmap) { + const doris_udf::StringVal& bitmap) { return BigIntVal(); } BigIntVal DummyTableFunctions::explode_json_array_int(doris_udf::FunctionContext* context, - const doris_udf::StringVal& str) { + const doris_udf::StringVal& str) { return BigIntVal(); } DoubleVal DummyTableFunctions::explode_json_array_double(doris_udf::FunctionContext* context, - const doris_udf::StringVal& str) { + const doris_udf::StringVal& str) { return DoubleVal(); } StringVal DummyTableFunctions::explode_json_array_string(doris_udf::FunctionContext* context, - const doris_udf::StringVal& str) { + const doris_udf::StringVal& str) { return StringVal(); } +IntVal DummyTableFunctions::explode_numbers(doris_udf::FunctionContext* context, + const doris_udf::IntVal& str) { + return IntVal(); +} } // namespace doris diff --git a/be/src/exprs/table_function/dummy_table_functions.h b/be/src/exprs/table_function/dummy_table_functions.h index 4723a52..9fde65c 100644 --- a/be/src/exprs/table_function/dummy_table_functions.h +++ b/be/src/exprs/table_function/dummy_table_functions.h @@ -18,11 +18,12 @@ #pragma once #include "exprs/anyval_util.h" +#include "udf/udf.h" namespace doris { // Currently Doris does not support array types, so the definition of table function -// is still using the definition of the scalar function. +// is still using the definition of the scalar function. // The definition here is just to facilitate the query planning stage and the query execution preparation stage // to make smooth use of the existing function framework // But the execution logic of the table function is not here. So the function names here are prefixed with "dummy". @@ -32,16 +33,17 @@ public: static void init(); static doris_udf::StringVal explode_split(doris_udf::FunctionContext* context, - const doris_udf::StringVal& str, - const doris_udf::StringVal& sep); + const doris_udf::StringVal& str, + const doris_udf::StringVal& sep); static doris_udf::BigIntVal explode_bitmap(doris_udf::FunctionContext* context, - const doris_udf::StringVal& bitmap); + const doris_udf::StringVal& bitmap); static doris_udf::BigIntVal explode_json_array_int(doris_udf::FunctionContext* context, - const doris_udf::StringVal& str); + const doris_udf::StringVal& str); static doris_udf::DoubleVal explode_json_array_double(doris_udf::FunctionContext* context, - const doris_udf::StringVal& str); + const doris_udf::StringVal& str); static doris_udf::StringVal explode_json_array_string(doris_udf::FunctionContext* context, - const doris_udf::StringVal& str); + const doris_udf::StringVal& str); + static doris_udf::IntVal explode_numbers(doris_udf::FunctionContext* context, + const doris_udf::IntVal& value); }; } // namespace doris - diff --git a/be/src/exprs/table_function/explode_bitmap.cpp b/be/src/exprs/table_function/explode_bitmap.cpp index 3b5518b..3ffac5f 100644 --- a/be/src/exprs/table_function/explode_bitmap.cpp +++ b/be/src/exprs/table_function/explode_bitmap.cpp @@ -37,30 +37,24 @@ ExplodeBitmapTableFunction::~ExplodeBitmapTableFunction() { } } -Status ExplodeBitmapTableFunction::prepare() { - return Status::OK(); -} - -Status ExplodeBitmapTableFunction::open() { - return Status::OK(); -} - Status ExplodeBitmapTableFunction::process(TupleRow* tuple_row) { - CHECK(1 == _expr_context->root()->get_num_children()) << _expr_context->root()->get_num_children(); + CHECK(1 == _expr_context->root()->get_num_children()) + << _expr_context->root()->get_num_children(); _eos = false; _is_current_empty = false; _cur_size = 0; _cur_offset = 0; - StringVal bitmap_str = _expr_context->root()->get_child(0)->get_string_val(_expr_context, tuple_row); + StringVal bitmap_str = + _expr_context->root()->get_child(0)->get_string_val(_expr_context, tuple_row); if (bitmap_str.is_null) { - _is_current_empty = true; + _is_current_empty = true; } else { if (bitmap_str.len == 0) { _cur_bitmap = reinterpret_cast<BitmapValue*>(bitmap_str.ptr); _cur_bitmap_owned = false; } else { - _cur_bitmap = new BitmapValue((char*) bitmap_str.ptr); + _cur_bitmap = new BitmapValue((char*)bitmap_str.ptr); _cur_bitmap_owned = true; } _cur_size = _cur_bitmap->cardinality(); @@ -102,10 +96,6 @@ Status ExplodeBitmapTableFunction::get_value(void** output) { return Status::OK(); } -Status ExplodeBitmapTableFunction::close() { - return Status::OK(); -} - Status ExplodeBitmapTableFunction::forward(bool* eos) { if (_is_current_empty) { *eos = true; diff --git a/be/src/exprs/table_function/explode_bitmap.h b/be/src/exprs/table_function/explode_bitmap.h index b491eea..2abb160 100644 --- a/be/src/exprs/table_function/explode_bitmap.h +++ b/be/src/exprs/table_function/explode_bitmap.h @@ -18,7 +18,6 @@ #pragma once #include "exprs/table_function/table_function.h" - #include "util/bitmap_value.h" namespace doris { @@ -28,12 +27,9 @@ public: ExplodeBitmapTableFunction(); virtual ~ExplodeBitmapTableFunction(); - virtual Status prepare() override; - virtual Status open() override; virtual Status process(TupleRow* tuple_row) override; virtual Status reset() override; virtual Status get_value(void** output) override; - virtual Status close() override; virtual Status forward(bool* eos) override; @@ -41,7 +37,6 @@ private: void _reset_iterator(); private: - // Read from tuple row. // if _cur_bitmap_owned is true, need to delete it when deconstruction BitmapValue* _cur_bitmap = nullptr; diff --git a/be/src/exprs/table_function/explode_json_array.cpp b/be/src/exprs/table_function/explode_json_array.cpp index 59db64e..fa8cf21 100644 --- a/be/src/exprs/table_function/explode_json_array.cpp +++ b/be/src/exprs/table_function/explode_json_array.cpp @@ -147,14 +147,6 @@ ExplodeJsonArrayTableFunction::ExplodeJsonArrayTableFunction(ExplodeJsonArrayTyp ExplodeJsonArrayTableFunction::~ExplodeJsonArrayTableFunction() { } -Status ExplodeJsonArrayTableFunction::prepare() { - return Status::OK(); -} - -Status ExplodeJsonArrayTableFunction::open() { - return Status::OK(); -} - Status ExplodeJsonArrayTableFunction::process(TupleRow* tuple_row) { CHECK(1 == _expr_context->root()->get_num_children()) << _expr_context->root()->get_num_children(); _is_current_empty = false; @@ -197,25 +189,4 @@ Status ExplodeJsonArrayTableFunction::get_value(void** output) { } return Status::OK(); } - -Status ExplodeJsonArrayTableFunction::close() { - return Status::OK(); -} - -Status ExplodeJsonArrayTableFunction::forward(bool* eos) { - if (_is_current_empty) { - *eos = true; - _eos = true; - } else { - ++_cur_offset; - if (_cur_offset == _cur_size) { - *eos = true; - _eos = true; - } else { - *eos = false; - } - } - return Status::OK(); -} - } // namespace doris diff --git a/be/src/exprs/table_function/explode_json_array.h b/be/src/exprs/table_function/explode_json_array.h index 8ecbd2d..2ebeea4 100644 --- a/be/src/exprs/table_function/explode_json_array.h +++ b/be/src/exprs/table_function/explode_json_array.h @@ -109,13 +109,9 @@ public: ExplodeJsonArrayTableFunction(ExplodeJsonArrayType type); virtual ~ExplodeJsonArrayTableFunction(); - virtual Status prepare() override; - virtual Status open() override; virtual Status process(TupleRow* tuple_row) override; virtual Status reset() override; virtual Status get_value(void** output) override; - virtual Status close() override; - virtual Status forward(bool* eos) override; private: void _set_null_output(); diff --git a/be/src/exprs/table_function/explode_split.cpp b/be/src/exprs/table_function/explode_split.cpp index 21defd3..0c704a6 100644 --- a/be/src/exprs/table_function/explode_split.cpp +++ b/be/src/exprs/table_function/explode_split.cpp @@ -29,10 +29,6 @@ ExplodeSplitTableFunction::ExplodeSplitTableFunction() { ExplodeSplitTableFunction::~ExplodeSplitTableFunction() {} -Status ExplodeSplitTableFunction::prepare() { - return Status::OK(); -} - Status ExplodeSplitTableFunction::open() { ScalarFnCall* fn_call = reinterpret_cast<ScalarFnCall*>(_expr_context->root()); FunctionContext* fn_ctx = _expr_context->fn_context(fn_call->get_fn_context_index()); @@ -94,25 +90,4 @@ Status ExplodeSplitTableFunction::get_value(void** output) { } return Status::OK(); } - -Status ExplodeSplitTableFunction::close() { - return Status::OK(); -} - -Status ExplodeSplitTableFunction::forward(bool* eos) { - if (_is_current_empty) { - *eos = true; - _eos = true; - } else { - ++_cur_offset; - if (_cur_offset == _cur_size) { - *eos = true; - _eos = true; - } else { - *eos = false; - } - } - return Status::OK(); -} - } // namespace doris diff --git a/be/src/exprs/table_function/explode_split.h b/be/src/exprs/table_function/explode_split.h index b8d1e2b..0fea203 100644 --- a/be/src/exprs/table_function/explode_split.h +++ b/be/src/exprs/table_function/explode_split.h @@ -28,14 +28,10 @@ public: ExplodeSplitTableFunction(); virtual ~ExplodeSplitTableFunction(); - virtual Status prepare() override; virtual Status open() override; virtual Status process(TupleRow* tuple_row) override; virtual Status reset() override; virtual Status get_value(void** output) override; - virtual Status close() override; - - virtual Status forward(bool* eos) override; protected: // The string value splitted from source, and will be referenced by diff --git a/be/src/exprs/table_function/table_function.h b/be/src/exprs/table_function/table_function.h index 0aa6951..c431d36 100644 --- a/be/src/exprs/table_function/table_function.h +++ b/be/src/exprs/table_function/table_function.h @@ -36,10 +36,13 @@ class TableFunction { public: virtual ~TableFunction() {} - virtual Status prepare() = 0; - virtual Status open() = 0; + virtual Status prepare() { return Status::OK(); } - virtual Status process(TupleRow* tuple_row) = 0; + virtual Status open() { return Status::OK(); } + + virtual Status process(TupleRow* tuple_row) { + return Status::NotSupported(fmt::format("table function {} not supported now.", _fn_name)); + } // only used for vectorized. virtual Status process_init(vectorized::Block* block) { @@ -69,11 +72,24 @@ public: return Status::OK(); } - virtual Status close() = 0; - - virtual Status forward(bool* eos) = 0; + virtual Status close() { return Status::OK(); } + + virtual Status forward(bool* eos) { + if (_is_current_empty) { + *eos = true; + _eos = true; + } else { + ++_cur_offset; + if (_cur_offset == _cur_size) { + *eos = true; + _eos = true; + } else { + *eos = false; + } + } + return Status::OK(); + } -public: std::string name() const { return _fn_name; } bool eos() const { return _eos; } diff --git a/be/src/exprs/table_function/table_function_factory.cpp b/be/src/exprs/table_function/table_function_factory.cpp index 4cdf267..d0c3954 100644 --- a/be/src/exprs/table_function/table_function_factory.cpp +++ b/be/src/exprs/table_function/table_function_factory.cpp @@ -22,6 +22,7 @@ #include "exprs/table_function/explode_json_array.h" #include "exprs/table_function/explode_split.h" #include "exprs/table_function/table_function.h" +#include "vec/exprs/table_function/vexplode_numbers.h" #include "vec/exprs/table_function/vexplode_split.h" namespace doris { @@ -52,7 +53,10 @@ const std::unordered_map<std::pair<std::string, bool>, std::function<TableFuncti {{"explode_json_array_int", false}, ExplodeJsonArrayIntCreator}, {{"explode_json_array_double", false}, ExplodeJsonArrayDoubleCreator}, {{"explode_json_array_string", false}, ExplodeJsonArrayStringCreator}, - {{"explode_split", true}, TableFunctionCreator<VExplodeSplitTableFunction>()}}; + {{"explode_split", true}, + TableFunctionCreator<vectorized::VExplodeSplitTableFunction>()}, + {{"explode_numbers", true}, + TableFunctionCreator<vectorized::VExplodeNumbersTableFunction>()}}; Status TableFunctionFactory::get_fn(const std::string& fn_name, bool is_vectorized, ObjectPool* pool, TableFunction** fn) { diff --git a/be/src/vec/CMakeLists.txt b/be/src/vec/CMakeLists.txt index 9a58191..7459bdc 100644 --- a/be/src/vec/CMakeLists.txt +++ b/be/src/vec/CMakeLists.txt @@ -106,6 +106,7 @@ set(VEC_FILES exprs/vcase_expr.cpp exprs/vinfo_func.cpp exprs/table_function/vexplode_split.cpp + exprs/table_function/vexplode_numbers.cpp functions/math.cpp functions/function_bitmap.cpp functions/function_bitmap_variadic.cpp diff --git a/be/src/vec/exprs/table_function/vexplode_numbers.cpp b/be/src/vec/exprs/table_function/vexplode_numbers.cpp new file mode 100644 index 0000000..540c7ac --- /dev/null +++ b/be/src/vec/exprs/table_function/vexplode_numbers.cpp @@ -0,0 +1,87 @@ +// 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 "vec/exprs/table_function/vexplode_numbers.h" + +#include "vec/exprs/vexpr.h" + +namespace doris::vectorized { + +VExplodeNumbersTableFunction::VExplodeNumbersTableFunction() { + _fn_name = "vexplode_numbers"; +} + +Status VExplodeNumbersTableFunction::process_init(vectorized::Block* block) { + CHECK(_vexpr_context->root()->children().size() == 1) + << "VExplodeSplitTableFunction must be have 1 children but have " + << _vexpr_context->root()->children().size(); + + int value_column_idx = -1; + _vexpr_context->root()->children()[0]->execute(_vexpr_context, block, &value_column_idx); + _value_column = block->get_by_position(value_column_idx).column; + + return Status::OK(); +} + +Status VExplodeNumbersTableFunction::process_row(size_t row_idx) { + _is_current_empty = false; + _eos = false; + + StringRef value = _value_column->get_data_at(row_idx); + + if (value.data == nullptr) { + _is_current_empty = true; + _cur_size = 0; + _cur_offset = 0; + } else { + _cur_size = *reinterpret_cast<const int*>(value.data); + _cur_offset = 0; + _is_current_empty = (_cur_size == 0); + } + return Status::OK(); +} + +Status VExplodeNumbersTableFunction::process_close() { + _value_column = nullptr; + return Status::OK(); +} + +Status VExplodeNumbersTableFunction::reset() { + _eos = false; + _cur_offset = 0; + return Status::OK(); +} + +Status VExplodeNumbersTableFunction::get_value(void** output) { + if (_is_current_empty) { + *output = nullptr; + } else { + *output = &_cur_offset; + } + return Status::OK(); +} + +Status VExplodeNumbersTableFunction::get_value_length(int64_t* length) { + if (_is_current_empty) { + *length = -1; + } else { + *length = sizeof(int); + } + return Status::OK(); +} + +} // namespace doris::vectorized diff --git a/be/src/vec/exprs/table_function/vexplode_split.h b/be/src/vec/exprs/table_function/vexplode_numbers.h similarity index 70% copy from be/src/vec/exprs/table_function/vexplode_split.h copy to be/src/vec/exprs/table_function/vexplode_numbers.h index 52ebef6..df0e25c 100644 --- a/be/src/vec/exprs/table_function/vexplode_split.h +++ b/be/src/vec/exprs/table_function/vexplode_numbers.h @@ -17,30 +17,25 @@ #pragma once -#include "exprs/table_function/explode_split.h" -#include "gutil/strings/stringpiece.h" -#include "runtime/string_value.h" +#include "exprs/table_function/table_function.h" #include "vec/columns/column.h" -namespace doris { +namespace doris::vectorized { -class VExplodeSplitTableFunction : public ExplodeSplitTableFunction { +class VExplodeNumbersTableFunction : public TableFunction { public: - VExplodeSplitTableFunction(); - virtual ~VExplodeSplitTableFunction() = default; + VExplodeNumbersTableFunction(); + virtual ~VExplodeNumbersTableFunction() = default; - virtual Status open() override; virtual Status process_init(vectorized::Block* block) override; virtual Status process_row(size_t row_idx) override; virtual Status process_close() override; + virtual Status reset() override; virtual Status get_value(void** output) override; virtual Status get_value_length(int64_t* length) override; private: - using ExplodeSplitTableFunction::process; - - vectorized::ColumnPtr _text_column; - vectorized::ColumnPtr _delimiter_column; + ColumnPtr _value_column; }; -} // namespace doris +} // namespace doris::vectorized diff --git a/be/src/vec/exprs/table_function/vexplode_split.cpp b/be/src/vec/exprs/table_function/vexplode_split.cpp index 0e2a674..1e124f5 100644 --- a/be/src/vec/exprs/table_function/vexplode_split.cpp +++ b/be/src/vec/exprs/table_function/vexplode_split.cpp @@ -22,7 +22,7 @@ #include "vec/columns/column.h" #include "vec/exprs/vexpr.h" -namespace doris { +namespace doris::vectorized { VExplodeSplitTableFunction::VExplodeSplitTableFunction() { _fn_name = "vexplode_split"; @@ -96,4 +96,4 @@ Status VExplodeSplitTableFunction::get_value_length(int64_t* length) { return Status::OK(); } -} // namespace doris +} // namespace doris::vectorized diff --git a/be/src/vec/exprs/table_function/vexplode_split.h b/be/src/vec/exprs/table_function/vexplode_split.h index 52ebef6..c7b7807 100644 --- a/be/src/vec/exprs/table_function/vexplode_split.h +++ b/be/src/vec/exprs/table_function/vexplode_split.h @@ -22,7 +22,7 @@ #include "runtime/string_value.h" #include "vec/columns/column.h" -namespace doris { +namespace doris::vectorized { class VExplodeSplitTableFunction : public ExplodeSplitTableFunction { public: @@ -39,8 +39,8 @@ public: private: using ExplodeSplitTableFunction::process; - vectorized::ColumnPtr _text_column; - vectorized::ColumnPtr _delimiter_column; + ColumnPtr _text_column; + ColumnPtr _delimiter_column; }; -} // namespace doris +} // namespace doris::vectorized diff --git a/be/src/vec/functions/function_fake.cpp b/be/src/vec/functions/function_fake.cpp index 11a186c..4eab7ab 100644 --- a/be/src/vec/functions/function_fake.cpp +++ b/be/src/vec/functions/function_fake.cpp @@ -22,6 +22,7 @@ namespace doris::vectorized { void register_function_fake(SimpleFunctionFactory& factory) { factory.register_function<FunctionFake<FunctionEsqueryImpl>>(); factory.register_function<FunctionFake<FunctionExplodeSplitImpl>>(); + factory.register_function<FunctionFake<FunctionExplodeNumbersImpl>>(); } } // namespace doris::vectorized diff --git a/be/src/vec/functions/function_fake.h b/be/src/vec/functions/function_fake.h index 8ad4776..22cd3c7 100644 --- a/be/src/vec/functions/function_fake.h +++ b/be/src/vec/functions/function_fake.h @@ -40,6 +40,13 @@ struct FunctionExplodeSplitImpl { } }; +struct FunctionExplodeNumbersImpl { + static constexpr auto name = "explode_numbers"; + static DataTypePtr get_return_type_impl(const DataTypes& arguments) { + return std::make_shared<DataTypeInt32>(); + } +}; + //FunctionFake is use for some function call expr only work at prepare/open phase, do not support execute(). template <typename Impl> class FunctionFake : public IFunction { diff --git a/docs/.vuepress/sidebar/en.js b/docs/.vuepress/sidebar/en.js index 05a9c2d..896805f 100644 --- a/docs/.vuepress/sidebar/en.js +++ b/docs/.vuepress/sidebar/en.js @@ -542,7 +542,8 @@ module.exports = [ children: [ "explode-bitmap", "explode-split", - "explode-json-array" + "explode-json-array", + "explode-numbers" ], }, "window-function", diff --git a/docs/.vuepress/sidebar/zh-CN.js b/docs/.vuepress/sidebar/zh-CN.js index 3053c2d..9aa4107 100644 --- a/docs/.vuepress/sidebar/zh-CN.js +++ b/docs/.vuepress/sidebar/zh-CN.js @@ -544,7 +544,8 @@ module.exports = [ children: [ "explode-bitmap", "explode-split", - "explode-json-array" + "explode-json-array", + "explode-numbers" ], }, "window-function", diff --git a/docs/en/sql-reference/sql-functions/table-functions/explode-numbers.md b/docs/en/sql-reference/sql-functions/table-functions/explode-numbers.md new file mode 100644 index 0000000..6d959e8 --- /dev/null +++ b/docs/en/sql-reference/sql-functions/table-functions/explode-numbers.md @@ -0,0 +1,56 @@ +--- +{ + "title": "explode_numbers", + "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. +--> + +# explode_numbers + +## description + +Table functions must be used in conjunction with Lateral View. + +Get a number sequence [0,n). + +grammar: + +``` +explode_numbers(n) +``` + +## example +``` +mysql> select e1 from (select 1 k1) as t lateral view explode_numbers(5) tmp1 as e1; ++------+ +| e1 | ++------+ +| 0 | +| 1 | +| 2 | +| 3 | +| 4 | ++------+ +``` +## keyword + + explode_numbers \ No newline at end of file diff --git a/docs/zh-CN/sql-reference/sql-functions/table-functions/explode-numbers.md b/docs/zh-CN/sql-reference/sql-functions/table-functions/explode-numbers.md new file mode 100644 index 0000000..d15799d --- /dev/null +++ b/docs/zh-CN/sql-reference/sql-functions/table-functions/explode-numbers.md @@ -0,0 +1,57 @@ +--- +{ + "title": "explode_numbers", + "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. +--> + +# explode_bitmap + +## description + +表函数,需配合 Lateral View 使用。 + +获得一个[0,n)的序列。 + +语法: + +``` +explode_numbers(n) +``` + +## example + +``` +mysql> select e1 from (select 1 k1) as t lateral view explode_numbers(5) tmp1 as e1; ++------+ +| e1 | ++------+ +| 0 | +| 1 | +| 2 | +| 3 | +| 4 | ++------+ +``` +## keyword + + explode_numbers \ No newline at end of file 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 6fa7c69..eb94fcd 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 @@ -82,15 +82,14 @@ public class FunctionCallExpr extends Expr { .add("variance").add("variance_pop").add("variance_pop").add("var_samp").add("var_pop").build(); private static final String ELEMENT_EXTRACT_FN_NAME = "%element_extract%"; - //use to record the num of json_object parameters + // use to record the num of json_object parameters private int originChildSize; // Save the functionCallExpr in the original statement private Expr originStmtFnExpr; private boolean isRewrote = false; - public static final String UNKNOWN_TABLE_FUNCTION_MSG = "Currently only support `explode_split`, `explode_bitmap` " + - "and `explode_json_array_xx` table functions"; + public static final String UNKNOWN_TABLE_FUNCTION_MSG = "This table function not supported now"; public void setIsAnalyticFnCall(boolean v) { isAnalyticFnCall = v; @@ -184,7 +183,7 @@ public class FunctionCallExpr extends Expr { StringBuilder sb = new StringBuilder(); for (int i = 0; i < children.size(); ++i) { Type type = getChild(i).getType(); - if (type.isNull()) { //Not to return NULL directly, so save string, but flag is '0' + if (type.isNull()) { // Not to return NULL directly, so save string, but flag is '0' if (((i & 1) == 0) && useKeyCheck == true) { throw new AnalysisException("json_object key can't be NULL: " + this.toSql()); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java index 33d0877..9d49cc5 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java @@ -2309,6 +2309,7 @@ public class FunctionSet<min_initIN9doris_udf12DecimalV2ValEEEvPNS2_15FunctionCo public static final String EXPLODE_JSON_ARRAY_INT = "explode_json_array_int"; public static final String EXPLODE_JSON_ARRAY_DOUBLE = "explode_json_array_double"; public static final String EXPLODE_JSON_ARRAY_STRING = "explode_json_array_string"; + public static final String EXPLODE_NUMBERS = "explode_numbers"; private void initTableFunction() { List<Function> explodeSplits = Lists.newArrayList(); @@ -2350,5 +2351,13 @@ public class FunctionSet<min_initIN9doris_udf12DecimalV2ValEEEvPNS2_15FunctionCo "_ZN5doris19DummyTableFunctions25explode_json_array_stringEPN9doris_udf15FunctionContextERKNS1_9StringValE", null, null, true)); tableFunctions.put(EXPLODE_JSON_ARRAY_STRING, explodeJsonArrayStrings); + + List<Function> explodeNumbers = Lists.newArrayList(); + explodeNumbers.add(ScalarFunction.createBuiltin( + EXPLODE_NUMBERS, Type.INT, Function.NullableMode.DEPEND_ON_ARGUMENT, + Lists.newArrayList(Type.INT), false, + "_ZN5doris19DummyTableFunctions22explode_numbersEPN9doris_udf15FunctionContextERKNS1_9IntValE", + null, null, true)); + tableFunctions.put(EXPLODE_NUMBERS, explodeNumbers); } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
