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

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

commit 3180053e1e29d498924b354652c14b591e147e58
Author: airborne12 <airborn...@gmail.com>
AuthorDate: Tue Nov 7 15:43:34 2023 +0800

    [Feature](inverted index) support range predicate for inverted index
---
 be/src/common/config.cpp                           |   1 +
 be/src/common/config.h                             |   2 +
 be/src/olap/block_column_predicate.cpp             |  39 +-
 be/src/olap/block_column_predicate.h               |   6 +-
 be/src/olap/column_predicate.h                     |   9 +
 be/src/olap/comparison_predicate.h                 |  76 ++-
 be/src/olap/in_list_predicate.h                    |  32 +-
 be/src/olap/match_predicate.cpp                    |  22 +-
 be/src/olap/olap_common.h                          |   4 +
 .../inverted_index/query/disjunction_query.cpp     |   3 +-
 .../inverted_index/query/disjunction_query.h       |   1 -
 .../inverted_index/query/inverted_index_query.cpp  | 314 +++++++++
 .../inverted_index/query/inverted_index_query.h    | 220 ++++++
 .../inverted_index/query/range_query.cpp           | 128 ++++
 .../query/{disjunction_query.h => range_query.h}   |  17 +-
 .../rowset/segment_v2/inverted_index_query_type.h  |  17 +
 .../rowset/segment_v2/inverted_index_reader.cpp    | 745 +++++++++------------
 .../olap/rowset/segment_v2/inverted_index_reader.h | 126 ++--
 be/src/olap/rowset/segment_v2/segment_iterator.cpp |  50 +-
 be/src/olap/rowset/segment_v2/segment_iterator.h   |   4 +-
 be/src/vec/exec/scan/new_olap_scan_node.cpp        |   7 +
 be/src/vec/exec/scan/new_olap_scan_node.h          |   4 +
 be/src/vec/exec/scan/new_olap_scanner.cpp          |   7 +
 be/src/vec/exec/scan/vscan_node.h                  |   2 +-
 24 files changed, 1307 insertions(+), 529 deletions(-)

diff --git a/be/src/common/config.cpp b/be/src/common/config.cpp
index 0a7d92f5da7..f2daf3de38f 100644
--- a/be/src/common/config.cpp
+++ b/be/src/common/config.cpp
@@ -1003,6 +1003,7 @@ DEFINE_Int32(inverted_index_read_buffer_size, "4096");
 DEFINE_Int32(max_depth_in_bkd_tree, "32");
 // index compaction
 DEFINE_Bool(inverted_index_compaction_enable, "false");
+DEFINE_mInt32(inverted_index_max_terms, "1024");
 // use num_broadcast_buffer blocks as buffer to do broadcast
 DEFINE_Int32(num_broadcast_buffer, "32");
 // semi-structure configs
diff --git a/be/src/common/config.h b/be/src/common/config.h
index c3a4a4229ba..d8a2acc060c 100644
--- a/be/src/common/config.h
+++ b/be/src/common/config.h
@@ -1040,6 +1040,8 @@ DECLARE_Int32(inverted_index_read_buffer_size);
 DECLARE_Int32(max_depth_in_bkd_tree);
 // index compaction
 DECLARE_Bool(inverted_index_compaction_enable);
+// max inverted index terms size for range query
+DECLARE_mInt32(inverted_index_max_terms);
 // use num_broadcast_buffer blocks as buffer to do broadcast
 DECLARE_Int32(num_broadcast_buffer);
 // semi-structure configs
diff --git a/be/src/olap/block_column_predicate.cpp 
b/be/src/olap/block_column_predicate.cpp
index 8cfb89363cd..a9b1b860281 100644
--- a/be/src/olap/block_column_predicate.cpp
+++ b/be/src/olap/block_column_predicate.cpp
@@ -213,11 +213,40 @@ void 
AndBlockColumnPredicate::evaluate_vec(vectorized::MutableColumns& block, ui
     }
 }
 
-Status AndBlockColumnPredicate::evaluate(const std::string& column_name,
-                                         InvertedIndexIterator* iterator, 
uint32_t num_rows,
-                                         roaring::Roaring* bitmap) const {
-    return Status::NotSupported(
-            "Not Implemented evaluate with inverted index, please check the 
predicate");
+Status AndBlockColumnPredicate::evaluate(const Schema& schema, 
InvertedIndexIterator* iterator,
+                                         uint32_t num_rows, roaring::Roaring* 
bitmap) const {
+    std::set<const ColumnPredicate*> predicates;
+    get_all_column_predicate(predicates);
+    std::unique_ptr<InvertedIndexQueryBase> query_value = nullptr;
+    uint32_t column_id = 0;
+    roaring::Roaring roaring;
+
+    for (const auto& pred : predicates) {
+        RETURN_IF_ERROR(pred->set_inverted_index_query_value(query_value, 
schema));
+        column_id = pred->column_id();
+    }
+    if (!predicates.empty()) {
+        const auto* column_desc = schema.column(column_id);
+        std::string column_name = column_desc->name();
+        RETURN_IF_ERROR(iterator->read_from_inverted_index(column_name, 
query_value.get(), num_rows,
+                                                           &roaring));
+
+        // mask out null_bitmap, since NULL cmp VALUE will produce NULL
+        //  and be treated as false in WHERE
+        // keep it after query, since query will try to read null_bitmap and 
put it to cache
+        InvertedIndexQueryCacheHandle null_bitmap_cache_handle;
+        RETURN_IF_ERROR(iterator->read_null_bitmap(&null_bitmap_cache_handle));
+        std::shared_ptr<roaring::Roaring> null_bitmap = 
null_bitmap_cache_handle.get_bitmap();
+        if (null_bitmap) {
+            *bitmap -= *null_bitmap;
+        }
+        *bitmap &= roaring;
+        return Status::OK();
+    }
+    DCHECK(false);
+
+    return Status::Error(INTERNAL_ERROR,
+                         "block column predicates size = 0, please check the 
predicate");
 }
 
 } // namespace doris
diff --git a/be/src/olap/block_column_predicate.h 
b/be/src/olap/block_column_predicate.h
index c91dc0c3678..fee5ef46ff2 100644
--- a/be/src/olap/block_column_predicate.h
+++ b/be/src/olap/block_column_predicate.h
@@ -90,7 +90,7 @@ public:
     virtual bool can_do_bloom_filter(bool ngram) const { return false; }
 
     //evaluate predicate on inverted
-    virtual Status evaluate(const std::string& column_name, 
InvertedIndexIterator* iterator,
+    virtual Status evaluate(const Schema& schema, InvertedIndexIterator* 
iterator,
                             uint32_t num_rows, roaring::Roaring* bitmap) const 
{
         return Status::NotSupported(
                 "Not Implemented evaluate with inverted index, please check 
the predicate");
@@ -199,8 +199,8 @@ public:
         return true;
     }
 
-    Status evaluate(const std::string& column_name, InvertedIndexIterator* 
iterator,
-                    uint32_t num_rows, roaring::Roaring* bitmap) const 
override;
+    Status evaluate(const Schema& schema, InvertedIndexIterator* iterator, 
uint32_t num_rows,
+                    roaring::Roaring* bitmap) const override;
 };
 
 } //namespace doris
diff --git a/be/src/olap/column_predicate.h b/be/src/olap/column_predicate.h
index 05e84999a83..2f007a589cd 100644
--- a/be/src/olap/column_predicate.h
+++ b/be/src/olap/column_predicate.h
@@ -52,6 +52,7 @@ enum class PredicateType {
     BF = 11,            // BloomFilter
     BITMAP_FILTER = 12, // BitmapFilter
     MATCH = 13,         // fulltext match
+    RANGE = 14,         // BKD index range search
 };
 
 inline std::string type_to_string(PredicateType type) {
@@ -208,6 +209,14 @@ public:
     virtual void set_page_ng_bf(std::unique_ptr<segment_v2::BloomFilter>) {
         DCHECK(false) << "should not reach here";
     }
+
+    virtual Status set_inverted_index_query_value(
+            std::unique_ptr<InvertedIndexQueryBase>& /*unused*/, const Schema& 
/*unused*/) const {
+        DCHECK(false) << "should not reach here";
+        return Status::Error<ErrorCode::NOT_IMPLEMENTED_ERROR>(
+                "set_inverted_index_query_value should not reach here.");
+    }
+
     uint32_t column_id() const { return _column_id; }
 
     bool opposite() const { return _opposite; }
diff --git a/be/src/olap/comparison_predicate.h 
b/be/src/olap/comparison_predicate.h
index 53149ea7ed4..d950ff28427 100644
--- a/be/src/olap/comparison_predicate.h
+++ b/be/src/olap/comparison_predicate.h
@@ -81,33 +81,11 @@ public:
         auto column_desc = schema.column(_column_id);
         std::string column_name = column_desc->name();
 
-        InvertedIndexQueryType query_type;
-        switch (PT) {
-        case PredicateType::EQ:
-            query_type = InvertedIndexQueryType::EQUAL_QUERY;
-            break;
-        case PredicateType::NE:
-            query_type = InvertedIndexQueryType::EQUAL_QUERY;
-            break;
-        case PredicateType::LT:
-            query_type = InvertedIndexQueryType::LESS_THAN_QUERY;
-            break;
-        case PredicateType::LE:
-            query_type = InvertedIndexQueryType::LESS_EQUAL_QUERY;
-            break;
-        case PredicateType::GT:
-            query_type = InvertedIndexQueryType::GREATER_THAN_QUERY;
-            break;
-        case PredicateType::GE:
-            query_type = InvertedIndexQueryType::GREATER_EQUAL_QUERY;
-            break;
-        default:
-            return Status::InvalidArgument("invalid comparison predicate type 
{}", PT);
-        }
-
         roaring::Roaring roaring;
-        RETURN_IF_ERROR(iterator->read_from_inverted_index(column_name, 
&_value, query_type,
-                                                           num_rows, 
&roaring));
+        std::unique_ptr<InvertedIndexQueryBase> query_value = nullptr;
+        RETURN_IF_ERROR(set_inverted_index_query_value(query_value, schema));
+        RETURN_IF_ERROR(iterator->read_from_inverted_index(column_name, 
query_value.get(), num_rows,
+                                                           &roaring));
 
         // mask out null_bitmap, since NULL cmp VALUE will produce NULL
         //  and be treated as false in WHERE
@@ -305,6 +283,52 @@ public:
         return PT == PredicateType::EQ && !ngram;
     }
 
+    Status 
set_inverted_index_query_value(std::unique_ptr<InvertedIndexQueryBase>& 
query_value,
+                                          const Schema& schema) const override 
{
+        if (query_value == nullptr) {
+            auto column_desc = schema.column(_column_id);
+            if constexpr (PT == PredicateType::EQ || PT == PredicateType::NE) {
+                query_value = std::make_unique<InvertedIndexPointQuery<Type, 
PT>>(
+                        column_desc->type_info());
+            } else {
+                query_value = std::make_unique<InvertedIndexRangeQuery<Type, 
PredicateType::RANGE>>(
+                        column_desc->type_info());
+            }
+        }
+        if constexpr (PT == PredicateType::EQ || PT == PredicateType::NE) {
+            auto q = static_cast<InvertedIndexPointQuery<Type, 
PT>*>(query_value.get());
+            RETURN_IF_ERROR(q->add_value(_value, 
InvertedIndexQueryType::EQUAL_QUERY));
+        } else {
+            InvertedIndexQueryType query_type = 
InvertedIndexQueryType::UNKNOWN_QUERY;
+            switch (PT) {
+            case PredicateType::EQ:
+                query_type = InvertedIndexQueryType::EQUAL_QUERY;
+                break;
+            case PredicateType::NE:
+                query_type = InvertedIndexQueryType::EQUAL_QUERY;
+                break;
+            case PredicateType::LT:
+                query_type = InvertedIndexQueryType::LESS_THAN_QUERY;
+                break;
+            case PredicateType::LE:
+                query_type = InvertedIndexQueryType::LESS_EQUAL_QUERY;
+                break;
+            case PredicateType::GT:
+                query_type = InvertedIndexQueryType::GREATER_THAN_QUERY;
+                break;
+            case PredicateType::GE:
+                query_type = InvertedIndexQueryType::GREATER_EQUAL_QUERY;
+                break;
+            default:
+                LOG(ERROR) << Status::InvalidArgument("invalid comparison 
predicate type {}", PT);
+            }
+            auto q = static_cast<InvertedIndexRangeQuery<Type, 
PredicateType::RANGE>*>(
+                    query_value.get());
+            RETURN_IF_ERROR(q->add_value(_value, query_type));
+        }
+        return Status::OK();
+    }
+
     void evaluate_or(const vectorized::IColumn& column, const uint16_t* sel, 
uint16_t size,
                      bool* flags) const override {
         _evaluate_bit<false>(column, sel, size, flags);
diff --git a/be/src/olap/in_list_predicate.h b/be/src/olap/in_list_predicate.h
index 329c9b8dc0e..682ef3eed95 100644
--- a/be/src/olap/in_list_predicate.h
+++ b/be/src/olap/in_list_predicate.h
@@ -221,6 +221,23 @@ public:
         return Status::OK();
     }
 
+    Status 
set_inverted_index_query_value(std::unique_ptr<InvertedIndexQueryBase>& 
query_value,
+                                          const Schema& schema) const override 
{
+        if (query_value == nullptr) {
+            auto column_desc = schema.column(_column_id);
+            query_value =
+                    std::make_unique<InvertedIndexPointQuery<Type, 
PT>>(column_desc->type_info());
+        }
+        HybridSetBase::IteratorBase* iter = _values->begin();
+        while (iter->has_next()) {
+            const T* value = reinterpret_cast<const T*>(iter->get_value());
+            auto q = static_cast<InvertedIndexPointQuery<Type, 
PT>*>(query_value.get());
+            RETURN_IF_ERROR(q->add_value(*value, 
InvertedIndexQueryType::EQUAL_QUERY));
+            iter->next();
+        }
+        return Status::OK();
+    }
+
     Status evaluate(const Schema& schema, InvertedIndexIterator* iterator, 
uint32_t num_rows,
                     roaring::Roaring* result) const override {
         if (iterator == nullptr) {
@@ -228,18 +245,11 @@ public:
         }
         auto column_desc = schema.column(_column_id);
         std::string column_name = column_desc->name();
+        std::unique_ptr<InvertedIndexQueryBase> query_value = nullptr;
+        RETURN_IF_ERROR(set_inverted_index_query_value(query_value, schema));
         roaring::Roaring indices;
-        HybridSetBase::IteratorBase* iter = _values->begin();
-        while (iter->has_next()) {
-            const void* value = iter->get_value();
-            InvertedIndexQueryType query_type = 
InvertedIndexQueryType::EQUAL_QUERY;
-            roaring::Roaring index;
-            RETURN_IF_ERROR(iterator->read_from_inverted_index(column_name, 
value, query_type,
-                                                               num_rows, 
&index));
-            indices |= index;
-            iter->next();
-        }
-
+        RETURN_IF_ERROR(iterator->read_from_inverted_index(column_name, 
query_value.get(), num_rows,
+                                                           &indices));
         // mask out null_bitmap, since NULL cmp VALUE will produce NULL
         //  and be treated as false in WHERE
         // keep it after query, since query will try to read null_bitmap and 
put it to cache
diff --git a/be/src/olap/match_predicate.cpp b/be/src/olap/match_predicate.cpp
index 61d25723155..8e6bf2413ff 100644
--- a/be/src/olap/match_predicate.cpp
+++ b/be/src/olap/match_predicate.cpp
@@ -59,14 +59,26 @@ Status MatchPredicate::evaluate(const Schema& schema, 
InvertedIndexIterator* ite
         int32_t length = _value.length();
         char* buffer = const_cast<char*>(_value.c_str());
         match_value.replace(buffer, length); //is it safe?
-        RETURN_IF_ERROR(iterator->read_from_inverted_index(
-                column_desc->name(), &match_value, inverted_index_query_type, 
num_rows, &roaring));
+        //TODO: need consider TYPE_CHAR/TYPE_VARCHAR
+        auto query_value =
+                std::make_unique<InvertedIndexPointQuery<TYPE_STRING, 
PredicateType::MATCH>>(
+                        column_desc->type_info());
+        RETURN_IF_ERROR(query_value->add_value(match_value, 
inverted_index_query_type));
+
+        
RETURN_IF_ERROR(iterator->read_from_inverted_index(column_desc->name(), 
query_value.get(),
+                                                           num_rows, 
&roaring));
     } else if (column_desc->type() == FieldType::OLAP_FIELD_TYPE_ARRAY &&
                
is_numeric_type(column_desc->get_sub_field(0)->type_info()->type())) {
         char buf[column_desc->get_sub_field(0)->type_info()->size()];
         column_desc->get_sub_field(0)->from_string(buf, _value);
-        RETURN_IF_ERROR(iterator->read_from_inverted_index(
-                column_desc->name(), buf, inverted_index_query_type, num_rows, 
&roaring, true));
+
+        std::unique_ptr<InvertedIndexQueryBase> query_value = nullptr;
+        RETURN_IF_ERROR(
+                
InvertedIndexQueryBase::create_and_add_value_from_field_type<PredicateType::MATCH>(
+                        column_desc->get_sub_field(0)->type_info(), buf, 
inverted_index_query_type,
+                        query_value));
+        
RETURN_IF_ERROR(iterator->read_from_inverted_index(column_desc->name(), 
query_value.get(),
+                                                           num_rows, &roaring, 
true));
     }
 
     // mask out null_bitmap, since NULL cmp VALUE will produce NULL
@@ -126,4 +138,4 @@ bool MatchPredicate::_skip_evaluate(InvertedIndexIterator* 
iterator) const {
     return false;
 }
 
-} // namespace doris
\ No newline at end of file
+} // namespace doris
diff --git a/be/src/olap/olap_common.h b/be/src/olap/olap_common.h
index e1c5717fcd0..712349cbb73 100644
--- a/be/src/olap/olap_common.h
+++ b/be/src/olap/olap_common.h
@@ -347,7 +347,11 @@ struct OlapReaderStatistics {
 
     int64_t rows_inverted_index_filtered = 0;
     int64_t inverted_index_filter_timer = 0;
+    int64_t inverted_index_block_column_predicate_filter_timer = 0;
+    int64_t inverted_index_column_predicate_filter_timer = 0;
+    int64_t inverted_index_try_query_timer = 0;
     int64_t inverted_index_query_timer = 0;
+    int64_t inverted_index_bkd_intersect_timer = 0;
     int64_t inverted_index_query_cache_hit = 0;
     int64_t inverted_index_query_cache_miss = 0;
     int64_t inverted_index_query_bitmap_copy_timer = 0;
diff --git 
a/be/src/olap/rowset/segment_v2/inverted_index/query/disjunction_query.cpp 
b/be/src/olap/rowset/segment_v2/inverted_index/query/disjunction_query.cpp
index 07a159b3222..3487d4275e6 100644
--- a/be/src/olap/rowset/segment_v2/inverted_index/query/disjunction_query.cpp
+++ b/be/src/olap/rowset/segment_v2/inverted_index/query/disjunction_query.cpp
@@ -36,12 +36,11 @@ DisjunctionQuery::~DisjunctionQuery() {
 
 void DisjunctionQuery::add(const std::wstring& field_name, const 
std::vector<std::string>& terms) {
     if (terms.size() < 1) {
-        _CLTHROWA(CL_ERR_IllegalArgument, "ConjunctionQuery::add: terms.size() 
< 1");
+        _CLTHROWA(CL_ERR_IllegalArgument, "DisjunctionQuery::add: terms.size() 
< 1");
     }
 
     for (auto& term : terms) {
         std::wstring ws_term = StringUtil::string_to_wstring(term);
-        _wsterms.emplace_back(&ws_term);
         Term* t = _CLNEW Term(field_name.c_str(), ws_term.c_str());
         _terms.push_back(t);
         TermDocs* term_doc = _reader->termDocs(t);
diff --git 
a/be/src/olap/rowset/segment_v2/inverted_index/query/disjunction_query.h 
b/be/src/olap/rowset/segment_v2/inverted_index/query/disjunction_query.h
index f42fd69dabc..bb0a837f42a 100644
--- a/be/src/olap/rowset/segment_v2/inverted_index/query/disjunction_query.h
+++ b/be/src/olap/rowset/segment_v2/inverted_index/query/disjunction_query.h
@@ -39,7 +39,6 @@ public:
 
 private:
     IndexReader* _reader = nullptr;
-    std::vector<std::wstring*> _wsterms;
     std::vector<Term*> _terms;
     std::vector<TermDocs*> _term_docs;
     std::vector<TermIterator> _term_iterators;
diff --git 
a/be/src/olap/rowset/segment_v2/inverted_index/query/inverted_index_query.cpp 
b/be/src/olap/rowset/segment_v2/inverted_index/query/inverted_index_query.cpp
new file mode 100644
index 00000000000..10762c58e21
--- /dev/null
+++ 
b/be/src/olap/rowset/segment_v2/inverted_index/query/inverted_index_query.cpp
@@ -0,0 +1,314 @@
+// 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 "inverted_index_query.h"
+
+#include <filesystem>
+#include <set>
+
+#include "io/fs/file_system.h"
+#include "olap/column_predicate.h"
+#include "olap/key_coder.h"
+#include "olap/olap_common.h"
+#include "olap/rowset/segment_v2/inverted_index_cache.h"
+#include "olap/types.h"
+#include "util/time.h"
+#include "vec/common/string_ref.h"
+
+namespace doris::segment_v2 {
+
+template <PrimitiveType Type, PredicateType PT>
+Status Helper<Type, PT>::create_and_add_value(const TypeInfo* type_info, char* 
value,
+                                              InvertedIndexQueryType t,
+                                              
std::unique_ptr<InvertedIndexQueryBase>& result) {
+    using CppType = typename 
PredicatePrimitiveTypeTraits<Type>::PredicateFieldType;
+
+    if (is_range_query(t)) {
+        auto range_query_ptr = std::make_unique<InvertedIndexRangeQuery<Type, 
PT>>(type_info);
+        
RETURN_IF_ERROR(range_query_ptr->add_value(*reinterpret_cast<CppType*>(value), 
t));
+        result = std::move(range_query_ptr);
+    } else {
+        auto point_query_ptr = std::make_unique<InvertedIndexPointQuery<Type, 
PT>>(type_info);
+        
RETURN_IF_ERROR(point_query_ptr->add_value(*reinterpret_cast<CppType*>(value), 
t));
+        result = std::move(point_query_ptr);
+    }
+
+    return Status::OK();
+}
+
+template <PredicateType PT>
+Status InvertedIndexQueryBase::create_and_add_value_from_field_type(
+        const TypeInfo* type_info, char* value, InvertedIndexQueryType t,
+        std::unique_ptr<InvertedIndexQueryBase>& result) {
+    Status st;
+    switch (type_info->type()) {
+    case FieldType::OLAP_FIELD_TYPE_DATETIME: {
+        st = Helper<PrimitiveType::TYPE_DATETIME, 
PT>::create_and_add_value(type_info, value, t,
+                                                                            
result);
+        break;
+    }
+    case FieldType::OLAP_FIELD_TYPE_DATE: {
+        st = Helper<PrimitiveType::TYPE_DATE, 
PT>::create_and_add_value(type_info, value, t,
+                                                                        
result);
+        break;
+    }
+    case FieldType::OLAP_FIELD_TYPE_DATETIMEV2: {
+        st = Helper<PrimitiveType::TYPE_DATETIMEV2, 
PT>::create_and_add_value(type_info, value, t,
+                                                                              
result);
+        break;
+    }
+    case FieldType::OLAP_FIELD_TYPE_DATEV2: {
+        st = Helper<PrimitiveType::TYPE_DATEV2, 
PT>::create_and_add_value(type_info, value, t,
+                                                                          
result);
+        break;
+    }
+    case FieldType::OLAP_FIELD_TYPE_TINYINT: {
+        st = Helper<PrimitiveType::TYPE_TINYINT, 
PT>::create_and_add_value(type_info, value, t,
+                                                                           
result);
+        break;
+    }
+    case FieldType::OLAP_FIELD_TYPE_SMALLINT: {
+        st = Helper<PrimitiveType::TYPE_SMALLINT, 
PT>::create_and_add_value(type_info, value, t,
+                                                                            
result);
+        break;
+    }
+    case FieldType::OLAP_FIELD_TYPE_INT: {
+        st = Helper<PrimitiveType::TYPE_INT, 
PT>::create_and_add_value(type_info, value, t, result);
+        break;
+    }
+    case FieldType::OLAP_FIELD_TYPE_LARGEINT: {
+        st = Helper<PrimitiveType::TYPE_LARGEINT, 
PT>::create_and_add_value(type_info, value, t,
+                                                                            
result);
+        break;
+    }
+    case FieldType::OLAP_FIELD_TYPE_DECIMAL32: {
+        st = Helper<PrimitiveType::TYPE_DECIMAL32, 
PT>::create_and_add_value(type_info, value, t,
+                                                                             
result);
+        break;
+    }
+    case FieldType::OLAP_FIELD_TYPE_DECIMAL64: {
+        st = Helper<PrimitiveType::TYPE_DECIMAL64, 
PT>::create_and_add_value(type_info, value, t,
+                                                                             
result);
+        break;
+    }
+    case FieldType::OLAP_FIELD_TYPE_DECIMAL128I: {
+        st = Helper<PrimitiveType::TYPE_DECIMAL128I, 
PT>::create_and_add_value(type_info, value, t,
+                                                                               
result);
+        break;
+    }
+    case FieldType::OLAP_FIELD_TYPE_DOUBLE: {
+        st = Helper<PrimitiveType::TYPE_DOUBLE, 
PT>::create_and_add_value(type_info, value, t,
+                                                                          
result);
+        break;
+    }
+    case FieldType::OLAP_FIELD_TYPE_FLOAT: {
+        st = Helper<PrimitiveType::TYPE_FLOAT, 
PT>::create_and_add_value(type_info, value, t,
+                                                                         
result);
+        break;
+    }
+    case FieldType::OLAP_FIELD_TYPE_BIGINT: {
+        st = Helper<PrimitiveType::TYPE_BIGINT, 
PT>::create_and_add_value(type_info, value, t,
+                                                                          
result);
+        break;
+    }
+    case FieldType::OLAP_FIELD_TYPE_BOOL: {
+        st = Helper<PrimitiveType::TYPE_BOOLEAN, 
PT>::create_and_add_value(type_info, value, t,
+                                                                           
result);
+        break;
+    }
+    case FieldType::OLAP_FIELD_TYPE_CHAR: {
+        st = Helper<PrimitiveType::TYPE_CHAR, 
PT>::create_and_add_value(type_info, value, t,
+                                                                        
result);
+        break;
+    }
+    case FieldType::OLAP_FIELD_TYPE_VARCHAR: {
+        st = Helper<PrimitiveType::TYPE_VARCHAR, 
PT>::create_and_add_value(type_info, value, t,
+                                                                           
result);
+        break;
+    }
+    case FieldType::OLAP_FIELD_TYPE_STRING: {
+        st = Helper<PrimitiveType::TYPE_STRING, 
PT>::create_and_add_value(type_info, value, t,
+                                                                          
result);
+        break;
+    }
+    default:
+        return Status::NotSupported("Unsupported column type for inverted 
index {}",
+                                    type_info->type());
+    }
+    if (!st.ok()) {
+        return st;
+    }
+    return Status::OK();
+}
+
+template Status 
InvertedIndexQueryBase::create_and_add_value_from_field_type<PredicateType::MATCH>(
+        const TypeInfo*, char*, InvertedIndexQueryType, 
std::unique_ptr<InvertedIndexQueryBase>&);
+
+template <PrimitiveType Type, PredicateType PT>
+InvertedIndexPointQuery<Type, PT>::InvertedIndexPointQuery(const TypeInfo* 
type_info)
+        : _type_info(type_info) {
+    _value_key_coder = get_key_coder(type_info->type());
+}
+
+template <PrimitiveType Type, PredicateType PT>
+std::string InvertedIndexPointQuery<Type, PT>::to_string() {
+    std::string result;
+    if constexpr (std::is_same_v<T, StringRef>) {
+        for (const T* v : _values) {
+            result += v->to_string();
+        }
+    } else {
+        for (auto& v : _values) {
+            result += _type_info->to_string(v);
+        }
+    }
+    return result;
+}
+
+template <PrimitiveType Type, PredicateType PT>
+Status InvertedIndexPointQuery<Type, PT>::add_value(const T& value, 
InvertedIndexQueryType t) {
+    if constexpr (std::is_same_v<T, StringRef>) {
+        auto act_len = strnlen(value.data, value.size);
+        std::string value_str(value.data, act_len);
+        _values_encoded.push_back(value_str);
+    } else {
+        std::string tmp;
+        _value_key_coder->full_encode_ascending(&value, &tmp);
+        _values_encoded.push_back(tmp);
+    }
+    _values.push_back(&value);
+    _type = t;
+    return Status::OK();
+}
+
+template <PrimitiveType Type, PredicateType PT>
+InvertedIndexRangeQuery<Type, PT>::InvertedIndexRangeQuery(const TypeInfo* 
type_info)
+        : _type_info(type_info) {
+    _value_key_coder = get_key_coder(type_info->type());
+    auto max_v = type_limit<T>::max();
+    auto min_v = type_limit<T>::min();
+    _value_key_coder->full_encode_ascending(&max_v, &_high_value_encoded);
+    _value_key_coder->full_encode_ascending(&min_v, &_low_value_encoded);
+}
+
+template <PrimitiveType Type, PredicateType PT>
+std::string InvertedIndexRangeQuery<Type, PT>::to_string() {
+    std::string low_op = _inclusive_low ? ">=" : ">";
+    std::string high_op = _inclusive_high ? "<=" : "<";
+    std::string buffer;
+    if (_low_value != nullptr) {
+        buffer.append(_type_info->to_string(_low_value) + low_op + " ");
+    }
+    if (_high_value != nullptr) {
+        buffer.append(_type_info->to_string(_high_value) + high_op);
+    }
+    return buffer;
+};
+
+template <PrimitiveType Type, PredicateType PT>
+Status InvertedIndexRangeQuery<Type, PT>::add_value(const T& value, 
InvertedIndexQueryType t) {
+    switch (t) {
+    case InvertedIndexQueryType::GREATER_THAN_QUERY: {
+        _low_value = &value;
+        _low_value_encoded.clear();
+        _value_key_coder->full_encode_ascending(&value, &_low_value_encoded);
+        break;
+    }
+
+    case InvertedIndexQueryType::GREATER_EQUAL_QUERY: {
+        _low_value = &value;
+        _inclusive_low = true;
+        _low_value_encoded.clear();
+        _value_key_coder->full_encode_ascending(&value, &_low_value_encoded);
+        break;
+    }
+
+    case InvertedIndexQueryType::LESS_THAN_QUERY: {
+        _high_value = &value;
+        _high_value_encoded.clear();
+        _value_key_coder->full_encode_ascending(&value, &_high_value_encoded);
+        break;
+    }
+
+    case InvertedIndexQueryType::LESS_EQUAL_QUERY: {
+        _high_value = &value;
+        _inclusive_high = true;
+        _high_value_encoded.clear();
+        _value_key_coder->full_encode_ascending(&value, &_high_value_encoded);
+        break;
+    }
+    case InvertedIndexQueryType::EQUAL_QUERY: {
+        _high_value = _low_value = &value;
+        _high_value_encoded.clear();
+        _value_key_coder->full_encode_ascending(&value, &_high_value_encoded);
+        _low_value_encoded.clear();
+        _value_key_coder->full_encode_ascending(&value, &_low_value_encoded);
+        break;
+    }
+    default: {
+        return Status::InternalError("Add value failed! Unsupported 
PredicateType {}", PT);
+    }
+    }
+    return Status::OK();
+}
+
+#define INSTANTIATE_FOR_TYPE_AND_PREDICATE(P, C)          \
+    template class C<TYPE_BOOLEAN, PredicateType::P>;     \
+    template class C<TYPE_INT, PredicateType::P>;         \
+    template class C<TYPE_TINYINT, PredicateType::P>;     \
+    template class C<TYPE_SMALLINT, PredicateType::P>;    \
+    template class C<TYPE_BIGINT, PredicateType::P>;      \
+    template class C<TYPE_LARGEINT, PredicateType::P>;    \
+    template class C<TYPE_FLOAT, PredicateType::P>;       \
+    template class C<TYPE_DOUBLE, PredicateType::P>;      \
+    template class C<TYPE_CHAR, PredicateType::P>;        \
+    template class C<TYPE_STRING, PredicateType::P>;      \
+    template class C<TYPE_VARCHAR, PredicateType::P>;     \
+    template class C<TYPE_TIME, PredicateType::P>;        \
+    template class C<TYPE_TIMEV2, PredicateType::P>;      \
+    template class C<TYPE_DATE, PredicateType::P>;        \
+    template class C<TYPE_DATEV2, PredicateType::P>;      \
+    template class C<TYPE_DATETIME, PredicateType::P>;    \
+    template class C<TYPE_DATETIMEV2, PredicateType::P>;  \
+    template class C<TYPE_DECIMALV2, PredicateType::P>;   \
+    template class C<TYPE_DECIMAL32, PredicateType::P>;   \
+    template class C<TYPE_DECIMAL64, PredicateType::P>;   \
+    template class C<TYPE_DECIMAL128I, PredicateType::P>; \
+    template class C<TYPE_DECIMAL256, PredicateType::P>;  \
+    template class C<TYPE_IPV4, PredicateType::P>;        \
+    template class C<TYPE_IPV6, PredicateType::P>;
+
+#define INSTANTIATE_FOR_TYPE(C)                          \
+    INSTANTIATE_FOR_TYPE_AND_PREDICATE(EQ, C)            \
+    INSTANTIATE_FOR_TYPE_AND_PREDICATE(NE, C)            \
+    INSTANTIATE_FOR_TYPE_AND_PREDICATE(LT, C)            \
+    INSTANTIATE_FOR_TYPE_AND_PREDICATE(LE, C)            \
+    INSTANTIATE_FOR_TYPE_AND_PREDICATE(GT, C)            \
+    INSTANTIATE_FOR_TYPE_AND_PREDICATE(GE, C)            \
+    INSTANTIATE_FOR_TYPE_AND_PREDICATE(IN_LIST, C)       \
+    INSTANTIATE_FOR_TYPE_AND_PREDICATE(NOT_IN_LIST, C)   \
+    INSTANTIATE_FOR_TYPE_AND_PREDICATE(IS_NULL, C)       \
+    INSTANTIATE_FOR_TYPE_AND_PREDICATE(IS_NOT_NULL, C)   \
+    INSTANTIATE_FOR_TYPE_AND_PREDICATE(BF, C)            \
+    INSTANTIATE_FOR_TYPE_AND_PREDICATE(BITMAP_FILTER, C) \
+    INSTANTIATE_FOR_TYPE_AND_PREDICATE(MATCH, C)         \
+    INSTANTIATE_FOR_TYPE_AND_PREDICATE(RANGE, C)
+
+INSTANTIATE_FOR_TYPE(InvertedIndexPointQuery)
+INSTANTIATE_FOR_TYPE(InvertedIndexRangeQuery)
+
+} // namespace doris::segment_v2
diff --git 
a/be/src/olap/rowset/segment_v2/inverted_index/query/inverted_index_query.h 
b/be/src/olap/rowset/segment_v2/inverted_index/query/inverted_index_query.h
new file mode 100644
index 00000000000..466fefeac78
--- /dev/null
+++ b/be/src/olap/rowset/segment_v2/inverted_index/query/inverted_index_query.h
@@ -0,0 +1,220 @@
+// 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.
+
+#pragma once
+
+#include <CLucene/util/FutureArrays.h>
+#include <CLucene/util/bkd/bkd_reader.h>
+
+#include <memory>
+#include <string>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "common/status.h"
+#include "io/fs/file_system.h"
+#include "io/fs/path.h"
+#include "olap/inverted_index_parser.h"
+#include "olap/rowset/segment_v2/inverted_index_cache.h"
+#include "olap/rowset/segment_v2/inverted_index_compound_reader.h"
+#include "olap/rowset/segment_v2/inverted_index_desc.h"
+#include "olap/rowset/segment_v2/inverted_index_query_type.h"
+#include "olap/tablet_schema.h"
+#include "runtime/primitive_type.h"
+#include "runtime/type_limit.h"
+
+namespace lucene {
+namespace store {
+class Directory;
+} // namespace store
+namespace util::bkd {
+class bkd_docid_set_iterator;
+} // namespace util::bkd
+} // namespace lucene
+namespace roaring {
+class Roaring;
+} // namespace roaring
+
+namespace doris {
+class KeyCoder;
+class TypeInfo;
+struct OlapReaderStatistics;
+class RuntimeState;
+enum class PredicateType;
+
+namespace segment_v2 {
+
+enum class QueryCategory { POINT_QUERY, RANGE_QUERY };
+
+class InvertedIndexQueryBase {
+public:
+    virtual std::string to_string() = 0;
+    virtual ~InvertedIndexQueryBase() = default;
+    virtual QueryCategory get_query_category() = 0;
+    [[nodiscard]] virtual PredicateType get_predicate_type() const = 0;
+    template <PredicateType PT>
+    static Status create_and_add_value_from_field_type(
+            const TypeInfo* type_info, char* value, InvertedIndexQueryType t,
+            std::unique_ptr<InvertedIndexQueryBase>& result);
+};
+
+template <PrimitiveType Type, PredicateType PT>
+struct Helper;
+
+class InvertedIndexPointQueryI : public InvertedIndexQueryBase {
+public:
+    InvertedIndexPointQueryI() = default;
+    ~InvertedIndexPointQueryI() override = default;
+    QueryCategory get_query_category() override { return 
QueryCategory::POINT_QUERY; }
+    std::string to_string() override {
+        LOG_FATAL("Execution reached an undefined behavior code path in 
InvertedIndexPointQueryI");
+        __builtin_unreachable();
+    }
+    [[nodiscard]] PredicateType get_predicate_type() const override {
+        LOG_FATAL("Execution reached an undefined behavior code path in 
InvertedIndexPointQueryI");
+        __builtin_unreachable();
+    }
+    [[nodiscard]] virtual const std::vector<std::string>& get_values() const {
+        LOG_FATAL("Execution reached an undefined behavior code path in 
InvertedIndexPointQueryI");
+        __builtin_unreachable();
+    };
+    [[nodiscard]] virtual InvertedIndexQueryType get_query_type() const {
+        LOG_FATAL("Execution reached an undefined behavior code path in 
InvertedIndexPointQueryI");
+        __builtin_unreachable();
+    };
+};
+
+template <PrimitiveType Type, PredicateType PT>
+class InvertedIndexPointQuery : public InvertedIndexPointQueryI {
+public:
+    using T = typename PredicatePrimitiveTypeTraits<Type>::PredicateFieldType;
+    InvertedIndexPointQuery(const TypeInfo* type_info);
+
+    Status add_value(const T& value, InvertedIndexQueryType t);
+    std::string to_string() override;
+    [[nodiscard]] const std::vector<std::string>& get_values() const override {
+        return _values_encoded;
+    };
+    [[nodiscard]] PredicateType get_predicate_type() const override { return 
PT; };
+    [[nodiscard]] InvertedIndexQueryType get_query_type() const override { 
return _type; };
+
+private:
+    std::vector<std::string> _values_encoded;
+    const KeyCoder* _value_key_coder {};
+    const TypeInfo* _type_info {};
+    std::vector<const T*> _values;
+    InvertedIndexQueryType _type;
+};
+
+template <PrimitiveType Type, PredicateType PT>
+struct Helper {
+    static Status create_and_add_value(const TypeInfo* type_info, char* value,
+                                       InvertedIndexQueryType t,
+                                       
std::unique_ptr<InvertedIndexQueryBase>& result);
+};
+
+class InvertedIndexRangeQueryI : public InvertedIndexQueryBase {
+public:
+    InvertedIndexRangeQueryI() = default;
+    ~InvertedIndexRangeQueryI() override = default;
+    [[nodiscard]] virtual const std::string& get_low_value() const = 0;
+    [[nodiscard]] virtual const std::string& get_high_value() const = 0;
+    virtual bool low_value_is_null() = 0;
+    virtual bool high_value_is_null() = 0;
+    QueryCategory get_query_category() override { return 
QueryCategory::RANGE_QUERY; }
+    std::string to_string() override {
+        LOG_FATAL("Execution reached an undefined behavior code path in 
InvertedIndexRangeQueryI");
+        __builtin_unreachable();
+    };
+    [[nodiscard]] PredicateType get_predicate_type() const override {
+        LOG_FATAL("Execution reached an undefined behavior code path in 
InvertedIndexRangeQueryI");
+        __builtin_unreachable();
+    };
+    [[nodiscard]] virtual bool is_low_value_inclusive() const {
+        LOG_FATAL("Execution reached an undefined behavior code path in 
InvertedIndexRangeQueryI");
+        __builtin_unreachable();
+    }
+    [[nodiscard]] virtual bool is_high_value_inclusive() const {
+        LOG_FATAL("Execution reached an undefined behavior code path in 
InvertedIndexRangeQueryI");
+        __builtin_unreachable();
+    }
+};
+
+class BinaryType {
+    ENABLE_FACTORY_CREATOR(BinaryType);
+
+public:
+    const uint8_t* _data {};
+    size_t _size {};
+
+    BinaryType() = default;
+    BinaryType(const uint8_t* data, size_t size) : _data(data), _size(size) {}
+    BinaryType(const std::string& str)
+            : _data(reinterpret_cast<const uint8_t*>(str.data())), 
_size(str.size()) {}
+
+    int operator<(const BinaryType& other) const {
+        return lucene::util::FutureArrays::CompareUnsigned(_data, 0, _size, 
other._data, 0,
+                                                           other._size) < 0;
+    }
+
+    int operator<=(const BinaryType& other) const {
+        return lucene::util::FutureArrays::CompareUnsigned(_data, 0, _size, 
other._data, 0,
+                                                           other._size) <= 0;
+    }
+
+    int operator>(const BinaryType& other) const {
+        return lucene::util::FutureArrays::CompareUnsigned(_data, 0, _size, 
other._data, 0,
+                                                           other._size) > 0;
+    }
+
+    int operator>=(const BinaryType& other) const {
+        return lucene::util::FutureArrays::CompareUnsigned(_data, 0, _size, 
other._data, 0,
+                                                           other._size) >= 0;
+    }
+};
+
+template <PrimitiveType Type, PredicateType PT>
+class InvertedIndexRangeQuery : public InvertedIndexRangeQueryI {
+public:
+    using T = typename PredicatePrimitiveTypeTraits<Type>::PredicateFieldType;
+    InvertedIndexRangeQuery(const TypeInfo* type_info);
+    Status add_value(const T& value, InvertedIndexQueryType t);
+    [[nodiscard]] const std::string& get_low_value() const override { return 
_low_value_encoded; };
+    [[nodiscard]] const std::string& get_high_value() const override {
+        return _high_value_encoded;
+    };
+    bool low_value_is_null() override { return _low_value == nullptr; };
+    bool high_value_is_null() override { return _high_value == nullptr; };
+    std::string to_string() override;
+    [[nodiscard]] PredicateType get_predicate_type() const override { return 
PT; };
+    [[nodiscard]] bool is_low_value_inclusive() const override { return 
_inclusive_low; }
+    [[nodiscard]] bool is_high_value_inclusive() const override { return 
_inclusive_high; }
+
+private:
+    const T* _low_value {};
+    const T* _high_value {};
+    std::string _low_value_encoded {};
+    std::string _high_value_encoded {};
+
+    const KeyCoder* _value_key_coder {};
+    const TypeInfo* _type_info {};
+    bool _inclusive_high {};
+    bool _inclusive_low {};
+};
+} // namespace segment_v2
+} // namespace doris
\ No newline at end of file
diff --git a/be/src/olap/rowset/segment_v2/inverted_index/query/range_query.cpp 
b/be/src/olap/rowset/segment_v2/inverted_index/query/range_query.cpp
new file mode 100644
index 00000000000..abf18b5d861
--- /dev/null
+++ b/be/src/olap/rowset/segment_v2/inverted_index/query/range_query.cpp
@@ -0,0 +1,128 @@
+// 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 "range_query.h"
+
+namespace doris {
+
+RangeQuery::RangeQuery(IndexReader* reader) : _reader(reader) {}
+
+RangeQuery::~RangeQuery() {
+    for (auto& term_doc : _term_docs) {
+        if (term_doc) {
+            _CLDELETE(term_doc);
+        }
+    }
+}
+
+Status RangeQuery::add(const std::wstring& field_name, 
InvertedIndexRangeQueryI* query) {
+    std::unique_ptr<lucene::index::Term, void (*)(lucene::index::Term*)> 
lower_term(
+            nullptr, [](lucene::index::Term* term) { _CLDECDELETE(term); });
+    std::unique_ptr<lucene::index::Term, void (*)(lucene::index::Term*)> 
upper_term(
+            nullptr, [](lucene::index::Term* term) { _CLDECDELETE(term); });
+
+    if (query->low_value_is_null() && query->high_value_is_null()) {
+        return Status::Error<ErrorCode::INVERTED_INDEX_INVALID_PARAMETERS>(
+                "StringTypeInvertedIndexReader::handle_range_query error: both 
low_value and "
+                "high_value is null");
+    }
+    auto search_low = query->get_low_value();
+    if (!query->low_value_is_null()) {
+        std::wstring search_low_ws = StringUtil::string_to_wstring(search_low);
+        lower_term.reset(_CLNEW lucene::index::Term(field_name.c_str(), 
search_low_ws.c_str()));
+    } else {
+        lower_term.reset(_CLNEW Term(field_name.c_str(), L""));
+    }
+    auto search_high = query->get_high_value();
+    if (!query->high_value_is_null()) {
+        std::wstring search_high_ws = 
StringUtil::string_to_wstring(search_high);
+        upper_term.reset(_CLNEW lucene::index::Term(field_name.c_str(), 
search_high_ws.c_str()));
+    }
+
+    auto* _enumerator = _reader->terms(lower_term.get());
+    Term* lastTerm = nullptr;
+    try {
+        bool checkLower = false;
+        if (!query->is_low_value_inclusive()) { // make adjustments to set to 
exclusive
+            checkLower = true;
+        }
+
+        do {
+            lastTerm = _enumerator->term();
+            if (lastTerm != nullptr && lastTerm->field() == field_name) {
+                if (!checkLower || _tcscmp(lastTerm->text(), 
lower_term->text()) > 0) {
+                    checkLower = false;
+                    if (upper_term != nullptr) {
+                        int compare = _tcscmp(upper_term->text(), 
lastTerm->text());
+                        /* if beyond the upper term, or is exclusive and
+                             * this is equal to the upper term, break out */
+                        if ((compare < 0) || 
(!query->is_high_value_inclusive() && compare == 0)) {
+                            break;
+                        }
+                    }
+                    TermDocs* term_doc = _reader->termDocs(lastTerm);
+                    _term_docs.push_back(term_doc);
+                    _term_iterators.emplace_back(term_doc);
+                }
+            } else {
+                break;
+            }
+            _CLDECDELETE(lastTerm);
+        } while (_enumerator->next());
+    } catch (CLuceneError& e) {
+        _CLDECDELETE(lastTerm);
+        _enumerator->close();
+        _CLDELETE(_enumerator);
+        return Status::Error<ErrorCode::INVERTED_INDEX_CLUCENE_ERROR>(
+                "CLuceneError occured, error msg: {}, search_str: {}", 
e.what(),
+                query->to_string());
+    }
+    _CLDECDELETE(lastTerm);
+    _enumerator->close();
+    _CLDELETE(_enumerator);
+    return Status::OK();
+}
+
+void RangeQuery::search(roaring::Roaring& roaring) {
+    roaring::Roaring result;
+    auto func = [&roaring](const TermIterator& term_docs, bool first) {
+        roaring::Roaring result;
+        DocRange doc_range;
+        while (term_docs.readRange(&doc_range)) {
+            if (doc_range.type_ == DocRangeType::kMany) {
+                result.addMany(doc_range.doc_many_size_, 
doc_range.doc_many->data());
+            } else {
+                result.addRange(doc_range.doc_range.first, 
doc_range.doc_range.second);
+            }
+        }
+        if (first) {
+            roaring.swap(result);
+        } else {
+            roaring |= result;
+        }
+    };
+    for (int i = 0; i < _term_iterators.size(); i++) {
+        auto& iter = _term_iterators[i];
+        if (i == 0) {
+            func(iter, true);
+        } else {
+            func(iter, false);
+        }
+    }
+}
+
+} // namespace doris
\ No newline at end of file
diff --git 
a/be/src/olap/rowset/segment_v2/inverted_index/query/disjunction_query.h 
b/be/src/olap/rowset/segment_v2/inverted_index/query/range_query.h
similarity index 74%
copy from be/src/olap/rowset/segment_v2/inverted_index/query/disjunction_query.h
copy to be/src/olap/rowset/segment_v2/inverted_index/query/range_query.h
index f42fd69dabc..47873d83e0b 100644
--- a/be/src/olap/rowset/segment_v2/inverted_index/query/disjunction_query.h
+++ b/be/src/olap/rowset/segment_v2/inverted_index/query/range_query.h
@@ -23,26 +23,27 @@
 #include <CLucene/index/Term.h>
 #include <CLucene/search/query/TermIterator.h>
 
+#include "inverted_index_query.h"
 #include "roaring/roaring.hh"
 
 CL_NS_USE(index)
 
 namespace doris {
+using namespace segment_v2;
 
-class DisjunctionQuery {
+class RangeQuery {
 public:
-    DisjunctionQuery(IndexReader* reader);
-    ~DisjunctionQuery();
+    RangeQuery(IndexReader* reader);
+    ~RangeQuery();
 
-    void add(const std::wstring& field_name, const std::vector<std::string>& 
terms);
+    Status add(const std::wstring& field_name, InvertedIndexRangeQueryI* 
query);
     void search(roaring::Roaring& roaring);
+    [[nodiscard]] size_t get_terms_size() const { return _term_docs.size(); }
 
 private:
     IndexReader* _reader = nullptr;
-    std::vector<std::wstring*> _wsterms;
-    std::vector<Term*> _terms;
-    std::vector<TermDocs*> _term_docs;
-    std::vector<TermIterator> _term_iterators;
+    std::vector<TermDocs*> _term_docs {};
+    std::vector<TermIterator> _term_iterators {};
 };
 
 } // namespace doris
\ No newline at end of file
diff --git a/be/src/olap/rowset/segment_v2/inverted_index_query_type.h 
b/be/src/olap/rowset/segment_v2/inverted_index_query_type.h
index 1ebfe635918..23a1f3b6bd9 100644
--- a/be/src/olap/rowset/segment_v2/inverted_index_query_type.h
+++ b/be/src/olap/rowset/segment_v2/inverted_index_query_type.h
@@ -32,8 +32,22 @@ enum class InvertedIndexQueryType {
     MATCH_ANY_QUERY = 5,
     MATCH_ALL_QUERY = 6,
     MATCH_PHRASE_QUERY = 7,
+    RANGE_QUERY = 8,
 };
 
+inline bool is_range_query(InvertedIndexQueryType query_type) {
+    return (query_type == InvertedIndexQueryType::GREATER_THAN_QUERY ||
+            query_type == InvertedIndexQueryType::GREATER_EQUAL_QUERY ||
+            query_type == InvertedIndexQueryType::LESS_THAN_QUERY ||
+            query_type == InvertedIndexQueryType::LESS_EQUAL_QUERY);
+}
+
+inline bool is_match_query(InvertedIndexQueryType query_type) {
+    return (query_type == InvertedIndexQueryType::MATCH_ANY_QUERY ||
+            query_type == InvertedIndexQueryType::MATCH_ALL_QUERY ||
+            query_type == InvertedIndexQueryType::MATCH_PHRASE_QUERY);
+}
+
 inline std::string InvertedIndexQueryType_toString(InvertedIndexQueryType 
query_type) {
     switch (query_type) {
     case InvertedIndexQueryType::UNKNOWN_QUERY: {
@@ -63,6 +77,9 @@ inline std::string 
InvertedIndexQueryType_toString(InvertedIndexQueryType query_
     case InvertedIndexQueryType::MATCH_PHRASE_QUERY: {
         return "MPHRASE";
     }
+    case InvertedIndexQueryType::RANGE_QUERY: {
+        return "RANGE";
+    }
     default:
         return "";
     }
diff --git a/be/src/olap/rowset/segment_v2/inverted_index_reader.cpp 
b/be/src/olap/rowset/segment_v2/inverted_index_reader.cpp
index 0969a7545ad..7653f557287 100644
--- a/be/src/olap/rowset/segment_v2/inverted_index_reader.cpp
+++ b/be/src/olap/rowset/segment_v2/inverted_index_reader.cpp
@@ -20,51 +20,49 @@
 #include <CLucene/analysis/AnalysisHeader.h>
 #include <CLucene/analysis/Analyzers.h>
 #include <CLucene/analysis/LanguageBasedAnalyzer.h>
-#include <CLucene/analysis/standard/StandardAnalyzer.h>
-#include <CLucene/clucene-config.h>
-#include <CLucene/config/repl_wchar.h>
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wshadow-field"
+#endif
+#include "CLucene/analysis/standard95/StandardAnalyzer.h"
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
 #include <CLucene/debug/error.h>
 #include <CLucene/debug/mem.h>
-#include <CLucene/index/IndexReader.h>
 #include <CLucene/index/Term.h>
 #include <CLucene/search/IndexSearcher.h>
 #include <CLucene/search/PhraseQuery.h>
 #include <CLucene/search/Query.h>
-#include <CLucene/search/RangeQuery.h>
 #include <CLucene/search/TermQuery.h>
 #include <CLucene/store/Directory.h>
 #include <CLucene/store/IndexInput.h>
 #include <CLucene/util/CLStreams.h>
-#include <CLucene/util/FutureArrays.h>
 #include <CLucene/util/bkd/bkd_docid_iterator.h>
 #include <CLucene/util/stringUtil.h>
-#include <math.h>
-#include <string.h>
 
-#include <algorithm>
 #include <filesystem>
 #include <ostream>
 #include <roaring/roaring.hh>
 #include <set>
 
-#include "CLucene/analysis/standard95/StandardAnalyzer.h"
 #include "common/config.h"
 #include "common/logging.h"
-#include "io/fs/file_system.h"
+#include "common/status.h"
+#include "olap/column_predicate.h"
 #include "olap/inverted_index_parser.h"
-#include "olap/key_coder.h"
 #include "olap/olap_common.h"
 #include 
"olap/rowset/segment_v2/inverted_index/char_filter/char_filter_factory.h"
 #include "olap/rowset/segment_v2/inverted_index/query/conjunction_query.h"
+#include "olap/rowset/segment_v2/inverted_index/query/disjunction_query.h"
+#include "olap/rowset/segment_v2/inverted_index/query/range_query.h"
 #include "olap/rowset/segment_v2/inverted_index_cache.h"
 #include "olap/rowset/segment_v2/inverted_index_compound_directory.h"
-#include "olap/rowset/segment_v2/inverted_index_desc.h"
 #include "olap/types.h"
 #include "runtime/runtime_state.h"
 #include "util/faststring.h"
 #include "util/runtime_profile.h"
 #include "util/time.h"
-#include "vec/common/string_ref.h"
 
 #define FINALIZE_INPUT(x) \
     if (x != nullptr) {   \
@@ -77,21 +75,7 @@
     } catch (...) {               \
     }
 
-namespace doris {
-namespace segment_v2 {
-
-bool InvertedIndexReader::_is_range_query(InvertedIndexQueryType query_type) {
-    return (query_type == InvertedIndexQueryType::GREATER_THAN_QUERY ||
-            query_type == InvertedIndexQueryType::GREATER_EQUAL_QUERY ||
-            query_type == InvertedIndexQueryType::LESS_THAN_QUERY ||
-            query_type == InvertedIndexQueryType::LESS_EQUAL_QUERY);
-}
-
-bool InvertedIndexReader::_is_match_query(InvertedIndexQueryType query_type) {
-    return (query_type == InvertedIndexQueryType::MATCH_ANY_QUERY ||
-            query_type == InvertedIndexQueryType::MATCH_ALL_QUERY ||
-            query_type == InvertedIndexQueryType::MATCH_PHRASE_QUERY);
-}
+namespace doris::segment_v2 {
 
 bool InvertedIndexReader::indexExists(io::Path& index_file_path) {
     bool exists = false;
@@ -154,8 +138,7 @@ std::vector<std::string> 
InvertedIndexReader::get_analyse_result(
 
     while (token_stream->next(&token)) {
         if (token.termLength<char>() != 0) {
-            analyse_result.emplace_back(
-                    std::string(token.termBuffer<char>(), 
token.termLength<char>()));
+            analyse_result.emplace_back(token.termBuffer<char>(), 
token.termLength<char>());
         }
     }
 
@@ -185,7 +168,7 @@ Status 
InvertedIndexReader::read_null_bitmap(InvertedIndexQueryCacheHandle* cach
         auto index_file_path = index_dir / index_file_name;
         InvertedIndexQueryCache::CacheKey cache_key {
                 index_file_path, "", InvertedIndexQueryType::UNKNOWN_QUERY, 
"null_bitmap"};
-        auto cache = InvertedIndexQueryCache::instance();
+        auto* cache = InvertedIndexQueryCache::instance();
         if (cache->lookup(cache_key, cache_handle)) {
             return Status::OK();
         }
@@ -209,15 +192,15 @@ Status 
InvertedIndexReader::read_null_bitmap(InvertedIndexQueryCacheHandle* cach
             *null_bitmap = 
roaring::Roaring::read(reinterpret_cast<char*>(buf.data()), false);
             null_bitmap->runOptimize();
             cache->insert(cache_key, null_bitmap, cache_handle);
-            FINALIZE_INPUT(null_bitmap_in);
+            FINALIZE_INPUT(null_bitmap_in)
         }
         if (owned_dir) {
-            FINALIZE_INPUT(dir);
+            FINALIZE_INPUT(dir)
         }
     } catch (CLuceneError& e) {
-        FINALLY_FINALIZE_INPUT(null_bitmap_in);
+        FINALLY_FINALIZE_INPUT(null_bitmap_in)
         if (owned_dir) {
-            FINALLY_FINALIZE_INPUT(dir);
+            FINALLY_FINALIZE_INPUT(dir)
         }
         return Status::Error<doris::ErrorCode::INVERTED_INDEX_CLUCENE_ERROR>(
                 "Inverted index read null bitmap error occurred, reason={}", 
e.what());
@@ -232,31 +215,16 @@ Status 
FullTextIndexReader::new_iterator(OlapReaderStatistics* stats, RuntimeSta
     return Status::OK();
 }
 
-Status FullTextIndexReader::query(OlapReaderStatistics* stats, RuntimeState* 
runtime_state,
-                                  const std::string& column_name, const void* 
query_value,
-                                  InvertedIndexQueryType query_type, 
roaring::Roaring* bit_map) {
-    SCOPED_RAW_TIMER(&stats->inverted_index_query_timer);
-
-    std::string search_str = reinterpret_cast<const 
StringRef*>(query_value)->to_string();
+Status FullTextIndexReader::_query(OlapReaderStatistics* stats, RuntimeState* 
runtime_state,
+                                   const std::string& column_name, 
std::string& search_str,
+                                   InvertedIndexQueryType query_type, 
roaring::Roaring* bit_map) {
     LOG(INFO) << column_name << " begin to search the fulltext index from 
clucene, query_str ["
               << search_str << "]";
 
-    io::Path path(_path);
-    auto index_dir = path.parent_path();
-    auto index_file_name =
-            InvertedIndexDescriptor::get_index_file_name(path.filename(), 
_index_meta.index_id());
-    auto index_file_path = index_dir / index_file_name;
-    InvertedIndexCtxSPtr inverted_index_ctx = 
std::make_shared<InvertedIndexCtx>();
-    inverted_index_ctx->parser_type = 
get_inverted_index_parser_type_from_string(
-            get_parser_string_from_properties(_index_meta.properties()));
-    inverted_index_ctx->parser_mode =
-            get_parser_mode_string_from_properties(_index_meta.properties());
-    inverted_index_ctx->char_filter_map =
-            
get_parser_char_filter_map_from_properties(_index_meta.properties());
     try {
-        auto analyzer = create_analyzer(inverted_index_ctx.get());
-        auto reader = create_reader(inverted_index_ctx.get(), search_str);
-        inverted_index_ctx->analyzer = analyzer.get();
+        auto analyzer = create_analyzer(_inverted_index_ctx.get());
+        auto reader = create_reader(_inverted_index_ctx.get(), search_str);
+        _inverted_index_ctx->analyzer = analyzer.get();
         std::vector<std::string> analyse_result =
                 get_analyse_result(reader.get(), analyzer.get(), column_name, 
query_type);
 
@@ -270,21 +238,22 @@ Status FullTextIndexReader::query(OlapReaderStatistics* 
stats, RuntimeState* run
                 query_type == InvertedIndexQueryType::MATCH_PHRASE_QUERY) {
                 LOG(WARNING) << msg;
                 return Status::OK();
-            } else {
-                return Status::Error<ErrorCode::INVERTED_INDEX_NO_TERMS>(msg);
             }
+            return Status::Error<ErrorCode::INVERTED_INDEX_NO_TERMS>(msg);
         }
 
         // check index file existence
-        if (!indexExists(index_file_path)) {
+        if (!indexExists(_file_full_path)) {
             return Status::Error<ErrorCode::INVERTED_INDEX_FILE_NOT_FOUND>(
-                    "inverted index path: {} not exist.", 
index_file_path.string());
+                    "inverted index path: {} not exist.", 
_file_full_path.string());
         }
 
-        InvertedIndexCacheHandle inverted_index_cache_handle;
-        InvertedIndexSearcherCache::instance()->get_index_searcher(
-                _fs, index_dir.c_str(), index_file_name, 
&inverted_index_cache_handle, stats);
-        auto index_searcher = inverted_index_cache_handle.get_index_searcher();
+        auto get_index_search = [this, &stats]() {
+            InvertedIndexCacheHandle inverted_index_cache_handle;
+            
static_cast<void>(InvertedIndexSearcherCache::instance()->get_index_searcher(
+                    _fs, _file_dir.c_str(), _file_name, 
&inverted_index_cache_handle, stats));
+            return inverted_index_cache_handle.get_index_searcher();
+        };
 
         std::unique_ptr<lucene::search::Query> query;
         std::wstring field_ws = std::wstring(column_name.begin(), 
column_name.end());
@@ -299,76 +268,65 @@ Status FullTextIndexReader::query(OlapReaderStatistics* 
stats, RuntimeState* run
                 str_tokens += token;
                 str_tokens += " ";
             }
-
-            auto cache = InvertedIndexQueryCache::instance();
-            InvertedIndexQueryCache::CacheKey cache_key;
-            cache_key.index_path = index_file_path;
-            cache_key.column_name = column_name;
-            cache_key.query_type = query_type;
-            //auto str_tokens = lucene_wcstoutf8string(wstr_tokens.c_str(), 
wstr_tokens.length());
-            cache_key.value.swap(str_tokens);
-            InvertedIndexQueryCacheHandle cache_handle;
             std::shared_ptr<roaring::Roaring> term_match_bitmap = nullptr;
-            if (cache->lookup(cache_key, &cache_handle)) {
-                stats->inverted_index_query_cache_hit++;
-                term_match_bitmap = cache_handle.get_bitmap();
-            } else {
-                stats->inverted_index_query_cache_miss++;
-
-                term_match_bitmap = std::make_shared<roaring::Roaring>();
-
-                Status res = Status::OK();
-                if (query_type == InvertedIndexQueryType::MATCH_PHRASE_QUERY) {
-                    auto* phrase_query = new lucene::search::PhraseQuery();
-                    for (auto& token : analyse_result) {
-                        std::wstring wtoken = 
StringUtil::string_to_wstring(token);
-                        auto* term = _CLNEW 
lucene::index::Term(field_ws.c_str(), wtoken.c_str());
-                        phrase_query->add(term);
-                        _CLDECDELETE(term);
-                    }
-                    query.reset(phrase_query);
-                    res = normal_index_search(stats, query_type, 
index_searcher,
-                                              null_bitmap_already_read, query, 
term_match_bitmap);
-                } else {
-                    res = match_all_index_search(stats, runtime_state, 
field_ws, analyse_result,
-                                                 index_searcher, 
term_match_bitmap);
-                }
-                if (!res.ok()) {
-                    return res;
+            InvertedIndexQueryCache::CacheKey cache_key {_file_full_path, 
column_name, query_type,
+                                                         str_tokens};
+            auto* cache = InvertedIndexQueryCache::instance();
+            InvertedIndexQueryCacheHandle cache_handler;
+            auto cache_status = handle_cache(cache, cache_key, &cache_handler, 
stats, bit_map);
+            if (cache_status.ok()) {
+                return Status::OK();
+            }
+            auto index_searcher = get_index_search();
+            term_match_bitmap = std::make_shared<roaring::Roaring>();
+            Status res = Status::OK();
+            if (query_type == InvertedIndexQueryType::MATCH_PHRASE_QUERY) {
+                auto* phrase_query = new lucene::search::PhraseQuery();
+                for (auto& token : analyse_result) {
+                    std::wstring wtoken = StringUtil::string_to_wstring(token);
+                    auto* term = _CLNEW lucene::index::Term(field_ws.c_str(), 
wtoken.c_str());
+                    phrase_query->add(term);
+                    _CLDECDELETE(term)
                 }
-
-                // add to cache
-                term_match_bitmap->runOptimize();
-                cache->insert(cache_key, term_match_bitmap, &cache_handle);
+                query.reset(phrase_query);
+                res = normal_index_search(stats, query_type, index_searcher,
+                                          null_bitmap_already_read, query, 
term_match_bitmap);
+            } else {
+                res = match_all_index_search(stats, runtime_state, field_ws, 
analyse_result,
+                                             index_searcher, 
term_match_bitmap);
             }
+            if (!res.ok()) {
+                return res;
+            }
+
+            // add to cache
+            term_match_bitmap->runOptimize();
+            cache->insert(cache_key, term_match_bitmap, &cache_handler);
             query_match_bitmap = *term_match_bitmap;
+
         } else {
             bool first = true;
             for (auto token : analyse_result) {
                 std::shared_ptr<roaring::Roaring> term_match_bitmap = nullptr;
 
                 // try to get term bitmap match result from cache to avoid 
query index on cache hit
-                auto cache = InvertedIndexQueryCache::instance();
+                auto* cache = InvertedIndexQueryCache::instance();
                 // use EQUAL_QUERY type here since cache is for each term/token
-                //auto token = lucene_wcstoutf8string(token_ws.c_str(), 
token_ws.length());
                 std::wstring token_ws = StringUtil::string_to_wstring(token);
-
                 InvertedIndexQueryCache::CacheKey cache_key {
-                        index_file_path, column_name, 
InvertedIndexQueryType::EQUAL_QUERY, token};
-                VLOG_DEBUG << "cache_key:" << cache_key.encode();
-                InvertedIndexQueryCacheHandle cache_handle;
-                if (cache->lookup(cache_key, &cache_handle)) {
-                    stats->inverted_index_query_cache_hit++;
-                    term_match_bitmap = cache_handle.get_bitmap();
+                        _file_full_path, column_name, 
InvertedIndexQueryType::EQUAL_QUERY, token};
+                InvertedIndexQueryCacheHandle cache_handler;
+                auto cache_status = handle_cache(cache, cache_key, 
&cache_handler, stats, bit_map);
+                if (cache_status.ok()) {
+                    term_match_bitmap = cache_handler.get_bitmap();
                 } else {
-                    stats->inverted_index_query_cache_miss++;
-
+                    auto index_searcher = get_index_search();
                     term_match_bitmap = std::make_shared<roaring::Roaring>();
                     // unique_ptr with custom deleter
                     std::unique_ptr<lucene::index::Term, void 
(*)(lucene::index::Term*)> term {
                             _CLNEW lucene::index::Term(field_ws.c_str(), 
token_ws.c_str()),
-                            [](lucene::index::Term* term) { 
_CLDECDELETE(term); }};
-                    query.reset(new lucene::search::TermQuery(term.get()));
+                            [](lucene::index::Term* term) { _CLDECDELETE(term) 
}};
+                    query = 
std::make_unique<lucene::search::TermQuery>(term.get());
 
                     Status res =
                             normal_index_search(stats, query_type, 
index_searcher,
@@ -379,7 +337,7 @@ Status FullTextIndexReader::query(OlapReaderStatistics* 
stats, RuntimeState* run
 
                     // add to cache
                     term_match_bitmap->runOptimize();
-                    cache->insert(cache_key, term_match_bitmap, &cache_handle);
+                    cache->insert(cache_key, term_match_bitmap, 
&cache_handler);
                 }
 
                 // add to query_match_bitmap
@@ -412,6 +370,27 @@ Status FullTextIndexReader::query(OlapReaderStatistics* 
stats, RuntimeState* run
     }
 }
 
+Status FullTextIndexReader::query(OlapReaderStatistics* stats, RuntimeState* 
runtime_state,
+                                  const std::string& column_name,
+                                  InvertedIndexQueryBase* query_value, 
roaring::Roaring* bit_map) {
+    SCOPED_RAW_TIMER(&stats->inverted_index_query_timer);
+    const auto& tmp = static_cast<InvertedIndexPointQueryI*>(query_value);
+    auto values = tmp->get_values();
+    auto query_type = tmp->get_query_type();
+    auto query_bitmap = std::make_shared<roaring::Roaring>();
+
+    for (auto it = values.begin(); it != values.end(); ++it) {
+        RETURN_IF_ERROR(
+                _query(stats, runtime_state, column_name, *it, query_type, 
query_bitmap.get()));
+        if (it == values.begin()) {
+            *bit_map = *query_bitmap;
+        } else {
+            *bit_map |= *query_bitmap;
+        }
+    }
+    return Status::OK();
+}
+
 Status FullTextIndexReader::normal_index_search(
         OlapReaderStatistics* stats, InvertedIndexQueryType query_type,
         const IndexSearcherPtr& index_searcher, bool& null_bitmap_already_read,
@@ -487,87 +466,38 @@ Status StringTypeInvertedIndexReader::new_iterator(
     return Status::OK();
 }
 
-Status StringTypeInvertedIndexReader::query(OlapReaderStatistics* stats,
-                                            RuntimeState* runtime_state,
-                                            const std::string& column_name, 
const void* query_value,
-                                            InvertedIndexQueryType query_type,
-                                            roaring::Roaring* bit_map) {
-    SCOPED_RAW_TIMER(&stats->inverted_index_query_timer);
-
-    const StringRef* search_query = reinterpret_cast<const 
StringRef*>(query_value);
-    auto act_len = strnlen(search_query->data, search_query->size);
-    std::string search_str(search_query->data, act_len);
+Status StringTypeInvertedIndexReader::handle_range_query(const std::string& 
column_name,
+                                                         OlapReaderStatistics* 
stats,
+                                                         
InvertedIndexRangeQueryI* query,
+                                                         roaring::Roaring* 
bit_map) {
     // std::string search_str = reinterpret_cast<const 
StringRef*>(query_value)->to_string();
     VLOG_DEBUG << "begin to query the inverted index from clucene"
-               << ", column_name: " << column_name << ", search_str: " << 
search_str;
-    std::wstring column_name_ws = std::wstring(column_name.begin(), 
column_name.end());
-    std::wstring search_str_ws = StringUtil::string_to_wstring(search_str);
-    // unique_ptr with custom deleter
-    std::unique_ptr<lucene::index::Term, void (*)(lucene::index::Term*)> term {
-            _CLNEW lucene::index::Term(column_name_ws.c_str(), 
search_str_ws.c_str()),
-            [](lucene::index::Term* term) { _CLDECDELETE(term); }};
-    std::unique_ptr<lucene::search::Query> query;
-
-    io::Path path(_path);
-    auto index_dir = path.parent_path();
-    auto index_file_name =
-            InvertedIndexDescriptor::get_index_file_name(path.filename(), 
_index_meta.index_id());
-    auto index_file_path = index_dir / index_file_name;
-
-    // try to get query bitmap result from cache and return immediately on 
cache hit
-    InvertedIndexQueryCache::CacheKey cache_key {index_file_path, column_name, 
query_type,
-                                                 search_str};
-    auto cache = InvertedIndexQueryCache::instance();
-    InvertedIndexQueryCacheHandle cache_handle;
-    if (cache->lookup(cache_key, &cache_handle)) {
-        stats->inverted_index_query_cache_hit++;
-        SCOPED_RAW_TIMER(&stats->inverted_index_query_bitmap_copy_timer);
-        *bit_map = *cache_handle.get_bitmap();
-        return Status::OK();
-    } else {
-        stats->inverted_index_query_cache_miss++;
-    }
+               << ", column_name: " << column_name << ", search_str: " << 
query->to_string();
 
-    // check index file existence
-    if (!indexExists(index_file_path)) {
-        return Status::Error<ErrorCode::INVERTED_INDEX_FILE_NOT_FOUND>(
-                "inverted index path: {} not exist.", 
index_file_path.string());
-    }
-
-    switch (query_type) {
-    case InvertedIndexQueryType::MATCH_ANY_QUERY:
-    case InvertedIndexQueryType::MATCH_ALL_QUERY:
-    case InvertedIndexQueryType::MATCH_PHRASE_QUERY:
-    case InvertedIndexQueryType::EQUAL_QUERY: {
-        query.reset(new lucene::search::TermQuery(term.get()));
-        break;
-    }
-    case InvertedIndexQueryType::LESS_THAN_QUERY: {
-        query.reset(new lucene::search::RangeQuery(nullptr, term.get(), 
false));
-        break;
-    }
-    case InvertedIndexQueryType::LESS_EQUAL_QUERY: {
-        query.reset(new lucene::search::RangeQuery(nullptr, term.get(), true));
-        break;
-    }
-    case InvertedIndexQueryType::GREATER_THAN_QUERY: {
-        query.reset(new lucene::search::RangeQuery(term.get(), nullptr, 
false));
-        break;
-    }
-    case InvertedIndexQueryType::GREATER_EQUAL_QUERY: {
-        query.reset(new lucene::search::RangeQuery(term.get(), nullptr, true));
-        break;
-    }
-    default:
-        return Status::Error<ErrorCode::INVERTED_INDEX_NOT_SUPPORTED>(
-                "invalid query type when query untokenized inverted index");
+    InvertedIndexQueryCache::CacheKey cache_key {
+            _file_full_path, column_name, InvertedIndexQueryType::RANGE_QUERY, 
query->to_string()};
+    auto* cache = InvertedIndexQueryCache::instance();
+    InvertedIndexQueryCacheHandle cache_handler;
+    auto cache_status = handle_cache(cache, cache_key, &cache_handler, stats, 
bit_map);
+    if (cache_status.ok()) {
+        return Status::OK();
     }
 
     roaring::Roaring result;
     InvertedIndexCacheHandle inverted_index_cache_handle;
-    InvertedIndexSearcherCache::instance()->get_index_searcher(
-            _fs, index_dir.c_str(), index_file_name, 
&inverted_index_cache_handle, stats);
+    
static_cast<void>(InvertedIndexSearcherCache::instance()->get_index_searcher(
+            _fs, _file_dir, _file_name, &inverted_index_cache_handle, stats));
     auto index_searcher = inverted_index_cache_handle.get_index_searcher();
+    RangeQuery range_query(index_searcher->getReader());
+    std::wstring column_name_ws = std::wstring(column_name.begin(), 
column_name.end());
+
+    RETURN_IF_ERROR(range_query.add(column_name_ws, query));
+    if (range_query.get_terms_size() > config::inverted_index_max_terms) {
+        return Status::Error<ErrorCode::INVERTED_INDEX_BYPASS>(
+                "range query term exceeds limits, try to downgrade from 
inverted index, column "
+                "name:{}, search_str:{}",
+                column_name, query->to_string());
+    }
 
     // try to reuse index_searcher's directory to read null_bitmap to cache
     // to avoid open directory additionally for null_bitmap
@@ -575,48 +505,102 @@ Status 
StringTypeInvertedIndexReader::query(OlapReaderStatistics* stats,
     read_null_bitmap(&null_bitmap_cache_handle, 
index_searcher->getReader()->directory());
 
     try {
-        if (query_type == InvertedIndexQueryType::MATCH_ANY_QUERY ||
-            query_type == InvertedIndexQueryType::MATCH_ALL_QUERY ||
-            query_type == InvertedIndexQueryType::EQUAL_QUERY) {
-            SCOPED_RAW_TIMER(&stats->inverted_index_searcher_search_timer);
-            index_searcher->_search(query.get(), [&result](DocRange* 
doc_range) {
-                if (doc_range->type_ == DocRangeType::kMany) {
-                    result.addMany(doc_range->doc_many_size_, 
doc_range->doc_many->data());
-                } else {
-                    result.addRange(doc_range->doc_range.first, 
doc_range->doc_range.second);
-                }
-            });
-        } else {
-            SCOPED_RAW_TIMER(&stats->inverted_index_searcher_search_timer);
-            index_searcher->_search(query.get(),
-                                    [&result](const int32_t docid, const 
float_t /*score*/) {
-                                        // docid equal to rowid in segment
-                                        result.add(docid);
-                                    });
-        }
+        SCOPED_RAW_TIMER(&stats->inverted_index_searcher_search_timer);
+        range_query.search(result);
+
     } catch (const CLuceneError& e) {
-        if (_is_range_query(query_type) && e.number() == 
CL_ERR_TooManyClauses) {
+        if (e.number() == CL_ERR_TooManyClauses) {
             return Status::Error<ErrorCode::INVERTED_INDEX_BYPASS>(
                     "range query term exceeds limits, try to downgrade from 
inverted index, column "
                     "name:{}, search_str:{}",
-                    column_name, search_str);
-        } else {
-            return Status::Error<ErrorCode::INVERTED_INDEX_CLUCENE_ERROR>(
-                    "CLuceneError occured, error msg: {}, column name: {}, 
search_str: {}",
-                    e.what(), column_name, search_str);
+                    column_name, query->to_string());
         }
+        return Status::Error<ErrorCode::INVERTED_INDEX_CLUCENE_ERROR>(
+                "CLuceneError occured, error msg: {}, column name: {}, 
search_str: {}", e.what(),
+                column_name, query->to_string());
     }
 
+    // add to cache
+    std::shared_ptr<roaring::Roaring> range_query_bitmap =
+            std::make_shared<roaring::Roaring>(result);
+    range_query_bitmap->runOptimize();
+    cache->insert(cache_key, range_query_bitmap, &cache_handler);
+
+    bit_map->swap(result);
+    return Status::OK();
+}
+
+Status StringTypeInvertedIndexReader::handle_point_query(const std::string& 
column_name,
+                                                         OlapReaderStatistics* 
stats,
+                                                         
InvertedIndexPointQueryI* query,
+                                                         roaring::Roaring* 
bit_map) {
+    std::wstring column_name_ws = std::wstring(column_name.begin(), 
column_name.end());
+    auto values = query->get_values();
+
+    InvertedIndexQueryCache::CacheKey cache_key {_file_full_path, column_name,
+                                                 query->get_query_type(), 
query->to_string()};
+    auto* cache = InvertedIndexQueryCache::instance();
+    InvertedIndexQueryCacheHandle cache_handler;
+    auto cache_status = handle_cache(cache, cache_key, &cache_handler, stats, 
bit_map);
+    if (cache_status.ok()) {
+        return Status::OK();
+    }
+
+    roaring::Roaring result;
+    InvertedIndexCacheHandle inverted_index_cache_handle;
+    
static_cast<void>(InvertedIndexSearcherCache::instance()->get_index_searcher(
+            _fs, _file_dir, _file_name, &inverted_index_cache_handle, stats));
+    auto index_searcher = inverted_index_cache_handle.get_index_searcher();
+    DisjunctionQuery dis_query(index_searcher->getReader());
+    dis_query.add(column_name_ws, values);
+    try {
+        SCOPED_RAW_TIMER(&stats->inverted_index_searcher_search_timer);
+        dis_query.search(result);
+    } catch (const CLuceneError& e) {
+        return Status::Error<ErrorCode::INVERTED_INDEX_CLUCENE_ERROR>(
+                "CLuceneError occured, error msg: {}, column name: {}, 
search_str: {}", e.what(),
+                column_name, query->to_string());
+    }
+
+    // try to reuse index_searcher's directory to read null_bitmap to cache
+    // to avoid open directory additionally for null_bitmap
+    InvertedIndexQueryCacheHandle null_bitmap_cache_handle;
+    static_cast<void>(
+            read_null_bitmap(&null_bitmap_cache_handle, 
index_searcher->getReader()->directory()));
+
     // add to cache
     std::shared_ptr<roaring::Roaring> term_match_bitmap =
             std::make_shared<roaring::Roaring>(result);
     term_match_bitmap->runOptimize();
-    cache->insert(cache_key, term_match_bitmap, &cache_handle);
+    cache->insert(cache_key, term_match_bitmap, &cache_handler);
 
     bit_map->swap(result);
     return Status::OK();
 }
 
+Status StringTypeInvertedIndexReader::query(OlapReaderStatistics* stats,
+                                            RuntimeState* runtime_state,
+                                            const std::string& column_name,
+                                            InvertedIndexQueryBase* 
query_value,
+                                            roaring::Roaring* bit_map) {
+    SCOPED_RAW_TIMER(&stats->inverted_index_query_timer);
+    // check index file existence
+    if (!indexExists(_file_full_path)) {
+        return Status::Error<ErrorCode::INVERTED_INDEX_FILE_NOT_FOUND>(
+                "inverted index path: {} not exist.", 
_file_full_path.string());
+    }
+    if (query_value->get_query_category() == QueryCategory::RANGE_QUERY) {
+        const auto& tmp = static_cast<InvertedIndexRangeQueryI*>(query_value);
+        return handle_range_query(column_name, stats, tmp, bit_map);
+    }
+    if (query_value->get_query_category() == QueryCategory::POINT_QUERY) {
+        const auto& tmp = static_cast<InvertedIndexPointQueryI*>(query_value);
+        return handle_point_query(column_name, stats, tmp, bit_map);
+    }
+    return Status::Error<ErrorCode::INVERTED_INDEX_CLUCENE_ERROR>(
+            "bkd index query type not support:{}", 
query_value->get_query_category());
+}
+
 InvertedIndexReaderType StringTypeInvertedIndexReader::type() {
     return InvertedIndexReaderType::STRING_TYPE;
 }
@@ -624,20 +608,12 @@ InvertedIndexReaderType 
StringTypeInvertedIndexReader::type() {
 BkdIndexReader::BkdIndexReader(io::FileSystemSPtr fs, const std::string& path,
                                const TabletIndex* index_meta)
         : InvertedIndexReader(fs, path, index_meta), _compoundReader(nullptr) {
-    io::Path io_path(_path);
-    auto index_dir = io_path.parent_path();
-    auto index_file_name = 
InvertedIndexDescriptor::get_index_file_name(io_path.filename(),
-                                                                        
index_meta->index_id());
-
-    // check index file existence
-    auto index_file = index_dir / index_file_name;
-    if (!indexExists(index_file)) {
-        LOG(WARNING) << "bkd index: " << index_file.string() << " not exist.";
+    if (!indexExists(_file_full_path)) {
+        LOG(WARNING) << "bkd index: " << _file_full_path.string() << " not 
exist.";
         return;
     }
-    _file_full_path = index_file;
     _compoundReader = std::make_unique<DorisCompoundReader>(
-            DorisCompoundDirectory::getDirectory(fs, index_dir.c_str()), 
index_file_name.c_str(),
+            DorisCompoundDirectory::getDirectory(fs, _file_dir.c_str()), 
_file_name.c_str(),
             config::inverted_index_read_buffer_size);
 }
 
@@ -647,51 +623,22 @@ Status BkdIndexReader::new_iterator(OlapReaderStatistics* 
stats, RuntimeState* r
     return Status::OK();
 }
 
-Status BkdIndexReader::bkd_query(OlapReaderStatistics* stats, const 
std::string& column_name,
-                                 const void* query_value, 
InvertedIndexQueryType query_type,
-                                 
std::shared_ptr<lucene::util::bkd::bkd_reader> r,
-                                 InvertedIndexVisitor* visitor) {
-    char tmp[r->bytes_per_dim_];
-    switch (query_type) {
-    case InvertedIndexQueryType::EQUAL_QUERY: {
-        _value_key_coder->full_encode_ascending(query_value, 
&visitor->query_max);
-        _value_key_coder->full_encode_ascending(query_value, 
&visitor->query_min);
-        break;
-    }
-    case InvertedIndexQueryType::LESS_THAN_QUERY:
-    case InvertedIndexQueryType::LESS_EQUAL_QUERY: {
-        _value_key_coder->full_encode_ascending(query_value, 
&visitor->query_max);
-        _type_info->set_to_min(tmp);
-        _value_key_coder->full_encode_ascending(tmp, &visitor->query_min);
-        break;
-    }
-    case InvertedIndexQueryType::GREATER_THAN_QUERY:
-    case InvertedIndexQueryType::GREATER_EQUAL_QUERY: {
-        _value_key_coder->full_encode_ascending(query_value, 
&visitor->query_min);
-        _type_info->set_to_max(tmp);
-        _value_key_coder->full_encode_ascending(tmp, &visitor->query_max);
-        break;
-    }
-    default:
-        return Status::Error<ErrorCode::INVERTED_INDEX_NOT_SUPPORTED>(
-                "invalid query type when query bkd index");
-    }
-    visitor->set_reader(r.get());
-    return Status::OK();
-}
-
 Status BkdIndexReader::try_query(OlapReaderStatistics* stats, const 
std::string& column_name,
-                                 const void* query_value, 
InvertedIndexQueryType query_type,
-                                 uint32_t* count) {
-    auto visitor = std::make_unique<InvertedIndexVisitor>(nullptr, query_type, 
true);
+                                 InvertedIndexQueryBase* query_value, 
uint32_t* count) {
+    SCOPED_RAW_TIMER(&stats->inverted_index_query_timer);
+    SCOPED_RAW_TIMER(&stats->inverted_index_try_query_timer);
+    auto visitor = std::make_unique<InvertedIndexVisitor>(nullptr, 
query_value, true);
     std::shared_ptr<lucene::util::bkd::bkd_reader> r;
     RETURN_IF_ERROR(get_bkd_reader(&r));
-    std::string query_str;
-    _value_key_coder->full_encode_ascending(query_value, &query_str);
+    std::string query_str = query_value->to_string();
 
+    auto query_type =
+            (query_value->get_query_category() == QueryCategory::RANGE_QUERY)
+                    ? InvertedIndexQueryType::RANGE_QUERY
+                    : 
static_cast<InvertedIndexPointQueryI*>(query_value)->get_query_type();
     InvertedIndexQueryCache::CacheKey cache_key {_file_full_path, column_name, 
query_type,
-                                                 query_str};
-    auto cache = InvertedIndexQueryCache::instance();
+                                                 query_str + "__TRY__"};
+    auto* cache = InvertedIndexQueryCache::instance();
     InvertedIndexQueryCacheHandle cache_handler;
     roaring::Roaring bit_map;
     auto cache_status = handle_cache(cache, cache_key, &cache_handler, stats, 
&bit_map);
@@ -700,54 +647,37 @@ Status BkdIndexReader::try_query(OlapReaderStatistics* 
stats, const std::string&
         return Status::OK();
     }
     try {
-        auto st = bkd_query(stats, column_name, query_value, query_type, r, 
visitor.get());
-        if (!st.ok()) {
-            if (st.code() == ErrorCode::END_OF_FILE) {
-                return Status::OK();
-            }
-            LOG(WARNING) << "bkd_query for column " << column_name << " 
failed: " << st;
-            return st;
-        }
+        visitor->set_reader(r.get());
         *count = r->estimate_point_count(visitor.get());
+        bit_map.addRange(0, *count - 1);
     } catch (const CLuceneError& e) {
         return Status::Error<ErrorCode::INVERTED_INDEX_CLUCENE_ERROR>(
                 "BKD Query CLuceneError Occurred, error msg: {}", e.what());
     }
-
+    std::shared_ptr<roaring::Roaring> query_bitmap = 
std::make_shared<roaring::Roaring>(bit_map);
+    query_bitmap->runOptimize();
+    cache->insert(cache_key, query_bitmap, &cache_handler);
     VLOG_DEBUG << "BKD index try search column: " << column_name << " result: 
" << *count;
     return Status::OK();
 }
 
-Status BkdIndexReader::handle_cache(InvertedIndexQueryCache* cache,
-                                    const InvertedIndexQueryCache::CacheKey& 
cache_key,
-                                    InvertedIndexQueryCacheHandle* 
cache_handler,
-                                    OlapReaderStatistics* stats, 
roaring::Roaring* bit_map) {
-    if (cache->lookup(cache_key, cache_handler)) {
-        stats->inverted_index_query_cache_hit++;
-        SCOPED_RAW_TIMER(&stats->inverted_index_query_bitmap_copy_timer);
-        *bit_map = *cache_handler->get_bitmap();
-        return Status::OK();
-    } else {
-        stats->inverted_index_query_cache_miss++;
-        return Status::Error<ErrorCode::KEY_NOT_FOUND>("cache miss");
-    }
-}
-
 Status BkdIndexReader::query(OlapReaderStatistics* stats, RuntimeState* 
runtime_state,
-                             const std::string& column_name, const void* 
query_value,
-                             InvertedIndexQueryType query_type, 
roaring::Roaring* bit_map) {
+                             const std::string& column_name, 
InvertedIndexQueryBase* query_value,
+                             roaring::Roaring* bit_map) {
     SCOPED_RAW_TIMER(&stats->inverted_index_query_timer);
-
-    auto visitor = std::make_unique<InvertedIndexVisitor>(bit_map, query_type);
+    auto visitor = std::make_unique<InvertedIndexVisitor>(bit_map, 
query_value);
     std::shared_ptr<lucene::util::bkd::bkd_reader> r;
     RETURN_IF_ERROR(get_bkd_reader(&r));
 
-    std::string query_str;
-    _value_key_coder->full_encode_ascending(query_value, &query_str);
+    std::string query_str = query_value->to_string();
+    auto query_type =
+            (query_value->get_query_category() == QueryCategory::RANGE_QUERY)
+                    ? InvertedIndexQueryType::RANGE_QUERY
+                    : 
static_cast<InvertedIndexPointQueryI*>(query_value)->get_query_type();
 
     InvertedIndexQueryCache::CacheKey cache_key {_file_full_path, column_name, 
query_type,
                                                  query_str};
-    auto cache = InvertedIndexQueryCache::instance();
+    auto* cache = InvertedIndexQueryCache::instance();
     InvertedIndexQueryCacheHandle cache_handler;
     auto cache_status = handle_cache(cache, cache_key, &cache_handler, stats, 
bit_map);
     if (cache_status.ok()) {
@@ -755,14 +685,8 @@ Status BkdIndexReader::query(OlapReaderStatistics* stats, 
RuntimeState* runtime_
     }
 
     try {
-        auto st = bkd_query(stats, column_name, query_value, query_type, r, 
visitor.get());
-        if (!st.ok()) {
-            if (st.code() == ErrorCode::END_OF_FILE) {
-                return Status::OK();
-            }
-            LOG(WARNING) << "bkd_query for column " << column_name << " 
failed: " << st;
-            return st;
-        }
+        visitor->set_reader(r.get());
+        SCOPED_RAW_TIMER(&stats->inverted_index_bkd_intersect_timer);
         r->intersect(visitor.get());
     } catch (const CLuceneError& e) {
         return Status::Error<ErrorCode::INVERTED_INDEX_CLUCENE_ERROR>(
@@ -816,7 +740,6 @@ Status 
BkdIndexReader::get_bkd_reader(std::shared_ptr<lucene::util::bkd::bkd_rea
         return Status::Error<ErrorCode::INVERTED_INDEX_NOT_SUPPORTED>(
                 "unsupported typeinfo, type={}", (*bkdReader)->type);
     }
-    _value_key_coder = get_key_coder(_type_info->type());
     return Status::OK();
 }
 
@@ -824,47 +747,59 @@ InvertedIndexReaderType BkdIndexReader::type() {
     return InvertedIndexReaderType::BKD;
 }
 
-InvertedIndexVisitor::InvertedIndexVisitor(roaring::Roaring* h, 
InvertedIndexQueryType query_type,
-                                           bool only_count)
-        : _hits(h), _num_hits(0), _only_count(only_count), 
_query_type(query_type) {}
+InvertedIndexVisitor::InvertedIndexVisitor(roaring::Roaring* hits,
+                                           InvertedIndexQueryBase* 
query_value, bool only_count)
+        : _hits(hits),
+          _num_hits(0),
+          _only_count(only_count),
+          _low_op(PredicateType::GT),
+          _high_op(PredicateType::LT) {
+    if (query_value->get_query_category() == QueryCategory::RANGE_QUERY) {
+        auto* range_query = 
reinterpret_cast<InvertedIndexRangeQueryI*>(query_value);
+        query_max = range_query->get_high_value();
+        query_min = range_query->get_low_value();
+        if (range_query->is_low_value_inclusive()) {
+            _low_op = PredicateType::GE;
+        }
+        if (range_query->is_high_value_inclusive()) {
+            _high_op = PredicateType::LE;
+        }
+    } else if (query_value->get_query_category() == 
QueryCategory::POINT_QUERY) {
+        auto* point_query = 
reinterpret_cast<InvertedIndexPointQueryI*>(query_value);
+        for (const std::string& v : point_query->get_values()) {
+            query_points.emplace_back(v);
+        }
+        // =1 equals 1<= && >=1
+        _low_op = PredicateType::GE;
+        _high_op = PredicateType::LE;
+    }
+}
+
+bool InvertedIndexVisitor::_matches(const BinaryType& packed_value, const 
BinaryType& qmax,
+                                    const BinaryType& qmin) {
+    bool minInside = (_low_op == PredicateType::GE ? packed_value >= qmin : 
packed_value > qmin);
+    bool maxInside = (_high_op == PredicateType::LE ? packed_value <= qmax : 
packed_value < qmax);
+    return minInside && maxInside;
+}
 
 bool InvertedIndexVisitor::matches(uint8_t* packed_value) {
-    for (int dim = 0; dim < _reader->num_data_dims_; dim++) {
-        int offset = dim * _reader->bytes_per_dim_;
-        if (_query_type == InvertedIndexQueryType::LESS_THAN_QUERY) {
-            if (lucene::util::FutureArrays::CompareUnsigned(
-                        packed_value, offset, offset + _reader->bytes_per_dim_,
-                        (const uint8_t*)query_max.c_str(), offset,
-                        offset + _reader->bytes_per_dim_) >= 0) {
-                // Doc's value is too high, in this dimension
-                return false;
-            }
-        } else if (_query_type == InvertedIndexQueryType::GREATER_THAN_QUERY) {
-            if (lucene::util::FutureArrays::CompareUnsigned(
-                        packed_value, offset, offset + _reader->bytes_per_dim_,
-                        (const uint8_t*)query_min.c_str(), offset,
-                        offset + _reader->bytes_per_dim_) <= 0) {
-                // Doc's value is too high, in this dimension
-                return false;
-            }
-        } else {
-            if (lucene::util::FutureArrays::CompareUnsigned(
-                        packed_value, offset, offset + _reader->bytes_per_dim_,
-                        (const uint8_t*)query_min.c_str(), offset,
-                        offset + _reader->bytes_per_dim_) < 0) {
-                // Doc's value is too low, in this dimension
-                return false;
-            }
-            if (lucene::util::FutureArrays::CompareUnsigned(
-                        packed_value, offset, offset + _reader->bytes_per_dim_,
-                        (const uint8_t*)query_max.c_str(), offset,
-                        offset + _reader->bytes_per_dim_) > 0) {
-                // Doc's value is too high, in this dimension
+    auto dim_match = [&](const BinaryType& qmax, const BinaryType& qmin) -> 
bool {
+        for (int dim = 0; dim < _reader->num_data_dims_; dim++) {
+            int offset = dim * _reader->bytes_per_dim_;
+            if (!_matches(BinaryType(packed_value + offset, 
_reader->bytes_per_dim_),
+                          BinaryType(qmax._data + offset, 
_reader->bytes_per_dim_),
+                          BinaryType(qmin._data + offset, 
_reader->bytes_per_dim_))) {
                 return false;
             }
         }
+        return true;
+    };
+    if (!query_points.empty()) {
+        return std::ranges::any_of(query_points, [&dim_match](const 
BinaryType& query_point) {
+            return dim_match(query_point, query_point);
+        });
     }
-    return true;
+    return dim_match(query_max, query_min);
 }
 
 void InvertedIndexVisitor::visit(std::vector<char>& doc_id, 
std::vector<uint8_t>& packed_value) {
@@ -931,77 +866,72 @@ void InvertedIndexVisitor::visit(int row_id, 
std::vector<uint8_t>& packed_value)
     }
 }
 
-lucene::util::bkd::relation 
InvertedIndexVisitor::compare(std::vector<uint8_t>& min_packed,
-                                                          
std::vector<uint8_t>& max_packed) {
-    bool crosses = false;
+lucene::util::bkd::relation InvertedIndexVisitor::_compare(const BinaryType& 
min_packed,
+                                                           const BinaryType& 
max_packed,
+                                                           const BinaryType& 
qmax,
+                                                           const BinaryType& 
qmin) {
+    bool minOutside = (_high_op == PredicateType::LE ? min_packed > qmax : 
min_packed >= qmax);
+    bool maxOutside = (_low_op == PredicateType::GE ? max_packed < qmin : 
max_packed <= qmin);
+    bool minInside = (_low_op == PredicateType::GE ? min_packed >= qmin : 
min_packed > qmin);
+    bool maxInside = (_high_op == PredicateType::LE ? max_packed <= qmax : 
max_packed < qmax);
 
-    for (int dim = 0; dim < _reader->num_data_dims_; dim++) {
-        int offset = dim * _reader->bytes_per_dim_;
+    if (minOutside || maxOutside) {
+        return lucene::util::bkd::relation::CELL_OUTSIDE_QUERY;
+    }
 
-        if (_query_type == InvertedIndexQueryType::LESS_THAN_QUERY) {
-            if (lucene::util::FutureArrays::CompareUnsigned(
-                        min_packed.data(), offset, offset + 
_reader->bytes_per_dim_,
-                        (const uint8_t*)query_max.c_str(), offset,
-                        offset + _reader->bytes_per_dim_) >= 0) {
-                return lucene::util::bkd::relation::CELL_OUTSIDE_QUERY;
-            }
-        } else if (_query_type == InvertedIndexQueryType::GREATER_THAN_QUERY) {
-            if (lucene::util::FutureArrays::CompareUnsigned(
-                        max_packed.data(), offset, offset + 
_reader->bytes_per_dim_,
-                        (const uint8_t*)query_min.c_str(), offset,
-                        offset + _reader->bytes_per_dim_) <= 0) {
-                return lucene::util::bkd::relation::CELL_OUTSIDE_QUERY;
+    if (minInside && maxInside) {
+        return lucene::util::bkd::relation::CELL_INSIDE_QUERY;
+    }
+
+    return lucene::util::bkd::relation::CELL_CROSSES_QUERY;
+}
+
+lucene::util::bkd::relation 
InvertedIndexVisitor::compare(std::vector<uint8_t>& min_packed,
+                                                          
std::vector<uint8_t>& max_packed) {
+    auto dim_compare = [&](const BinaryType& qmax,
+                           const BinaryType& qmin) -> 
lucene::util::bkd::relation {
+        lucene::util::bkd::relation final_relation = 
lucene::util::bkd::relation::CELL_INSIDE_QUERY;
+        for (int dim = 0; dim < _reader->num_data_dims_; dim++) {
+            int offset = dim * _reader->bytes_per_dim_;
+            auto relation =
+                    _compare(BinaryType(min_packed.data() + offset, 
_reader->bytes_per_dim_),
+                             BinaryType(max_packed.data() + offset, 
_reader->bytes_per_dim_),
+                             BinaryType(qmax._data + offset, 
_reader->bytes_per_dim_),
+                             BinaryType(qmin._data + offset, 
_reader->bytes_per_dim_));
+            if (relation == lucene::util::bkd::relation::CELL_OUTSIDE_QUERY) {
+                return relation;
             }
-        } else {
-            if (lucene::util::FutureArrays::CompareUnsigned(
-                        min_packed.data(), offset, offset + 
_reader->bytes_per_dim_,
-                        (const uint8_t*)query_max.c_str(), offset,
-                        offset + _reader->bytes_per_dim_) > 0 ||
-                lucene::util::FutureArrays::CompareUnsigned(
-                        max_packed.data(), offset, offset + 
_reader->bytes_per_dim_,
-                        (const uint8_t*)query_min.c_str(), offset,
-                        offset + _reader->bytes_per_dim_) < 0) {
-                return lucene::util::bkd::relation::CELL_OUTSIDE_QUERY;
+            if (relation == lucene::util::bkd::relation::CELL_CROSSES_QUERY) {
+                final_relation = 
lucene::util::bkd::relation::CELL_CROSSES_QUERY;
             }
         }
-        if (_query_type == InvertedIndexQueryType::LESS_THAN_QUERY ||
-            _query_type == InvertedIndexQueryType::GREATER_THAN_QUERY) {
-            crosses |= lucene::util::FutureArrays::CompareUnsigned(
-                               min_packed.data(), offset, offset + 
_reader->bytes_per_dim_,
-                               (const uint8_t*)query_min.c_str(), offset,
-                               offset + _reader->bytes_per_dim_) <= 0 ||
-                       lucene::util::FutureArrays::CompareUnsigned(
-                               max_packed.data(), offset, offset + 
_reader->bytes_per_dim_,
-                               (const uint8_t*)query_max.c_str(), offset,
-                               offset + _reader->bytes_per_dim_) >= 0;
-        } else {
-            crosses |= lucene::util::FutureArrays::CompareUnsigned(
-                               min_packed.data(), offset, offset + 
_reader->bytes_per_dim_,
-                               (const uint8_t*)query_min.c_str(), offset,
-                               offset + _reader->bytes_per_dim_) < 0 ||
-                       lucene::util::FutureArrays::CompareUnsigned(
-                               max_packed.data(), offset, offset + 
_reader->bytes_per_dim_,
-                               (const uint8_t*)query_max.c_str(), offset,
-                               offset + _reader->bytes_per_dim_) > 0;
+        return final_relation;
+    };
+    if (!query_points.empty()) {
+        lucene::util::bkd::relation final_relation =
+                lucene::util::bkd::relation::CELL_OUTSIDE_QUERY;
+        for (auto query_point : query_points) {
+            lucene::util::bkd::relation relation = dim_compare(query_point, 
query_point);
+            if (relation == lucene::util::bkd::relation::CELL_INSIDE_QUERY) {
+                return relation;
+            }
+            if (relation == lucene::util::bkd::relation::CELL_CROSSES_QUERY) {
+                final_relation = 
lucene::util::bkd::relation::CELL_CROSSES_QUERY;
+            }
         }
+        return final_relation;
     }
-    if (crosses) {
-        return lucene::util::bkd::relation::CELL_CROSSES_QUERY;
-    } else {
-        return lucene::util::bkd::relation::CELL_INSIDE_QUERY;
-    }
+    return dim_compare(query_max, query_min);
 }
 
 Status InvertedIndexIterator::read_from_inverted_index(const std::string& 
column_name,
-                                                       const void* query_value,
-                                                       InvertedIndexQueryType 
query_type,
+                                                       InvertedIndexQueryBase* 
query_value,
                                                        uint32_t 
segment_num_rows,
                                                        roaring::Roaring* 
bit_map, bool skip_try) {
     if (!skip_try && _reader->type() == InvertedIndexReaderType::BKD) {
         auto query_bkd_limit_percent = 
config::query_bkd_inverted_index_limit_percent;
         uint32_t hit_count = 0;
-        RETURN_IF_ERROR(
-                try_read_from_inverted_index(column_name, query_value, 
query_type, &hit_count));
+        RETURN_IF_ERROR(try_read_from_inverted_index(column_name, query_value, 
&hit_count));
         if (hit_count > segment_num_rows * query_bkd_limit_percent / 100) {
             return Status::Error<ErrorCode::INVERTED_INDEX_BYPASS>(
                     "hit count: {}, bkd inverted reached limit {}%, segment 
num rows:{}", hit_count,
@@ -1009,22 +939,16 @@ Status 
InvertedIndexIterator::read_from_inverted_index(const std::string& column
         }
     }
 
-    RETURN_IF_ERROR(
-            _reader->query(_stats, _runtime_state, column_name, query_value, 
query_type, bit_map));
+    RETURN_IF_ERROR(_reader->query(_stats, _runtime_state, column_name, 
query_value, bit_map));
     return Status::OK();
 }
 
 Status InvertedIndexIterator::try_read_from_inverted_index(const std::string& 
column_name,
-                                                           const void* 
query_value,
-                                                           
InvertedIndexQueryType query_type,
+                                                           
InvertedIndexQueryBase* query_value,
                                                            uint32_t* count) {
     // NOTE: only bkd index support try read now.
-    if (query_type == InvertedIndexQueryType::GREATER_EQUAL_QUERY ||
-        query_type == InvertedIndexQueryType::GREATER_THAN_QUERY ||
-        query_type == InvertedIndexQueryType::LESS_EQUAL_QUERY ||
-        query_type == InvertedIndexQueryType::LESS_THAN_QUERY ||
-        query_type == InvertedIndexQueryType::EQUAL_QUERY) {
-        RETURN_IF_ERROR(_reader->try_query(_stats, column_name, query_value, 
query_type, count));
+    if (_reader->type() == InvertedIndexReaderType::BKD) {
+        RETURN_IF_ERROR(_reader->try_query(_stats, column_name, query_value, 
count));
     }
     return Status::OK();
 }
@@ -1037,5 +961,4 @@ const std::map<string, string>& 
InvertedIndexIterator::get_index_properties() co
     return _reader->get_index_properties();
 }
 
-} // namespace segment_v2
-} // namespace doris
+} // namespace doris::segment_v2
diff --git a/be/src/olap/rowset/segment_v2/inverted_index_reader.h 
b/be/src/olap/rowset/segment_v2/inverted_index_reader.h
index 20c5c731f9e..bd133dec801 100644
--- a/be/src/olap/rowset/segment_v2/inverted_index_reader.h
+++ b/be/src/olap/rowset/segment_v2/inverted_index_reader.h
@@ -18,7 +18,6 @@
 #pragma once
 
 #include <CLucene/util/bkd/bkd_reader.h>
-#include <stdint.h>
 
 #include <memory>
 #include <string>
@@ -29,20 +28,21 @@
 #include "io/fs/file_system.h"
 #include "io/fs/path.h"
 #include "olap/inverted_index_parser.h"
+#include "olap/rowset/segment_v2/inverted_index/query/inverted_index_query.h"
 #include "olap/rowset/segment_v2/inverted_index_cache.h"
 #include "olap/rowset/segment_v2/inverted_index_compound_reader.h"
+#include "olap/rowset/segment_v2/inverted_index_desc.h"
 #include "olap/rowset/segment_v2/inverted_index_query_type.h"
 #include "olap/tablet_schema.h"
+#include "runtime/type_limit.h"
 
 namespace lucene {
 namespace store {
 class Directory;
 } // namespace store
-namespace util {
-namespace bkd {
+namespace util::bkd {
 class bkd_docid_set_iterator;
-} // namespace bkd
-} // namespace util
+} // namespace util::bkd
 } // namespace lucene
 namespace roaring {
 class Roaring;
@@ -53,6 +53,7 @@ class KeyCoder;
 class TypeInfo;
 struct OlapReaderStatistics;
 class RuntimeState;
+enum class PredicateType;
 
 namespace segment_v2 {
 
@@ -72,18 +73,39 @@ class InvertedIndexReader : public 
std::enable_shared_from_this<InvertedIndexRea
 public:
     explicit InvertedIndexReader(io::FileSystemSPtr fs, const std::string& 
path,
                                  const TabletIndex* index_meta)
-            : _fs(fs), _path(path), _index_meta(*index_meta) {}
+            : _fs(std::move(fs)), _path(path), _index_meta(*index_meta) {
+        io::Path io_path(_path);
+        auto index_dir = io_path.parent_path();
+        auto index_file_name = 
InvertedIndexDescriptor::get_index_file_name(io_path.filename(),
+                                                                            
index_meta->index_id());
+        auto index_file_path = index_dir / index_file_name;
+        _file_full_path = index_file_path;
+        _file_name = index_file_name;
+        _file_dir = index_dir.c_str();
+    }
+    virtual Status handle_cache(InvertedIndexQueryCache* cache,
+                                const InvertedIndexQueryCache::CacheKey& 
cache_key,
+                                InvertedIndexQueryCacheHandle* cache_handler,
+                                OlapReaderStatistics* stats, roaring::Roaring* 
bit_map) {
+        if (cache->lookup(cache_key, cache_handler)) {
+            stats->inverted_index_query_cache_hit++;
+            SCOPED_RAW_TIMER(&stats->inverted_index_query_bitmap_copy_timer);
+            *bit_map = *cache_handler->get_bitmap();
+            return Status::OK();
+        }
+        stats->inverted_index_query_cache_miss++;
+        return Status::Error<ErrorCode::KEY_NOT_FOUND>("cache miss");
+    }
     virtual ~InvertedIndexReader() = default;
 
     // create a new column iterator. Client should delete returned iterator
     virtual Status new_iterator(OlapReaderStatistics* stats, RuntimeState* 
runtime_state,
                                 std::unique_ptr<InvertedIndexIterator>* 
iterator) = 0;
     virtual Status query(OlapReaderStatistics* stats, RuntimeState* 
runtime_state,
-                         const std::string& column_name, const void* 
query_value,
-                         InvertedIndexQueryType query_type, roaring::Roaring* 
bit_map) = 0;
+                         const std::string& column_name, 
InvertedIndexQueryBase* query_value,
+                         roaring::Roaring* bit_map) = 0;
     virtual Status try_query(OlapReaderStatistics* stats, const std::string& 
column_name,
-                             const void* query_value, InvertedIndexQueryType 
query_type,
-                             uint32_t* count) = 0;
+                             InvertedIndexQueryBase* query_value, uint32_t* 
count) = 0;
 
     Status read_null_bitmap(InvertedIndexQueryCacheHandle* cache_handle,
                             lucene::store::Directory* dir = nullptr);
@@ -108,31 +130,42 @@ public:
             InvertedIndexCtx* inverted_index_ctx);
 
 protected:
-    bool _is_range_query(InvertedIndexQueryType query_type);
-    bool _is_match_query(InvertedIndexQueryType query_type);
     friend class InvertedIndexIterator;
     io::FileSystemSPtr _fs;
     const std::string& _path;
     TabletIndex _index_meta;
+    io::Path _file_full_path;
+    std::string _file_name;
+    std::string _file_dir;
 };
 
 class FullTextIndexReader : public InvertedIndexReader {
     ENABLE_FACTORY_CREATOR(FullTextIndexReader);
 
+private:
+    InvertedIndexCtxSPtr _inverted_index_ctx {};
+
 public:
     explicit FullTextIndexReader(io::FileSystemSPtr fs, const std::string& 
path,
                                  const TabletIndex* index_meta)
-            : InvertedIndexReader(fs, path, index_meta) {}
+            : InvertedIndexReader(fs, path, index_meta) {
+        _inverted_index_ctx = std::make_shared<InvertedIndexCtx>();
+        _inverted_index_ctx->parser_type = 
get_inverted_index_parser_type_from_string(
+                get_parser_string_from_properties(_index_meta.properties()));
+        _inverted_index_ctx->parser_mode =
+                
get_parser_mode_string_from_properties(_index_meta.properties());
+        _inverted_index_ctx->char_filter_map =
+                
get_parser_char_filter_map_from_properties(_index_meta.properties());
+    }
     ~FullTextIndexReader() override = default;
 
     Status new_iterator(OlapReaderStatistics* stats, RuntimeState* 
runtime_state,
                         std::unique_ptr<InvertedIndexIterator>* iterator) 
override;
     Status query(OlapReaderStatistics* stats, RuntimeState* runtime_state,
-                 const std::string& column_name, const void* query_value,
-                 InvertedIndexQueryType query_type, roaring::Roaring* bit_map) 
override;
+                 const std::string& column_name, InvertedIndexQueryBase* 
query_value,
+                 roaring::Roaring* bit_map) override;
     Status try_query(OlapReaderStatistics* stats, const std::string& 
column_name,
-                     const void* query_value, InvertedIndexQueryType 
query_type,
-                     uint32_t* count) override {
+                     InvertedIndexQueryBase* query_value, uint32_t* count) 
override {
         return Status::Error<ErrorCode::NOT_IMPLEMENTED_ERROR>(
                 "FullTextIndexReader not support try_query");
     }
@@ -153,6 +186,9 @@ private:
                                   const std::shared_ptr<roaring::Roaring>& 
term_match_bitmap);
 
     void check_null_bitmap(const IndexSearcherPtr& index_searcher, bool& 
null_bitmap_already_read);
+    Status _query(OlapReaderStatistics* stats, RuntimeState* runtime_state,
+                  const std::string& column_name, std::string& search_str,
+                  InvertedIndexQueryType query_type, roaring::Roaring* 
bit_map);
 };
 
 class StringTypeInvertedIndexReader : public InvertedIndexReader {
@@ -167,14 +203,18 @@ public:
     Status new_iterator(OlapReaderStatistics* stats, RuntimeState* 
runtime_state,
                         std::unique_ptr<InvertedIndexIterator>* iterator) 
override;
     Status query(OlapReaderStatistics* stats, RuntimeState* runtime_state,
-                 const std::string& column_name, const void* query_value,
-                 InvertedIndexQueryType query_type, roaring::Roaring* bit_map) 
override;
+                 const std::string& column_name, InvertedIndexQueryBase* 
query_value,
+                 roaring::Roaring* bit_map) override;
     Status try_query(OlapReaderStatistics* stats, const std::string& 
column_name,
-                     const void* query_value, InvertedIndexQueryType 
query_type,
-                     uint32_t* count) override {
+                     InvertedIndexQueryBase* query_value, uint32_t* count) 
override {
         return Status::Error<ErrorCode::NOT_IMPLEMENTED_ERROR>(
                 "StringTypeInvertedIndexReader not support try_query");
     }
+    Status handle_range_query(const std::string& column_name, 
OlapReaderStatistics* stats,
+                              InvertedIndexRangeQueryI* query, 
roaring::Roaring* bit_map);
+    Status handle_point_query(const std::string& column_name, 
OlapReaderStatistics* stats,
+                              InvertedIndexPointQueryI* query, 
roaring::Roaring* bit_map);
+
     InvertedIndexReaderType type() override;
 };
 
@@ -184,19 +224,20 @@ private:
     uint32_t _num_hits;
     bool _only_count;
     lucene::util::bkd::bkd_reader* _reader;
-    InvertedIndexQueryType _query_type;
+    PredicateType _low_op;
+    PredicateType _high_op;
 
 public:
-    std::string query_min;
-    std::string query_max;
+    BinaryType query_min;
+    BinaryType query_max;
+    std::vector<BinaryType> query_points;
 
 public:
-    InvertedIndexVisitor(roaring::Roaring* hits, InvertedIndexQueryType 
query_type,
+    InvertedIndexVisitor(roaring::Roaring* hits, InvertedIndexQueryBase* 
query_value,
                          bool only_count = false);
     ~InvertedIndexVisitor() override = default;
 
     void set_reader(lucene::util::bkd::bkd_reader* r) { _reader = r; }
-    lucene::util::bkd::bkd_reader* get_reader() { return _reader; }
 
     void visit(int row_id) override;
     void visit(roaring::Roaring& r) override;
@@ -207,17 +248,17 @@ public:
     void visit(lucene::util::bkd::bkd_docid_set_iterator* iter,
                std::vector<uint8_t>& packed_value) override;
     bool matches(uint8_t* packed_value);
+    bool _matches(const BinaryType& packed_value, const BinaryType& qmax, 
const BinaryType& qmin);
     lucene::util::bkd::relation compare(std::vector<uint8_t>& min_packed,
                                         std::vector<uint8_t>& max_packed) 
override;
+    lucene::util::bkd::relation _compare(const BinaryType& min_packed, const 
BinaryType& max_packed,
+                                         const BinaryType& qmax, const 
BinaryType& qmin);
     uint32_t get_num_hits() const { return _num_hits; }
 };
 
 class BkdIndexReader : public InvertedIndexReader {
     ENABLE_FACTORY_CREATOR(BkdIndexReader);
 
-private:
-    std::string _file_full_path;
-
 public:
     explicit BkdIndexReader(io::FileSystemSPtr fs, const std::string& path,
                             const TabletIndex* index_meta);
@@ -240,27 +281,16 @@ public:
                         std::unique_ptr<InvertedIndexIterator>* iterator) 
override;
 
     Status query(OlapReaderStatistics* stats, RuntimeState* runtime_state,
-                 const std::string& column_name, const void* query_value,
-                 InvertedIndexQueryType query_type, roaring::Roaring* bit_map) 
override;
+                 const std::string& column_name, InvertedIndexQueryBase* 
query_value,
+                 roaring::Roaring* bit_map) override;
     Status try_query(OlapReaderStatistics* stats, const std::string& 
column_name,
-                     const void* query_value, InvertedIndexQueryType 
query_type,
-                     uint32_t* count) override;
-    Status bkd_query(OlapReaderStatistics* stats, const std::string& 
column_name,
-                     const void* query_value, InvertedIndexQueryType 
query_type,
-                     std::shared_ptr<lucene::util::bkd::bkd_reader> r,
-                     InvertedIndexVisitor* visitor);
-
-    Status handle_cache(InvertedIndexQueryCache* cache,
-                        const InvertedIndexQueryCache::CacheKey& cache_key,
-                        InvertedIndexQueryCacheHandle* cache_handler, 
OlapReaderStatistics* stats,
-                        roaring::Roaring* bit_map);
+                     InvertedIndexQueryBase* query_value, uint32_t* count) 
override;
 
     InvertedIndexReaderType type() override;
     Status get_bkd_reader(std::shared_ptr<lucene::util::bkd::bkd_reader>* 
reader);
 
 private:
     const TypeInfo* _type_info {};
-    const KeyCoder* _value_key_coder {};
     std::unique_ptr<DorisCompoundReader> _compoundReader;
 };
 
@@ -270,13 +300,13 @@ class InvertedIndexIterator {
 public:
     InvertedIndexIterator(OlapReaderStatistics* stats, RuntimeState* 
runtime_state,
                           std::shared_ptr<InvertedIndexReader> reader)
-            : _stats(stats), _runtime_state(runtime_state), _reader(reader) {}
+            : _stats(stats), _runtime_state(runtime_state), 
_reader(std::move(reader)) {}
 
-    Status read_from_inverted_index(const std::string& column_name, const 
void* query_value,
-                                    InvertedIndexQueryType query_type, 
uint32_t segment_num_rows,
+    Status read_from_inverted_index(const std::string& column_name,
+                                    InvertedIndexQueryBase* query_value, 
uint32_t segment_num_rows,
                                     roaring::Roaring* bit_map, bool skip_try = 
false);
-    Status try_read_from_inverted_index(const std::string& column_name, const 
void* query_value,
-                                        InvertedIndexQueryType query_type, 
uint32_t* count);
+    Status try_read_from_inverted_index(const std::string& column_name,
+                                        InvertedIndexQueryBase* query_value, 
uint32_t* count);
 
     Status read_null_bitmap(InvertedIndexQueryCacheHandle* cache_handle,
                             lucene::store::Directory* dir = nullptr) {
diff --git a/be/src/olap/rowset/segment_v2/segment_iterator.cpp 
b/be/src/olap/rowset/segment_v2/segment_iterator.cpp
index 28274752b05..ab6cc36cb9c 100644
--- a/be/src/olap/rowset/segment_v2/segment_iterator.cpp
+++ b/be/src/olap/rowset/segment_v2/segment_iterator.cpp
@@ -234,8 +234,10 @@ Status SegmentIterator::_init_impl(const 
StorageReadOptions& opts) {
             predicate->clone(&cloned);
             _pool->add(cloned);
             _col_predicates.emplace_back(cloned);
+            origin_to_clone_predicates[predicate] = cloned;
         } else {
             _col_predicates.emplace_back(predicate);
+            origin_to_clone_predicates[predicate] = predicate;
         }
     }
     _tablet_id = opts.tablet_id;
@@ -866,6 +868,7 @@ inline bool 
SegmentIterator::_inverted_index_not_support_pred_type(const Predica
 Status SegmentIterator::_apply_inverted_index_on_column_predicate(
         ColumnPredicate* pred, std::vector<ColumnPredicate*>& 
remaining_predicates,
         bool* continue_apply) {
+    
SCOPED_RAW_TIMER(&_opts.stats->inverted_index_column_predicate_filter_timer);
     if (!_check_apply_by_inverted_index(pred)) {
         remaining_predicates.emplace_back(pred);
     } else {
@@ -916,7 +919,8 @@ Status 
SegmentIterator::_apply_inverted_index_on_column_predicate(
 Status SegmentIterator::_apply_inverted_index_on_block_column_predicate(
         ColumnId column_id, MutilColumnBlockPredicate* pred,
         std::set<const ColumnPredicate*>& no_need_to_pass_column_predicate_set,
-        bool* continue_apply) {
+        std::vector<ColumnPredicate*>& remaining_predicates, bool* 
continue_apply) {
+    
SCOPED_RAW_TIMER(&_opts.stats->inverted_index_block_column_predicate_filter_timer);
     bool handle_by_fulltext = _column_has_fulltext_index(column_id);
     std::set<const ColumnPredicate*> predicate_set {};
 
@@ -933,15 +937,29 @@ Status 
SegmentIterator::_apply_inverted_index_on_block_column_predicate(
 
         std::string column_name = _schema->column(column_id)->name();
 
-        auto res = pred->evaluate(column_name, 
_inverted_index_iterators[column_id].get(),
-                                  num_rows(), &output_result);
+        auto process_predicate_set = [&](const auto& predicate_set) {
+            for (auto& orig_pred : predicate_set) {
+                if (origin_to_clone_predicates.contains(orig_pred)) {
+                    auto& cloned_pred = origin_to_clone_predicates[orig_pred];
+                    no_need_to_pass_column_predicate_set.emplace(cloned_pred);
+                } else {
+                    LOG(ERROR)
+                            << "column:" << column_name << " pred:" << 
orig_pred->debug_string()
+                            << " is not in origin_to_clone_predicates when 
process_predicate_set";
+                }
+            }
+        };
+
+        auto res = pred->evaluate(*_schema, 
_inverted_index_iterators[column_id].get(), num_rows(),
+                                  &output_result);
 
         if (res.ok()) {
             if (_check_column_pred_all_push_down(column_name) &&
                 !all_predicates_are_marked_by_runtime_filter(predicate_set)) {
                 _need_read_data_indices[column_id] = false;
             }
-            no_need_to_pass_column_predicate_set.insert(predicate_set.begin(), 
predicate_set.end());
+            process_predicate_set(predicate_set);
+            
//no_need_to_pass_column_predicate_set.insert(predicate_set.begin(), 
predicate_set.end());
             _row_bitmap &= output_result;
             if (_row_bitmap.isEmpty()) {
                 // all rows have been pruned, no need to process further 
predicates
@@ -949,8 +967,25 @@ Status 
SegmentIterator::_apply_inverted_index_on_block_column_predicate(
             }
             return res;
         } else {
-            //TODO:mock until AndBlockColumnPredicate evaluate is ok.
-            if (res.code() == ErrorCode::NOT_IMPLEMENTED_ERROR) {
+            // because column predicate only process LE/LT/GT/GE predicate 
type, need_remaining_after_evaluate only support in_or_list
+            bool need_remaining_after_evaluate = false;
+            if (_downgrade_without_index(res, need_remaining_after_evaluate)) {
+                // downgrade without index query
+                //process_predicate_set(predicate_set);
+                // need to pass non-index evaluate after
+                for (auto& orig_pred : predicate_set) {
+                    if (origin_to_clone_predicates.contains(orig_pred)) {
+                        auto& cloned_pred = 
origin_to_clone_predicates[orig_pred];
+                        remaining_predicates.push_back(cloned_pred);
+                        
no_need_to_pass_column_predicate_set.emplace(cloned_pred);
+                    } else {
+                        LOG(ERROR)
+                                << "column:" << column_name << " pred:" << 
orig_pred->debug_string()
+                                << " is not in origin_to_clone_predicates when 
"
+                                   "_downgrade_without_index";
+                    }
+                }
+                _not_apply_index_pred.insert(column_id);
                 return Status::OK();
             }
             LOG(WARNING) << "failed to evaluate index"
@@ -1008,7 +1043,8 @@ Status SegmentIterator::_apply_inverted_index() {
         auto pred = entry.second;
         bool continue_apply = true;
         RETURN_IF_ERROR(_apply_inverted_index_on_block_column_predicate(
-                column_id, pred.get(), no_need_to_pass_column_predicate_set, 
&continue_apply));
+                column_id, pred.get(), no_need_to_pass_column_predicate_set, 
remaining_predicates,
+                &continue_apply));
         if (!continue_apply) {
             break;
         }
diff --git a/be/src/olap/rowset/segment_v2/segment_iterator.h 
b/be/src/olap/rowset/segment_v2/segment_iterator.h
index 33d3a3f5f9c..3559dfbaaf4 100644
--- a/be/src/olap/rowset/segment_v2/segment_iterator.h
+++ b/be/src/olap/rowset/segment_v2/segment_iterator.h
@@ -181,7 +181,7 @@ private:
     [[nodiscard]] Status _apply_inverted_index_on_block_column_predicate(
             ColumnId column_id, MutilColumnBlockPredicate* pred,
             std::set<const ColumnPredicate*>& 
no_need_to_pass_column_predicate_set,
-            bool* continue_apply);
+            std::vector<ColumnPredicate*>& remaining_predicates, bool* 
continue_apply);
     [[nodiscard]] Status _apply_index_except_leafnode_of_andnode();
     [[nodiscard]] Status _apply_bitmap_index_except_leafnode_of_andnode(
             ColumnPredicate* pred, roaring::Roaring* output_result);
@@ -392,6 +392,8 @@ private:
     // make a copy of `_opts.column_predicates` in order to make local changes
     std::vector<ColumnPredicate*> _col_predicates;
     std::vector<ColumnPredicate*> _col_preds_except_leafnode_of_andnode;
+    // comparison predicate will be cloned when segment_iterator init, we need 
to store the pair in order to find clone predicate directly.
+    std::unordered_map<const ColumnPredicate*, ColumnPredicate*> 
origin_to_clone_predicates;
     vectorized::VExprContextSPtrs _common_expr_ctxs_push_down;
     bool _enable_common_expr_pushdown = false;
     std::vector<vectorized::VExprSPtr> _remaining_conjunct_roots;
diff --git a/be/src/vec/exec/scan/new_olap_scan_node.cpp 
b/be/src/vec/exec/scan/new_olap_scan_node.cpp
index 5aa179d3006..698b50923a9 100644
--- a/be/src/vec/exec/scan/new_olap_scan_node.cpp
+++ b/be/src/vec/exec/scan/new_olap_scan_node.cpp
@@ -165,11 +165,18 @@ Status NewOlapScanNode::_init_profile() {
     _inverted_index_filter_counter =
             ADD_COUNTER(_segment_profile, "RowsInvertedIndexFiltered", 
TUnit::UNIT);
     _inverted_index_filter_timer = ADD_TIMER(_segment_profile, 
"InvertedIndexFilterTime");
+    _inverted_index_block_column_predicate_filter_timer =
+            ADD_TIMER(_segment_profile, 
"InvertedIndexBlockColumnPredicateFilterTime");
+    _inverted_index_column_predicate_filter_timer =
+            ADD_TIMER(_segment_profile, 
"InvertedIndexColumnPredicateFilterTime");
     _inverted_index_query_cache_hit_counter =
             ADD_COUNTER(_segment_profile, "InvertedIndexQueryCacheHit", 
TUnit::UNIT);
     _inverted_index_query_cache_miss_counter =
             ADD_COUNTER(_segment_profile, "InvertedIndexQueryCacheMiss", 
TUnit::UNIT);
     _inverted_index_query_timer = ADD_TIMER(_segment_profile, 
"InvertedIndexQueryTime");
+    _inverted_index_try_query_timer = ADD_TIMER(_segment_profile, 
"InvertedIndexTryQueryTime");
+    _inverted_index_bkd_intersect_timer =
+            ADD_TIMER(_segment_profile, "InvertedIndexBKDIntersectTime");
     _inverted_index_query_bitmap_copy_timer =
             ADD_TIMER(_segment_profile, "InvertedIndexQueryBitmapCopyTime");
     _inverted_index_query_bitmap_op_timer =
diff --git a/be/src/vec/exec/scan/new_olap_scan_node.h 
b/be/src/vec/exec/scan/new_olap_scan_node.h
index 0725c37cf5e..ff64ed6d567 100644
--- a/be/src/vec/exec/scan/new_olap_scan_node.h
+++ b/be/src/vec/exec/scan/new_olap_scan_node.h
@@ -182,9 +182,13 @@ private:
 
     RuntimeProfile::Counter* _inverted_index_filter_counter = nullptr;
     RuntimeProfile::Counter* _inverted_index_filter_timer = nullptr;
+    RuntimeProfile::Counter* 
_inverted_index_block_column_predicate_filter_timer = nullptr;
+    RuntimeProfile::Counter* _inverted_index_column_predicate_filter_timer = 
nullptr;
     RuntimeProfile::Counter* _inverted_index_query_cache_hit_counter = nullptr;
     RuntimeProfile::Counter* _inverted_index_query_cache_miss_counter = 
nullptr;
     RuntimeProfile::Counter* _inverted_index_query_timer = nullptr;
+    RuntimeProfile::Counter* _inverted_index_try_query_timer = nullptr;
+    RuntimeProfile::Counter* _inverted_index_bkd_intersect_timer = nullptr;
     RuntimeProfile::Counter* _inverted_index_query_bitmap_copy_timer = nullptr;
     RuntimeProfile::Counter* _inverted_index_query_bitmap_op_timer = nullptr;
     RuntimeProfile::Counter* _inverted_index_searcher_open_timer = nullptr;
diff --git a/be/src/vec/exec/scan/new_olap_scanner.cpp 
b/be/src/vec/exec/scan/new_olap_scanner.cpp
index ea4187e556a..d26241532b2 100644
--- a/be/src/vec/exec/scan/new_olap_scanner.cpp
+++ b/be/src/vec/exec/scan/new_olap_scanner.cpp
@@ -585,6 +585,13 @@ void NewOlapScanner::_update_counters_before_close() {
                    stats.inverted_index_searcher_open_timer);
     COUNTER_UPDATE(olap_parent->_inverted_index_searcher_search_timer,
                    stats.inverted_index_searcher_search_timer);
+    
COUNTER_UPDATE(olap_parent->_inverted_index_block_column_predicate_filter_timer,
                    
+                   stats.inverted_index_block_column_predicate_filter_timer);  
                    
+    COUNTER_UPDATE(olap_parent->_inverted_index_column_predicate_filter_timer, 
                         
+                   stats.inverted_index_column_predicate_filter_timer);        
                    
+    COUNTER_UPDATE(olap_parent->_inverted_index_bkd_intersect_timer,           
                         
+                   stats.inverted_index_bkd_intersect_timer);                  
                    
+    COUNTER_UPDATE(olap_parent->_inverted_index_try_query_timer, 
stats.inverted_index_try_query_timer); 
 
     if (config::enable_file_cache) {
         io::FileCacheProfileReporter 
cache_profile(olap_parent->_segment_profile.get());
diff --git a/be/src/vec/exec/scan/vscan_node.h 
b/be/src/vec/exec/scan/vscan_node.h
index 7600189a251..f81753efb6e 100644
--- a/be/src/vec/exec/scan/vscan_node.h
+++ b/be/src/vec/exec/scan/vscan_node.h
@@ -277,7 +277,7 @@ protected:
     std::unordered_map<std::string, ColumnValueRangeType> 
_colname_to_value_range;
     /**
      * _colname_to_value_range only store the leaf of and in the conjunct expr 
tree,
-     * we use _compound_value_ranges to store conresponding value ranges 
+     * we use _compound_value_ranges to store corresponding value ranges
      * in the one compound relationship except the leaf of and node,
      * such as `where a > 1 or b > 10 and c < 200`, the expr tree like: 
      *     or


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

Reply via email to