HappenLee commented on code in PR #14402:
URL: https://github.com/apache/doris/pull/14402#discussion_r1027106252


##########
be/src/vec/exprs/vcompound_pred.h:
##########
@@ -16,38 +16,174 @@
 // under the License.
 
 #pragma once
-#include "runtime/runtime_state.h"
+#include <gen_cpp/Opcodes_types.h>
+
+#include "common/status.h"
+#include "util/simd/bits.h"
+#include "vec/columns/column.h"
+#include "vec/columns/columns_number.h"
+#include "vec/common/assert_cast.h"
 #include "vec/exprs/vectorized_fn_call.h"
 #include "vec/exprs/vexpr.h"
-#include "vec/functions/function.h"
 
 namespace doris::vectorized {
 
-class VcompoundPred final : public VectorizedFnCall {
+inline std::string compound_operator_to_string(TExprOpcode::type op) {
+    if (op == TExprOpcode::COMPOUND_AND) {
+        return "and";
+    } else if (op == TExprOpcode::COMPOUND_OR) {
+        return "or";
+    } else {
+        return "not";
+    }
+}
+
+class VcompoundPred : public VectorizedFnCall {
 public:
     VcompoundPred(const TExprNode& node) : VectorizedFnCall(node) {
-        switch (node.opcode) {
-        case TExprOpcode::COMPOUND_AND:
-            _fn.name.function_name = "and";
-            break;
-        case TExprOpcode::COMPOUND_OR:
-            _fn.name.function_name = "or";
-            break;
-        default:
-            _fn.name.function_name = "not";
-            break;
+        _op = node.opcode;
+        _fn.name.function_name = compound_operator_to_string(_op);
+        _expr_name = "CompoundPredicate (" + _fn.name.function_name + ")";
+    }
+
+    VExpr* clone(ObjectPool* pool) const override { return pool->add(new 
VcompoundPred(*this)); }
+
+    const std::string& expr_name() const override { return _expr_name; }
+
+    Status execute(VExprContext* context, doris::vectorized::Block* block,
+                   int* result_column_id) override {
+        if (_have_invalid_child()) {
+            return VectorizedFnCall::execute(context, block, result_column_id);
+        }
+
+        int lhs_id = -1;
+        int rhs_id = -1;
+        RETURN_IF_ERROR(_children[0]->execute(context, block, &lhs_id));
+        ColumnPtr lhs_column = block->get_by_position(lhs_id).column;
+
+        ColumnPtr rhs_column = nullptr;
+
+        size_t size = lhs_column->size();
+        uint8* __restrict data = _get_raw_data(lhs_column);
+        int filted = simd::count_zero_num((int8_t*)data, size);
+        bool full = filted == 0;
+        bool empty = filted == size;
+
+        const uint8* __restrict data_rhs = nullptr;
+        bool full_rhs = false;
+        bool empty_rhs = false;
+
+        auto get_rhs_colum = [&]() {
+            if (rhs_id == -1) {
+                RETURN_IF_ERROR(_children[1]->execute(context, block, 
&rhs_id));
+                rhs_column = block->get_by_position(rhs_id).column;
+                data_rhs = _get_raw_data(rhs_column);
+                if (!empty) {
+                    if (const uint8* null_map =
+                                
_get_null_map(block->get_by_position(rhs_id).column);
+                        null_map != nullptr) {
+                        for (size_t i = 0; i < size; i++) {
+                            data[i] &= !null_map[i];
+                        }
+                    }
+                }
+                int filted = simd::count_zero_num((int8_t*)data_rhs, size);
+                full_rhs = filted == 0;
+                empty_rhs = filted == size;
+            }
+            return Status::OK();
+        };
+
+        if (_op == TExprOpcode::COMPOUND_AND) {
+            if (!empty) { // empty and any = empty, so lhs should not empty
+                RETURN_IF_ERROR(get_rhs_colum());
+                if (empty_rhs) { // any and empty = empty
+                    *result_column_id = rhs_id;
+                    return Status::OK();
+                } else if (!full_rhs) { // any and full = any, so rhs should 
not full.
+                    for (size_t i = 0; i < size; i++) {
+                        data[i] &= data_rhs[i];
+                    }
+                }
+            }
+        } else if (_op == TExprOpcode::COMPOUND_OR) {
+            if (!full) { // full or any = full, so lhs should not full
+                RETURN_IF_ERROR(get_rhs_colum());
+                if (full_rhs) { // any or full = full
+                    *result_column_id = rhs_id;
+                    return Status::OK();
+                } else if (!empty_rhs) { // any or empty = any, so rhs should 
not empty
+                    for (size_t i = 0; i < size; i++) {
+                        data[i] |= data_rhs[i];
+                    }
+                }
+            }
+        } else {
+            for (size_t i = 0; i < size; i++) {
+                data[i] = !data[i];
+            }
         }
+
+        *result_column_id = lhs_id;
+        return Status::OK();
     }
 
     std::string debug_string() const override {
         std::stringstream out;
-        out << "CompoundPredicate {" << _fn.name.function_name;
-        out << " (" << _children[0]->debug_string();
+        out << _expr_name << "{\n";
+        out << _children[0]->debug_string();
         if (children().size() > 1) {
-            out << ", " << _children[1]->debug_string();
+            out << ",\n" << _children[1]->debug_string();
         }
-        out << ")}";
+        out << "}";
         return out.str();
     }
+
+private:
+    bool _have_invalid_child() const {

Review Comment:
   change the function name not the invalid child



##########
be/src/vec/exprs/vcompound_pred.h:
##########
@@ -16,38 +16,174 @@
 // under the License.
 
 #pragma once
-#include "runtime/runtime_state.h"
+#include <gen_cpp/Opcodes_types.h>
+
+#include "common/status.h"
+#include "util/simd/bits.h"
+#include "vec/columns/column.h"
+#include "vec/columns/columns_number.h"
+#include "vec/common/assert_cast.h"
 #include "vec/exprs/vectorized_fn_call.h"
 #include "vec/exprs/vexpr.h"
-#include "vec/functions/function.h"
 
 namespace doris::vectorized {
 
-class VcompoundPred final : public VectorizedFnCall {
+inline std::string compound_operator_to_string(TExprOpcode::type op) {
+    if (op == TExprOpcode::COMPOUND_AND) {
+        return "and";
+    } else if (op == TExprOpcode::COMPOUND_OR) {
+        return "or";
+    } else {
+        return "not";
+    }
+}
+
+class VcompoundPred : public VectorizedFnCall {
 public:
     VcompoundPred(const TExprNode& node) : VectorizedFnCall(node) {
-        switch (node.opcode) {
-        case TExprOpcode::COMPOUND_AND:
-            _fn.name.function_name = "and";
-            break;
-        case TExprOpcode::COMPOUND_OR:
-            _fn.name.function_name = "or";
-            break;
-        default:
-            _fn.name.function_name = "not";
-            break;
+        _op = node.opcode;
+        _fn.name.function_name = compound_operator_to_string(_op);
+        _expr_name = "CompoundPredicate (" + _fn.name.function_name + ")";
+    }
+
+    VExpr* clone(ObjectPool* pool) const override { return pool->add(new 
VcompoundPred(*this)); }
+
+    const std::string& expr_name() const override { return _expr_name; }
+
+    Status execute(VExprContext* context, doris::vectorized::Block* block,
+                   int* result_column_id) override {
+        if (_have_invalid_child()) {
+            return VectorizedFnCall::execute(context, block, result_column_id);
+        }
+
+        int lhs_id = -1;
+        int rhs_id = -1;
+        RETURN_IF_ERROR(_children[0]->execute(context, block, &lhs_id));
+        ColumnPtr lhs_column = block->get_by_position(lhs_id).column;
+
+        ColumnPtr rhs_column = nullptr;
+
+        size_t size = lhs_column->size();
+        uint8* __restrict data = _get_raw_data(lhs_column);
+        int filted = simd::count_zero_num((int8_t*)data, size);
+        bool full = filted == 0;
+        bool empty = filted == size;
+
+        const uint8* __restrict data_rhs = nullptr;
+        bool full_rhs = false;
+        bool empty_rhs = false;
+
+        auto get_rhs_colum = [&]() {
+            if (rhs_id == -1) {
+                RETURN_IF_ERROR(_children[1]->execute(context, block, 
&rhs_id));
+                rhs_column = block->get_by_position(rhs_id).column;
+                data_rhs = _get_raw_data(rhs_column);
+                if (!empty) {
+                    if (const uint8* null_map =
+                                
_get_null_map(block->get_by_position(rhs_id).column);
+                        null_map != nullptr) {
+                        for (size_t i = 0; i < size; i++) {
+                            data[i] &= !null_map[i];
+                        }
+                    }
+                }
+                int filted = simd::count_zero_num((int8_t*)data_rhs, size);
+                full_rhs = filted == 0;
+                empty_rhs = filted == size;
+            }
+            return Status::OK();
+        };
+
+        if (_op == TExprOpcode::COMPOUND_AND) {
+            if (!empty) { // empty and any = empty, so lhs should not empty
+                RETURN_IF_ERROR(get_rhs_colum());
+                if (empty_rhs) { // any and empty = empty
+                    *result_column_id = rhs_id;
+                    return Status::OK();
+                } else if (!full_rhs) { // any and full = any, so rhs should 
not full.
+                    for (size_t i = 0; i < size; i++) {
+                        data[i] &= data_rhs[i];
+                    }
+                }
+            }
+        } else if (_op == TExprOpcode::COMPOUND_OR) {
+            if (!full) { // full or any = full, so lhs should not full
+                RETURN_IF_ERROR(get_rhs_colum());
+                if (full_rhs) { // any or full = full
+                    *result_column_id = rhs_id;
+                    return Status::OK();
+                } else if (!empty_rhs) { // any or empty = any, so rhs should 
not empty
+                    for (size_t i = 0; i < size; i++) {
+                        data[i] |= data_rhs[i];
+                    }
+                }
+            }
+        } else {
+            for (size_t i = 0; i < size; i++) {
+                data[i] = !data[i];

Review Comment:
   FunctionNot Seem already do the work ?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to