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

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


The following commit(s) were added to refs/heads/branch-4.0 by this push:
     new 98fbe2bf2d4 branch-4.0: [fix](predicate) Avoid recomputing predicates 
#60484 (#60514)
98fbe2bf2d4 is described below

commit 98fbe2bf2d445628699f948738166af927d167e7
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Thu Feb 5 14:53:10 2026 +0800

    branch-4.0: [fix](predicate) Avoid recomputing predicates #60484 (#60514)
    
    Cherry-picked from #60484
    
    Co-authored-by: Gabriel <[email protected]>
---
 be/src/olap/column_predicate.h              |  2 ++
 be/src/olap/comparison_predicate.h          |  6 ++++++
 be/src/olap/in_list_predicate.h             |  7 +++++++
 be/src/olap/null_predicate.h                |  1 +
 be/src/pipeline/exec/olap_scan_operator.cpp | 23 ++++++++++++++++++++++-
 5 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/be/src/olap/column_predicate.h b/be/src/olap/column_predicate.h
index 9e6cf291a26..c4a5736beb0 100644
--- a/be/src/olap/column_predicate.h
+++ b/be/src/olap/column_predicate.h
@@ -225,6 +225,8 @@ public:
     }
 
     virtual double get_ignore_threshold() const { return 0; }
+    // If this predicate acts on the key column, this predicate should be 
erased.
+    virtual bool could_be_erased() const { return false; }
     // Return the size of value set for IN/NOT IN predicates and 0 for others.
     virtual std::string debug_string() const {
         fmt::memory_buffer debug_string_buffer;
diff --git a/be/src/olap/comparison_predicate.h 
b/be/src/olap/comparison_predicate.h
index 7b86e8522f7..53e8ae6898e 100644
--- a/be/src/olap/comparison_predicate.h
+++ b/be/src/olap/comparison_predicate.h
@@ -52,6 +52,12 @@ public:
                        ColumnPredicate::debug_string());
         return fmt::to_string(debug_string_buffer);
     }
+    bool could_be_erased() const override {
+        if ((PT == PredicateType::NE && !_opposite) || (PT == 
PredicateType::EQ && _opposite)) {
+            return false;
+        }
+        return true;
+    }
 
     PredicateType type() const override { return PT; }
 
diff --git a/be/src/olap/in_list_predicate.h b/be/src/olap/in_list_predicate.h
index 2c34f5cfa38..20003ab7845 100644
--- a/be/src/olap/in_list_predicate.h
+++ b/be/src/olap/in_list_predicate.h
@@ -145,6 +145,13 @@ public:
 
     PredicateType type() const override { return PT; }
 
+    bool could_be_erased() const override {
+        if ((PT == PredicateType::NOT_IN_LIST && !_opposite) ||
+            (PT == PredicateType::IN_LIST && _opposite)) {
+            return false;
+        }
+        return true;
+    }
     Status evaluate(const vectorized::IndexFieldNameAndTypePair& 
name_with_type,
                     IndexIterator* iterator, uint32_t num_rows,
                     roaring::Roaring* result) const override {
diff --git a/be/src/olap/null_predicate.h b/be/src/olap/null_predicate.h
index 7345e4b2703..4db04add084 100644
--- a/be/src/olap/null_predicate.h
+++ b/be/src/olap/null_predicate.h
@@ -60,6 +60,7 @@ public:
                        ColumnPredicate::debug_string(), _is_null);
         return fmt::to_string(debug_string_buffer);
     }
+    bool could_be_erased() const override { return true; }
 
     PredicateType type() const override;
 
diff --git a/be/src/pipeline/exec/olap_scan_operator.cpp 
b/be/src/pipeline/exec/olap_scan_operator.cpp
index 05a6ddbfd2c..d8f698c4081 100644
--- a/be/src/pipeline/exec/olap_scan_operator.cpp
+++ b/be/src/pipeline/exec/olap_scan_operator.cpp
@@ -21,6 +21,7 @@
 
 #include <memory>
 #include <numeric>
+#include <optional>
 
 #include "cloud/cloud_meta_mgr.h"
 #include "cloud/cloud_storage_engine.h"
@@ -878,6 +879,8 @@ Status OlapScanLocalState::_build_key_ranges_and_filters() {
             DCHECK(_slot_id_to_predicates.count(iter->first) > 0);
             const auto& value_range = iter->second;
 
+            std::optional<int> key_to_erase;
+
             RETURN_IF_ERROR(std::visit(
                     [&](auto&& range) {
                         // make a copy or range and pass to extend_scan_key, 
keep the range unchanged
@@ -889,7 +892,7 @@ Status OlapScanLocalState::_build_key_ranges_and_filters() {
                                     _scan_keys.extend_scan_key(temp_range, 
p._max_scan_key_num,
                                                                &exact_range, 
&eos, &should_break));
                             if (exact_range) {
-                                _slot_id_to_value_range.erase(iter->first);
+                                key_to_erase = iter->first;
                             }
                         } else {
                             // if exceed max_pushdown_conditions_per_column, 
use whole_value_rang instead
@@ -902,6 +905,24 @@ Status OlapScanLocalState::_build_key_ranges_and_filters() 
{
                         return Status::OK();
                     },
                     value_range));
+
+            // Perform the erase operation after the visit is complete, still 
under lock
+            if (key_to_erase.has_value()) {
+                _slot_id_to_value_range.erase(*key_to_erase);
+
+                std::vector<std::shared_ptr<ColumnPredicate>> new_predicates;
+                for (const auto& it : _slot_id_to_predicates[*key_to_erase]) {
+                    if (!it->could_be_erased()) {
+                        new_predicates.push_back(it);
+                    }
+                }
+                if (new_predicates.empty()) {
+                    _slot_id_to_predicates.erase(*key_to_erase);
+                } else {
+                    _slot_id_to_predicates[*key_to_erase] = new_predicates;
+                }
+            }
+            // lock is released here when it goes out of scope
         }
         if (eos) {
             _eos = true;


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

Reply via email to