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]

Reply via email to