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

yiguolei pushed a commit to branch dev-1.1.2
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/dev-1.1.2 by this push:
     new 3b8e78d196 [Enhancement](table_function) table function node 
enhancement (#12206)
3b8e78d196 is described below

commit 3b8e78d19659d769efd7affbecb44efa18578ad7
Author: camby <[email protected]>
AuthorDate: Wed Aug 31 11:03:48 2022 +0800

    [Enhancement](table_function) table function node enhancement (#12206)
    
    * table function node enhancement
    
    * also avoid copy for non-vec table function node
    
    * fix table function node output slots calculation while lateral view 
involves subquery
    
    Co-authored-by: cambyzju <[email protected]>
---
 be/src/exec/table_function_node.cpp                | 29 ++++++++++++++--------
 be/src/vec/exec/vtable_function_node.cpp           |  6 ++++-
 be/src/vec/exec/vtable_function_node.h             | 22 +++++++++++++++-
 .../apache/doris/planner/TableFunctionNode.java    | 13 +++++++++-
 4 files changed, 57 insertions(+), 13 deletions(-)

diff --git a/be/src/exec/table_function_node.cpp 
b/be/src/exec/table_function_node.cpp
index ff86df9601..e9d69ba3e5 100644
--- a/be/src/exec/table_function_node.cpp
+++ b/be/src/exec/table_function_node.cpp
@@ -279,16 +279,25 @@ Status TableFunctionNode::get_next(RuntimeState* state, 
RowBatch* row_batch, boo
                     memcpy(tuple_ptr, child_tuple, 
parent_tuple_desc->byte_size());
                     // only deep copy the child slot if it is selected and is 
var len (Eg: string, bitmap, hll)
                     for (int j = 0; j < _child_slot_sizes[i]; ++j) {
-                        SlotDescriptor *child_slot_desc = 
child_tuple_desc->slots()[j];
-                        SlotDescriptor *parent_slot_desc = 
parent_tuple_desc->slots()[j];
-
-                        if (_output_slot_ids[parent_slot_desc->id()] &&
-                            
!child_tuple->is_null(child_slot_desc->null_indicator_offset())
-                            && child_slot_desc->type().is_string_type()) {
-                            void *dest_slot = 
tuple_ptr->get_slot(parent_slot_desc->tuple_offset());
-                            
RawValue::write(child_tuple->get_slot(child_slot_desc->tuple_offset()),
-                                            dest_slot, 
parent_slot_desc->type(),
-                                            row_batch->tuple_data_pool());
+                        SlotDescriptor* child_slot_desc = 
child_tuple_desc->slots()[j];
+                        SlotDescriptor* parent_slot_desc = 
parent_tuple_desc->slots()[j];
+
+                        if 
(child_tuple->is_null(child_slot_desc->null_indicator_offset())) {
+                            continue;
+                        }
+                        if (child_slot_desc->type().is_string_type()) {
+                            void* dest_slot = 
tuple_ptr->get_slot(parent_slot_desc->tuple_offset());
+                            if (_output_slot_ids[parent_slot_desc->id()]) {
+                                // deep coopy
+                                RawValue::write(
+                                        
child_tuple->get_slot(child_slot_desc->tuple_offset()),
+                                        dest_slot, parent_slot_desc->type(),
+                                        row_batch->tuple_data_pool());
+                            } else {
+                                // clear for unused slot
+                                StringValue* dest = 
reinterpret_cast<StringValue*>(dest_slot);
+                                dest->replace(nullptr, 0);
+                            }
                         }
                     }
                     parent_tuple_row->set_tuple(tuple_idx, tuple_ptr);
diff --git a/be/src/vec/exec/vtable_function_node.cpp 
b/be/src/vec/exec/vtable_function_node.cpp
index 30dd0097f6..e38d5c3726 100644
--- a/be/src/vec/exec/vtable_function_node.cpp
+++ b/be/src/vec/exec/vtable_function_node.cpp
@@ -156,6 +156,10 @@ Status 
VTableFunctionNode::get_expanded_block(RuntimeState* state, Block* output
 
             // 1. copy data from child_block.
             for (int i = 0; i < _child_slots.size(); i++) {
+                if (!slot_need_copy(i)) {
+                    columns[i]->insert_default();
+                    continue;
+                }
                 auto src_column = _child_block->get_by_position(i).column;
                 columns[i]->insert_from(*src_column, _cur_child_offset);
             }
@@ -221,4 +225,4 @@ Status VTableFunctionNode::_process_next_child_row() {
     return Status::OK();
 }
 
-} // namespace doris::vectorized
\ No newline at end of file
+} // namespace doris::vectorized
diff --git a/be/src/vec/exec/vtable_function_node.h 
b/be/src/vec/exec/vtable_function_node.h
index 1913cd1d35..72108fa1d9 100644
--- a/be/src/vec/exec/vtable_function_node.h
+++ b/be/src/vec/exec/vtable_function_node.h
@@ -33,6 +33,26 @@ public:
 private:
     Status _process_next_child_row() override;
 
+    /*  Now the output tuples for table function node is base_table_tuple + 
tf1 + tf2 + ...
+        But not all slots are used, the real used slots are inside 
table_function_node.outputSlotIds.
+        For case like explode_bitmap:
+            SELECT a2,count(*) as a3 FROM A WHERE a1 IN
+                (SELECT c1 FROM B LATERAL VIEW explode_bitmap(b1) C as c1)
+            GROUP BY a2 ORDER BY a3;
+        Actually we only need to output column c1, no need to output columns 
in bitmap table B.
+        Copy large bitmap columns are very expensive and slow.
+
+        Here we check if the slot is realy used, otherwise we avoid copy it 
and just insert a default value.
+
+        A better solution is:
+            1. FE: create a new output tuple based on the real output slots;
+            2. BE: refractor (V)TableFunctionNode output rows based no the new 
tuple;
+    */
+    inline bool slot_need_copy(SlotId slot_id) const {
+        auto id = _output_slots[slot_id]->id();
+        return (id < _output_slot_ids.size()) && (_output_slot_ids[id]);
+    }
+
     using TableFunctionNode::get_next;
 
     Status get_expanded_block(RuntimeState* state, Block* output_block, bool* 
eos);
@@ -42,4 +62,4 @@ private:
     std::vector<SlotDescriptor*> _output_slots;
 };
 
-} // namespace doris::vectorized
\ No newline at end of file
+} // namespace doris::vectorized
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/TableFunctionNode.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/TableFunctionNode.java
index c09a0fdd37..d430539b03 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/TableFunctionNode.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/TableFunctionNode.java
@@ -40,7 +40,6 @@ import java.util.Set;
 import java.util.stream.Collectors;
 
 public class TableFunctionNode extends PlanNode {
-
     private List<LateralViewRef> lateralViewRefs;
     private ArrayList<Expr> fnCallExprList;
     private List<TupleId> lateralViewTupleIds;
@@ -99,11 +98,23 @@ public class TableFunctionNode extends PlanNode {
         for (Expr resultExpr : baseTblResultExprs) {
             // find all slotRef bound by tupleIds in resultExpr
             resultExpr.getSlotRefsBoundByTupleIds(tupleIds, outputSlotRef);
+
+            // For vec engine while lateral view involves subquery
+            Expr dst = outputSmap.get(resultExpr);
+            if (dst != null) {
+                dst.getSlotRefsBoundByTupleIds(tupleIds, outputSlotRef);
+            }
         }
         // case2
         List<Expr> remainConjuncts = analyzer.getRemainConjuncts(tupleIds);
         for (Expr expr : remainConjuncts) {
             expr.getSlotRefsBoundByTupleIds(tupleIds, outputSlotRef);
+
+            // For vec engine while lateral view involves subquery
+            Expr dst = outputSmap.get(expr);
+            if (dst != null) {
+                dst.getSlotRefsBoundByTupleIds(tupleIds, outputSlotRef);
+            }
         }
         // set output slot ids
         for (SlotRef slotRef : outputSlotRef) {


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

Reply via email to