Coverage Report

Created: 2026-08-21 12:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/storage/delete/delete_handler.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#pragma once
19
20
#include <butil/macros.h>
21
22
#include <cstdint>
23
#include <string>
24
#include <type_traits>
25
26
#include "common/factory_creator.h"
27
#include "common/status.h"
28
#include "core/arena.h"
29
#include "storage/predicate/column_predicate.h"
30
#include "storage/rowset/rowset_meta.h"
31
#include "storage/schema.h"
32
#include "storage/tablet/tablet_schema.h"
33
34
namespace doris {
35
36
class AndBlockColumnPredicate;
37
class ColumnPredicate;
38
class DeletePredicatePB;
39
class TCondition;
40
41
// Represent a delete condition.
42
struct DeleteConditions {
43
    int64_t filter_version = 0; // The version of this condition
44
    std::vector<std::shared_ptr<const ColumnPredicate>> column_predicate_vec;
45
};
46
47
// This class resolves persisted delete conditions to read-schema ordinals and evaluates them while
48
// reading rows.
49
class DeleteHandler {
50
    ENABLE_FACTORY_CREATOR(DeleteHandler);
51
52
public:
53
    struct ConditionParseResult {
54
        int32_t col_unique_id;
55
        std::string column_name;
56
        PredicateType condition_op;
57
        std::list<std::string> value_str;
58
    };
59
    // generated DeletePredicatePB by TCondition
60
    static Status generate_delete_predicate(const TabletSchema& schema,
61
                                            const std::vector<TCondition>& conditions,
62
                                            DeletePredicatePB* del_pred);
63
64
    static Status convert_to_sub_pred_v2(DeletePredicatePB* delete_pred, TabletSchemaSPtr schema);
65
66
    /**
67
     * Use regular expression to extract 'column_name', 'op' and 'operands'
68
     *
69
     * @param condition_str input predicate string in form of `X OP Y`
70
     * @param condition output param
71
     * @return OK if matched and extracted correctly otherwise DELETE_INVALID_PARAMETERS
72
     */
73
    static ConditionParseResult parse_condition(const std::string& condition_str);
74
    static ConditionParseResult parse_condition(const DeleteSubPredicatePB& sub_cond);
75
    static PredicateType parse_condition_op(const std::string& op_str,
76
                                            const std::list<std::string>& cond_values);
77
78
private:
79
    // Validate the condition on the schema.
80
    static Status check_condition_valid(const TabletSchema& tablet_schema, const TCondition& cond);
81
82
    // Check whether the condition value is valid according to its type.
83
    // 1. For integers(int8,int16,in32,int64,uint8,uint16,uint32,uint64), check whether they are overflow
84
    // 2. For decimal, check whether precision or scale is overflow
85
    // 3. For date and datetime, check format and value
86
    // 4. For char and varchar, check length
87
    static bool is_condition_value_valid(const TabletColumn& column,
88
                                         const std::string& condition_op,
89
                                         const std::string& value_str);
90
91
public:
92
959k
    DeleteHandler() = default;
93
    ~DeleteHandler();
94
95
    // Initialize DeleteHandler, use the delete conditions whose version is less
96
    // than or equal to 'version' to fill '_del_conds'.
97
    //
98
    // Delete-condition columns that are absent from `read_schema` are resolved
99
    // against the schema stored in the corresponding delete-predicate rowset and
100
    // returned through `dropped_columns`.
101
    // NOTE: You should lock the tablet's header file before calling this function.
102
    // input:
103
    //     * version: maximum version
104
    //     * read_schema: schema used to bind delete-predicate column ordinals
105
    // output:
106
    //     * dropped_columns: missing delete-predicate columns in append order
107
    // return:
108
    //     * Status::Error<DELETE_INVALID_PARAMETERS>(): input parameters are not valid
109
    //     * Status::Error<MEM_ALLOC_FAILED>(): alloc memory failed
110
    Status init(const std::vector<RowsetMetaSharedPtr>& delete_preds, int64_t version,
111
                const ReadSchemaSPtr& read_schema, std::vector<TabletColumn>* dropped_columns);
112
113
949k
    [[nodiscard]] bool empty() const { return _del_conds.empty(); }
114
115
    void get_delete_conditions_after_version(
116
            int64_t version, AndBlockColumnPredicate* and_block_column_predicate_ptr,
117
            std::unordered_map<int32_t, std::vector<std::shared_ptr<const ColumnPredicate>>>*
118
                    del_predicates_for_zone_map) const;
119
120
private:
121
    template <typename SubPredType>
122
        requires(std::is_same_v<SubPredType, DeleteSubPredicatePB> or
123
                 std::is_same_v<SubPredType, std::string>)
124
    Status _parse_column_pred(
125
            const ReadSchema& read_schema, const TabletSchemaSPtr& delete_pred_related_schema,
126
            const ::google::protobuf::RepeatedPtrField<SubPredType>& sub_pred_list,
127
            DeleteConditions* delete_conditions, std::vector<TabletColumn>* dropped_columns);
128
129
    // Resolve in order:
130
    // 1. Look up ReadSchema by predicate UID when present.
131
    // 2. Resolve the historical TabletColumn in the predicate rowset schema by predicate UID, or
132
    //    by predicate name for legacy metadata without a UID.
133
    // 3. Look up ReadSchema by the historical TabletColumn's UID.
134
    // 4. Look up dropped_columns by the historical column's UID.
135
    // 5. Append the historical column to dropped_columns when no match exists.
136
    // Example: if old x(uid=10) is dropped and x(uid=20) is added, step 2 recovers uid=10 and avoids
137
    // binding the predicate to uid=20.
138
    static Status _resolve_column(const ReadSchema& read_schema, int32_t col_unique_id,
139
                                  const std::string& column_name,
140
                                  const TabletSchemaSPtr& delete_pred_related_schema,
141
                                  ColumnId* column_id, const TabletColumn** column,
142
                                  std::vector<TabletColumn>* dropped_columns);
143
144
    bool _is_inited = false;
145
    // DeleteConditions in _del_conds are in 'OR' relationship
146
    std::vector<DeleteConditions> _del_conds;
147
    Arena _predicate_arena;
148
149
    DISALLOW_COPY_AND_ASSIGN(DeleteHandler);
150
};
151
152
} // namespace doris