This is an automated email from the ASF dual-hosted git repository.

morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-doris.git


The following commit(s) were added to refs/heads/master by this push:
     new d2374dbd5e [fix](Lateral-View) fix outer combinator not work on 
non-vectorized (#9212)
d2374dbd5e is described below

commit d2374dbd5ef19000c7ec8b56b8788cf3afd498e1
Author: Pxl <[email protected]>
AuthorDate: Sun May 1 22:09:50 2022 +0800

    [fix](Lateral-View) fix outer combinator not work on non-vectorized (#9212)
---
 be/src/exec/table_function_node.cpp                | 18 +++++-
 be/src/exec/table_function_node.h                  | 11 ++--
 be/src/vec/exec/vtable_function_node.cpp           | 14 +---
 be/src/vec/exec/vtable_function_node.h             |  2 -
 be/src/vec/functions/function_fake.cpp             | 75 ++++++++++++++--------
 be/src/vec/functions/function_fake.h               |  3 +-
 be/src/vec/functions/simple_function_factory.h     |  6 +-
 .../table_function/explode_json_array.out          |  4 --
 8 files changed, 77 insertions(+), 56 deletions(-)

diff --git a/be/src/exec/table_function_node.cpp 
b/be/src/exec/table_function_node.cpp
index 01a023b07b..50351438c3 100644
--- a/be/src/exec/table_function_node.cpp
+++ b/be/src/exec/table_function_node.cpp
@@ -78,6 +78,16 @@ Status TableFunctionNode::_prepare_output_slot_ids(const 
TPlanNode& tnode) {
     return Status::OK();
 }
 
+bool TableFunctionNode::_is_inner_and_empty() {
+    for (int i = 0; i < _fn_num; i++) {
+        // if any table function is not outer and has empty result, go to next 
child row
+        if (!_fns[i]->is_outer() && _fns[i]->current_empty()) {
+            return true;
+        }
+    }
+    return false;
+}
+
 Status TableFunctionNode::prepare(RuntimeState* state) {
     RETURN_IF_ERROR(ExecNode::prepare(state));
     SCOPED_SWITCH_TASK_THREAD_LOCAL_MEM_TRACKER(mem_tracker());
@@ -230,9 +240,10 @@ Status TableFunctionNode::get_next(RuntimeState* state, 
RowBatch* row_batch, boo
             }
         }
 
+        bool skip_child_row = false;
         while (true) {
             int idx = _find_last_fn_eos_idx();
-            if (idx == 0) {
+            if (idx == 0 || skip_child_row) {
                 // all table functions' results are exhausted, process next 
child row
                 RETURN_IF_ERROR(_process_next_child_row());
                 if (_child_batch_exhausted) {
@@ -246,6 +257,11 @@ Status TableFunctionNode::get_next(RuntimeState* state, 
RowBatch* row_batch, boo
                 }
             }
 
+            // if any table function is not outer and has empty result, go to 
next child row
+            if (skip_child_row = _is_inner_and_empty(); skip_child_row) {
+                continue;
+            }
+
             // get slots from every table function
             // Notice that _fn_values[i] may be null if the table function has 
empty result set.
             for (int i = 0; i < _fn_num; i++) {
diff --git a/be/src/exec/table_function_node.h 
b/be/src/exec/table_function_node.h
index fd06760943..06de804c3c 100644
--- a/be/src/exec/table_function_node.h
+++ b/be/src/exec/table_function_node.h
@@ -32,14 +32,15 @@ public:
     TableFunctionNode(ObjectPool* pool, const TPlanNode& tnode, const 
DescriptorTbl& descs);
     ~TableFunctionNode();
 
-    virtual Status init(const TPlanNode& tnode, RuntimeState* state = nullptr);
-    virtual Status prepare(RuntimeState* state);
-    virtual Status open(RuntimeState* state);
-    virtual Status get_next(RuntimeState* state, RowBatch* row_batch, bool* 
eos);
-    virtual Status close(RuntimeState* state);
+    Status init(const TPlanNode& tnode, RuntimeState* state = nullptr) 
override;
+    Status prepare(RuntimeState* state) override;
+    Status open(RuntimeState* state) override;
+    Status get_next(RuntimeState* state, RowBatch* row_batch, bool* eos) 
override;
+    Status close(RuntimeState* state) override;
 
 protected:
     Status _prepare_output_slot_ids(const TPlanNode& tnode);
+    bool _is_inner_and_empty();
 
     // return:
     //  0: all fns are eos
diff --git a/be/src/vec/exec/vtable_function_node.cpp 
b/be/src/vec/exec/vtable_function_node.cpp
index 6b25849f77..d21b252f35 100644
--- a/be/src/vec/exec/vtable_function_node.cpp
+++ b/be/src/vec/exec/vtable_function_node.cpp
@@ -92,16 +92,6 @@ Status VTableFunctionNode::get_next(RuntimeState* state, 
Block* block, bool* eos
     return Status::OK();
 }
 
-bool VTableFunctionNode::_is_inner_and_empty() {
-    for (int i = 0; i < _fn_num; i++) {
-        // if any table function is not outer and has empty result, go to next 
child row
-        if (!_fns[i]->is_outer() && _fns[i]->current_empty()) {
-            return true;
-        }
-    }
-    return false;
-}
-
 Status VTableFunctionNode::get_expanded_block(RuntimeState* state, Block* 
output_block, bool* eos) {
     DCHECK(_child_block != nullptr);
 
@@ -156,7 +146,7 @@ Status VTableFunctionNode::get_expanded_block(RuntimeState* 
state, Block* output
             }
 
             // if any table function is not outer and has empty result, go to 
next child row
-            if ((skip_child_row = _is_inner_and_empty()) == true) {
+            if (skip_child_row = _is_inner_and_empty(); skip_child_row) {
                 continue;
             }
 
@@ -225,7 +215,7 @@ Status VTableFunctionNode::_process_next_child_row() {
             RETURN_IF_ERROR(fn->process_close());
         }
 
-        release_block_memory(*_child_block.get());
+        release_block_memory(*_child_block);
         _cur_child_offset = -1;
         return Status::OK();
     }
diff --git a/be/src/vec/exec/vtable_function_node.h 
b/be/src/vec/exec/vtable_function_node.h
index 6192e52ff6..1913cd1d35 100644
--- a/be/src/vec/exec/vtable_function_node.h
+++ b/be/src/vec/exec/vtable_function_node.h
@@ -37,8 +37,6 @@ private:
 
     Status get_expanded_block(RuntimeState* state, Block* output_block, bool* 
eos);
 
-    bool _is_inner_and_empty();
-
     std::unique_ptr<Block> _child_block;
     std::vector<SlotDescriptor*> _child_slots;
     std::vector<SlotDescriptor*> _output_slots;
diff --git a/be/src/vec/functions/function_fake.cpp 
b/be/src/vec/functions/function_fake.cpp
index 1f52297806..faf8d0d525 100644
--- a/be/src/vec/functions/function_fake.cpp
+++ b/be/src/vec/functions/function_fake.cpp
@@ -21,33 +21,21 @@
 #include <string_view>
 #include <type_traits>
 
+#include "vec/data_types/data_type_nullable.h"
+
 namespace doris::vectorized {
 
-// We can use std::basic_fixed_string with c++20 in the future
-template <const char* Name, typename ReturnType>
-struct FakeFunctionBaseImpl {
-    static constexpr auto name = Name;
+template <typename ReturnType, bool AlwaysNullable = false>
+struct FunctionFakeBaseImpl {
     static DataTypePtr get_return_type_impl(const DataTypes& arguments) {
+        if constexpr (AlwaysNullable) {
+            return make_nullable(std::make_shared<ReturnType>());
+        }
         return std::make_shared<ReturnType>();
     }
 };
 
-#define C_STR(str_) boost::mpl::c_str<BOOST_METAPARSE_STRING(str_)>::value
-
-using FunctionEsquery = FakeFunctionBaseImpl<C_STR("esquery"), DataTypeUInt8>;
-
-using FunctionExplodeSplit = FakeFunctionBaseImpl<C_STR("explode_split"), 
DataTypeString>;
-using FunctionExplodeNumbers = FakeFunctionBaseImpl<C_STR("explode_numbers"), 
DataTypeInt32>;
-using FunctionExplodeJsonArrayInt =
-        FakeFunctionBaseImpl<C_STR("explode_json_array_int"), DataTypeInt64>;
-using FunctionExplodeJsonArrayString =
-        FakeFunctionBaseImpl<C_STR("explode_json_array_string"), 
DataTypeString>;
-using FunctionExplodeJsonArrayDouble =
-        FakeFunctionBaseImpl<C_STR("explode_json_array_double"), 
DataTypeFloat64>;
-using FunctionExplodeBitmap = FakeFunctionBaseImpl<C_STR("explode_bitmap"), 
DataTypeInt64>;
-
 struct FunctionExplode {
-    static constexpr auto name = "explode";
     static DataTypePtr get_return_type_impl(const DataTypes& arguments) {
         DCHECK(is_array(arguments[0])) << arguments[0]->get_name() << " not 
supported";
         return make_nullable(
@@ -55,16 +43,49 @@ struct FunctionExplode {
     }
 };
 
+template <typename ReturnType, bool Nullable = false>
+void register_function_default(SimpleFunctionFactory& factory, const 
std::string& name) {
+    factory.register_function<FunctionFake<FunctionFakeBaseImpl<ReturnType, 
Nullable>>>(name);
+};
+
+template <typename FunctionImpl>
+void register_table_function_expand(SimpleFunctionFactory& factory, const 
std::string& name,
+                                    const std::string& suffix) {
+    factory.register_function<FunctionFake<FunctionImpl>>(name);
+    factory.register_function<FunctionFake<FunctionImpl>>(name + suffix);
+};
+
+template <typename ReturnType>
+void register_table_function_expand_default(SimpleFunctionFactory& factory, 
const std::string& name,
+                                            const std::string& suffix) {
+    
factory.register_function<FunctionFake<FunctionFakeBaseImpl<ReturnType>>>(name);
+    factory.register_function<FunctionFake<FunctionFakeBaseImpl<ReturnType, 
true>>>(name + suffix);
+};
+
+template <typename FunctionImpl>
+void register_table_function_expand_outer(SimpleFunctionFactory& factory, 
const std::string& name) {
+    register_table_function_expand<FunctionImpl>(factory, name, 
COMBINATOR_SUFFIX_OUTER);
+};
+
+template <typename ReturnType>
+void register_table_function_expand_outer_default(SimpleFunctionFactory& 
factory,
+                                                  const std::string& name) {
+    register_table_function_expand_default<ReturnType>(factory, name, 
COMBINATOR_SUFFIX_OUTER);
+};
+
 void register_function_fake(SimpleFunctionFactory& factory) {
-    factory.register_function<FunctionFake<FunctionEsquery>>();
+    register_function_default<DataTypeUInt8>(factory, "esquery");
+
+    register_table_function_expand_outer<FunctionExplode>(factory, "explode");
 
-    factory.register_table_function<FunctionFake<FunctionExplodeSplit>>();
-    factory.register_table_function<FunctionFake<FunctionExplodeNumbers>>();
-    
factory.register_table_function<FunctionFake<FunctionExplodeJsonArrayDouble>>();
-    
factory.register_table_function<FunctionFake<FunctionExplodeJsonArrayInt>>();
-    
factory.register_table_function<FunctionFake<FunctionExplodeJsonArrayString>>();
-    factory.register_table_function<FunctionFake<FunctionExplodeBitmap>>();
-    factory.register_table_function<FunctionFake<FunctionExplode>>();
+    register_table_function_expand_outer_default<DataTypeString>(factory, 
"explode_split");
+    register_table_function_expand_outer_default<DataTypeInt32>(factory, 
"explode_numbers");
+    register_table_function_expand_outer_default<DataTypeInt64>(factory, 
"explode_json_array_int");
+    register_table_function_expand_outer_default<DataTypeString>(factory,
+                                                                 
"explode_json_array_string");
+    register_table_function_expand_outer_default<DataTypeFloat64>(factory,
+                                                                  
"explode_json_array_double");
+    register_table_function_expand_outer_default<DataTypeInt64>(factory, 
"explode_bitmap");
 }
 
 } // namespace doris::vectorized
diff --git a/be/src/vec/functions/function_fake.h 
b/be/src/vec/functions/function_fake.h
index eaaecaf843..2dbf4f263f 100644
--- a/be/src/vec/functions/function_fake.h
+++ b/be/src/vec/functions/function_fake.h
@@ -20,6 +20,7 @@
 #include "common/status.h"
 #include "vec/core/types.h"
 #include "vec/data_types/data_type_array.h"
+#include "vec/data_types/data_type_nullable.h"
 #include "vec/data_types/data_type_number.h"
 #include "vec/data_types/data_type_string.h"
 #include "vec/functions/function_helpers.h"
@@ -31,7 +32,7 @@ namespace doris::vectorized {
 template <typename Impl>
 class FunctionFake : public IFunction {
 public:
-    static constexpr auto name = Impl::name;
+    static constexpr auto name = "fake";
 
     static FunctionPtr create() { return std::make_shared<FunctionFake>(); }
 
diff --git a/be/src/vec/functions/simple_function_factory.h 
b/be/src/vec/functions/simple_function_factory.h
index 033682212a..986528f25f 100644
--- a/be/src/vec/functions/simple_function_factory.h
+++ b/be/src/vec/functions/simple_function_factory.h
@@ -112,10 +112,8 @@ public:
     }
 
     template <class Function>
-    void register_table_function() {
-        function_creators[Function::name] = &createDefaultFunction<Function>;
-        function_creators[std::string(Function::name) + 
COMBINATOR_SUFFIX_OUTER] =
-                &createDefaultFunction<Function>;
+    void register_function(std::string name) {
+        function_creators[name] = &createDefaultFunction<Function>;
     }
 
     void register_alias(const std::string& name, const std::string& alias) {
diff --git 
a/regression-test/data/query/sql_functions/table_function/explode_json_array.out
 
b/regression-test/data/query/sql_functions/table_function/explode_json_array.out
index 52e504bdfb..4170e82089 100644
--- 
a/regression-test/data/query/sql_functions/table_function/explode_json_array.out
+++ 
b/regression-test/data/query/sql_functions/table_function/explode_json_array.out
@@ -22,10 +22,6 @@
 60     8
 
 -- !explode_json_array3 --
-100    John    30      1       Street 1        \N
-200    Mary    \N      1       Street 2        \N
-300    Mike    80      3       Street 3        \N
-400    Dan     50      4       Street 4        \N
 
 -- !explode_json_array4 --
 100    John    30      1       Street 1        1.23    1


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to