Coverage Report

Created: 2026-03-17 02:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/storage/delete/delete_handler.cpp
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
#include "storage/delete/delete_handler.h"
19
20
#include <gen_cpp/PaloInternalService_types.h>
21
#include <gen_cpp/olap_file.pb.h>
22
#include <thrift/protocol/TDebugProtocol.h>
23
24
#include <string>
25
#include <vector>
26
27
#include "common/config.h"
28
#include "common/logging.h"
29
#include "common/status.h"
30
#include "exprs/function/cast/cast_parameters.h"
31
#include "exprs/function/cast/cast_to_boolean.h"
32
#include "exprs/function/cast/cast_to_date_or_datetime_impl.hpp"
33
#include "exprs/function/cast/cast_to_datetimev2_impl.hpp"
34
#include "exprs/function/cast/cast_to_datev2_impl.hpp"
35
#include "exprs/function/cast/cast_to_decimal.h"
36
#include "exprs/function/cast/cast_to_float.h"
37
#include "exprs/function/cast/cast_to_int.h"
38
#include "exprs/function/cast/cast_to_ip.h"
39
#include "storage/olap_common.h"
40
#include "storage/predicate/block_column_predicate.h"
41
#include "storage/predicate/predicate_creator.h"
42
#include "storage/tablet/tablet_schema.h"
43
#include "storage/utils.h"
44
#include "util/debug_points.h"
45
46
using apache::thrift::ThriftDebugString;
47
using std::vector;
48
using std::string;
49
50
using ::google::protobuf::RepeatedPtrField;
51
52
namespace doris {
53
54
template <PrimitiveType PType>
55
Status convert(const DataTypePtr& data_type, const std::string& str, Arena& arena,
56
111
               typename PrimitiveTypeTraits<PType>::CppType& res) {
57
    if constexpr (PType == TYPE_TINYINT || PType == TYPE_SMALLINT || PType == TYPE_INT ||
58
92
                  PType == TYPE_BIGINT || PType == TYPE_LARGEINT) {
59
92
        CastParameters parameters;
60
92
        if (!CastToInt::from_string<false>({str.data(), str.size()}, res, parameters)) {
61
2
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
62
2
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
63
2
                    str);
64
2
        }
65
90
        return Status::OK();
66
92
    }
67
0
    if constexpr (PType == TYPE_FLOAT || PType == TYPE_DOUBLE) {
68
0
        CastParameters parameters;
69
0
        if (!CastToFloat::from_string({str.data(), str.size()}, res, parameters)) {
70
0
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
71
0
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
72
0
                    str);
73
0
        }
74
0
        return Status::OK();
75
0
    }
76
0
    if constexpr (PType == TYPE_DATE) {
77
0
        CastParameters parameters;
78
0
        if (!CastToDateOrDatetime::from_string<false>({str.data(), str.size()}, res, nullptr,
79
0
                                                      parameters)) {
80
0
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
81
0
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
82
0
                    str);
83
0
        }
84
0
        return Status::OK();
85
0
    }
86
0
    if constexpr (PType == TYPE_DATETIME) {
87
0
        CastParameters parameters;
88
0
        if (!CastToDateOrDatetime::from_string<true>({str.data(), str.size()}, res, nullptr,
89
0
                                                     parameters)) {
90
0
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
91
0
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
92
0
                    str);
93
0
        }
94
0
        return Status::OK();
95
0
    }
96
0
    if constexpr (PType == TYPE_DATEV2) {
97
0
        CastParameters parameters;
98
0
        if (!CastToDateV2::from_string({str.data(), str.size()}, res, nullptr, parameters)) {
99
0
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
100
0
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
101
0
                    str);
102
0
        }
103
0
        return Status::OK();
104
0
    }
105
0
    if constexpr (PType == TYPE_DATETIMEV2) {
106
0
        CastParameters parameters;
107
0
        if (!CastToDatetimeV2::from_string({str.data(), str.size()}, res, nullptr,
108
0
                                           data_type->get_scale(), parameters)) {
109
0
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
110
0
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
111
0
                    str);
112
0
        }
113
0
        return Status::OK();
114
0
    }
115
18
    if constexpr (PType == TYPE_TIMESTAMPTZ) {
116
18
        CastParameters parameters;
117
18
        if (!CastToTimstampTz::from_string({str.data(), str.size()}, res, parameters, nullptr,
118
18
                                           data_type->get_scale())) {
119
5
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
120
5
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
121
5
                    str);
122
5
        }
123
13
        return Status::OK();
124
18
    }
125
0
    if constexpr (PType == TYPE_CHAR) {
126
0
        size_t target = assert_cast<const DataTypeString*>(remove_nullable(data_type).get())->len();
127
0
        res = {str.data(), str.size()};
128
0
        if (target > str.size()) {
129
0
            char* buffer = arena.alloc(target);
130
0
            memset(buffer, 0, target);
131
0
            memcpy(buffer, str.data(), str.size());
132
0
            res = {buffer, target};
133
0
        }
134
0
        return Status::OK();
135
0
    }
136
0
    if constexpr (PType == TYPE_STRING || PType == TYPE_VARCHAR) {
137
0
        char* buffer = arena.alloc(str.size());
138
0
        memcpy(buffer, str.data(), str.size());
139
0
        res = {buffer, str.size()};
140
0
        return Status::OK();
141
0
    }
142
0
    if constexpr (PType == TYPE_BOOLEAN) {
143
0
        CastParameters parameters;
144
0
        UInt8 tmp;
145
0
        if (!CastToBool::from_string({str.data(), str.size()}, tmp, parameters)) {
146
0
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
147
0
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
148
0
                    str);
149
0
        }
150
0
        res = tmp != 0;
151
0
        return Status::OK();
152
0
    }
153
1
    if constexpr (PType == TYPE_IPV4) {
154
1
        CastParameters parameters;
155
1
        if (!CastToIPv4::from_string({str.data(), str.size()}, res, parameters)) {
156
0
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
157
0
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
158
0
                    str);
159
0
        }
160
1
        return Status::OK();
161
1
    }
162
0
    if constexpr (PType == TYPE_IPV6) {
163
0
        CastParameters parameters;
164
0
        if (!CastToIPv6::from_string({str.data(), str.size()}, res, parameters)) {
165
0
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
166
0
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
167
0
                    str);
168
0
        }
169
0
        return Status::OK();
170
0
    }
171
0
    if constexpr (PType == TYPE_DECIMALV2) {
172
0
        CastParameters parameters;
173
0
        Decimal128V2 tmp;
174
0
        if (!CastToDecimal::from_string({str.data(), str.size()}, tmp, data_type->get_precision(),
175
0
                                        data_type->get_scale(), parameters)) {
176
0
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
177
0
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
178
0
                    str);
179
0
        }
180
0
        res = DecimalV2Value(tmp.value);
181
0
        return Status::OK();
182
0
    } else if constexpr (is_decimal(PType)) {
183
0
        CastParameters parameters;
184
0
        if (!CastToDecimal::from_string({str.data(), str.size()}, res, data_type->get_precision(),
185
0
                                        data_type->get_scale(), parameters)) {
186
0
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
187
0
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
188
0
                    str);
189
0
        }
190
0
        return Status::OK();
191
0
    }
192
0
    return Status::Error<ErrorCode::INVALID_ARGUMENT>(
193
111
            "unsupported data type in delete handler. type={}",
194
111
            type_to_string(data_type->get_primitive_type()));
195
111
}
_ZN5doris7convertILNS_13PrimitiveTypeE3EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Line
Count
Source
56
9
               typename PrimitiveTypeTraits<PType>::CppType& res) {
57
    if constexpr (PType == TYPE_TINYINT || PType == TYPE_SMALLINT || PType == TYPE_INT ||
58
9
                  PType == TYPE_BIGINT || PType == TYPE_LARGEINT) {
59
9
        CastParameters parameters;
60
9
        if (!CastToInt::from_string<false>({str.data(), str.size()}, res, parameters)) {
61
2
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
62
2
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
63
2
                    str);
64
2
        }
65
7
        return Status::OK();
66
9
    }
67
    if constexpr (PType == TYPE_FLOAT || PType == TYPE_DOUBLE) {
68
        CastParameters parameters;
69
        if (!CastToFloat::from_string({str.data(), str.size()}, res, parameters)) {
70
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
71
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
72
                    str);
73
        }
74
        return Status::OK();
75
    }
76
    if constexpr (PType == TYPE_DATE) {
77
        CastParameters parameters;
78
        if (!CastToDateOrDatetime::from_string<false>({str.data(), str.size()}, res, nullptr,
79
                                                      parameters)) {
80
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
81
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
82
                    str);
83
        }
84
        return Status::OK();
85
    }
86
    if constexpr (PType == TYPE_DATETIME) {
87
        CastParameters parameters;
88
        if (!CastToDateOrDatetime::from_string<true>({str.data(), str.size()}, res, nullptr,
89
                                                     parameters)) {
90
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
91
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
92
                    str);
93
        }
94
        return Status::OK();
95
    }
96
    if constexpr (PType == TYPE_DATEV2) {
97
        CastParameters parameters;
98
        if (!CastToDateV2::from_string({str.data(), str.size()}, res, nullptr, parameters)) {
99
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
100
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
101
                    str);
102
        }
103
        return Status::OK();
104
    }
105
    if constexpr (PType == TYPE_DATETIMEV2) {
106
        CastParameters parameters;
107
        if (!CastToDatetimeV2::from_string({str.data(), str.size()}, res, nullptr,
108
                                           data_type->get_scale(), parameters)) {
109
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
110
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
111
                    str);
112
        }
113
        return Status::OK();
114
    }
115
    if constexpr (PType == TYPE_TIMESTAMPTZ) {
116
        CastParameters parameters;
117
        if (!CastToTimstampTz::from_string({str.data(), str.size()}, res, parameters, nullptr,
118
                                           data_type->get_scale())) {
119
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
120
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
121
                    str);
122
        }
123
        return Status::OK();
124
    }
125
    if constexpr (PType == TYPE_CHAR) {
126
        size_t target = assert_cast<const DataTypeString*>(remove_nullable(data_type).get())->len();
127
        res = {str.data(), str.size()};
128
        if (target > str.size()) {
129
            char* buffer = arena.alloc(target);
130
            memset(buffer, 0, target);
131
            memcpy(buffer, str.data(), str.size());
132
            res = {buffer, target};
133
        }
134
        return Status::OK();
135
    }
136
    if constexpr (PType == TYPE_STRING || PType == TYPE_VARCHAR) {
137
        char* buffer = arena.alloc(str.size());
138
        memcpy(buffer, str.data(), str.size());
139
        res = {buffer, str.size()};
140
        return Status::OK();
141
    }
142
    if constexpr (PType == TYPE_BOOLEAN) {
143
        CastParameters parameters;
144
        UInt8 tmp;
145
        if (!CastToBool::from_string({str.data(), str.size()}, tmp, parameters)) {
146
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
147
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
148
                    str);
149
        }
150
        res = tmp != 0;
151
        return Status::OK();
152
    }
153
    if constexpr (PType == TYPE_IPV4) {
154
        CastParameters parameters;
155
        if (!CastToIPv4::from_string({str.data(), str.size()}, res, parameters)) {
156
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
157
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
158
                    str);
159
        }
160
        return Status::OK();
161
    }
162
    if constexpr (PType == TYPE_IPV6) {
163
        CastParameters parameters;
164
        if (!CastToIPv6::from_string({str.data(), str.size()}, res, parameters)) {
165
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
166
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
167
                    str);
168
        }
169
        return Status::OK();
170
    }
171
    if constexpr (PType == TYPE_DECIMALV2) {
172
        CastParameters parameters;
173
        Decimal128V2 tmp;
174
        if (!CastToDecimal::from_string({str.data(), str.size()}, tmp, data_type->get_precision(),
175
                                        data_type->get_scale(), parameters)) {
176
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
177
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
178
                    str);
179
        }
180
        res = DecimalV2Value(tmp.value);
181
        return Status::OK();
182
9
    } else if constexpr (is_decimal(PType)) {
183
9
        CastParameters parameters;
184
9
        if (!CastToDecimal::from_string({str.data(), str.size()}, res, data_type->get_precision(),
185
9
                                        data_type->get_scale(), parameters)) {
186
9
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
187
9
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
188
9
                    str);
189
9
        }
190
9
        return Status::OK();
191
9
    }
192
9
    return Status::Error<ErrorCode::INVALID_ARGUMENT>(
193
9
            "unsupported data type in delete handler. type={}",
194
9
            type_to_string(data_type->get_primitive_type()));
195
9
}
_ZN5doris7convertILNS_13PrimitiveTypeE4EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Line
Count
Source
56
8
               typename PrimitiveTypeTraits<PType>::CppType& res) {
57
    if constexpr (PType == TYPE_TINYINT || PType == TYPE_SMALLINT || PType == TYPE_INT ||
58
8
                  PType == TYPE_BIGINT || PType == TYPE_LARGEINT) {
59
8
        CastParameters parameters;
60
8
        if (!CastToInt::from_string<false>({str.data(), str.size()}, res, parameters)) {
61
0
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
62
0
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
63
0
                    str);
64
0
        }
65
8
        return Status::OK();
66
8
    }
67
    if constexpr (PType == TYPE_FLOAT || PType == TYPE_DOUBLE) {
68
        CastParameters parameters;
69
        if (!CastToFloat::from_string({str.data(), str.size()}, res, parameters)) {
70
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
71
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
72
                    str);
73
        }
74
        return Status::OK();
75
    }
76
    if constexpr (PType == TYPE_DATE) {
77
        CastParameters parameters;
78
        if (!CastToDateOrDatetime::from_string<false>({str.data(), str.size()}, res, nullptr,
79
                                                      parameters)) {
80
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
81
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
82
                    str);
83
        }
84
        return Status::OK();
85
    }
86
    if constexpr (PType == TYPE_DATETIME) {
87
        CastParameters parameters;
88
        if (!CastToDateOrDatetime::from_string<true>({str.data(), str.size()}, res, nullptr,
89
                                                     parameters)) {
90
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
91
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
92
                    str);
93
        }
94
        return Status::OK();
95
    }
96
    if constexpr (PType == TYPE_DATEV2) {
97
        CastParameters parameters;
98
        if (!CastToDateV2::from_string({str.data(), str.size()}, res, nullptr, parameters)) {
99
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
100
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
101
                    str);
102
        }
103
        return Status::OK();
104
    }
105
    if constexpr (PType == TYPE_DATETIMEV2) {
106
        CastParameters parameters;
107
        if (!CastToDatetimeV2::from_string({str.data(), str.size()}, res, nullptr,
108
                                           data_type->get_scale(), parameters)) {
109
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
110
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
111
                    str);
112
        }
113
        return Status::OK();
114
    }
115
    if constexpr (PType == TYPE_TIMESTAMPTZ) {
116
        CastParameters parameters;
117
        if (!CastToTimstampTz::from_string({str.data(), str.size()}, res, parameters, nullptr,
118
                                           data_type->get_scale())) {
119
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
120
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
121
                    str);
122
        }
123
        return Status::OK();
124
    }
125
    if constexpr (PType == TYPE_CHAR) {
126
        size_t target = assert_cast<const DataTypeString*>(remove_nullable(data_type).get())->len();
127
        res = {str.data(), str.size()};
128
        if (target > str.size()) {
129
            char* buffer = arena.alloc(target);
130
            memset(buffer, 0, target);
131
            memcpy(buffer, str.data(), str.size());
132
            res = {buffer, target};
133
        }
134
        return Status::OK();
135
    }
136
    if constexpr (PType == TYPE_STRING || PType == TYPE_VARCHAR) {
137
        char* buffer = arena.alloc(str.size());
138
        memcpy(buffer, str.data(), str.size());
139
        res = {buffer, str.size()};
140
        return Status::OK();
141
    }
142
    if constexpr (PType == TYPE_BOOLEAN) {
143
        CastParameters parameters;
144
        UInt8 tmp;
145
        if (!CastToBool::from_string({str.data(), str.size()}, tmp, parameters)) {
146
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
147
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
148
                    str);
149
        }
150
        res = tmp != 0;
151
        return Status::OK();
152
    }
153
    if constexpr (PType == TYPE_IPV4) {
154
        CastParameters parameters;
155
        if (!CastToIPv4::from_string({str.data(), str.size()}, res, parameters)) {
156
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
157
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
158
                    str);
159
        }
160
        return Status::OK();
161
    }
162
    if constexpr (PType == TYPE_IPV6) {
163
        CastParameters parameters;
164
        if (!CastToIPv6::from_string({str.data(), str.size()}, res, parameters)) {
165
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
166
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
167
                    str);
168
        }
169
        return Status::OK();
170
    }
171
    if constexpr (PType == TYPE_DECIMALV2) {
172
        CastParameters parameters;
173
        Decimal128V2 tmp;
174
        if (!CastToDecimal::from_string({str.data(), str.size()}, tmp, data_type->get_precision(),
175
                                        data_type->get_scale(), parameters)) {
176
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
177
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
178
                    str);
179
        }
180
        res = DecimalV2Value(tmp.value);
181
        return Status::OK();
182
8
    } else if constexpr (is_decimal(PType)) {
183
8
        CastParameters parameters;
184
8
        if (!CastToDecimal::from_string({str.data(), str.size()}, res, data_type->get_precision(),
185
8
                                        data_type->get_scale(), parameters)) {
186
8
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
187
8
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
188
8
                    str);
189
8
        }
190
8
        return Status::OK();
191
8
    }
192
8
    return Status::Error<ErrorCode::INVALID_ARGUMENT>(
193
8
            "unsupported data type in delete handler. type={}",
194
8
            type_to_string(data_type->get_primitive_type()));
195
8
}
_ZN5doris7convertILNS_13PrimitiveTypeE5EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Line
Count
Source
56
75
               typename PrimitiveTypeTraits<PType>::CppType& res) {
57
    if constexpr (PType == TYPE_TINYINT || PType == TYPE_SMALLINT || PType == TYPE_INT ||
58
75
                  PType == TYPE_BIGINT || PType == TYPE_LARGEINT) {
59
75
        CastParameters parameters;
60
75
        if (!CastToInt::from_string<false>({str.data(), str.size()}, res, parameters)) {
61
0
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
62
0
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
63
0
                    str);
64
0
        }
65
75
        return Status::OK();
66
75
    }
67
    if constexpr (PType == TYPE_FLOAT || PType == TYPE_DOUBLE) {
68
        CastParameters parameters;
69
        if (!CastToFloat::from_string({str.data(), str.size()}, res, parameters)) {
70
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
71
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
72
                    str);
73
        }
74
        return Status::OK();
75
    }
76
    if constexpr (PType == TYPE_DATE) {
77
        CastParameters parameters;
78
        if (!CastToDateOrDatetime::from_string<false>({str.data(), str.size()}, res, nullptr,
79
                                                      parameters)) {
80
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
81
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
82
                    str);
83
        }
84
        return Status::OK();
85
    }
86
    if constexpr (PType == TYPE_DATETIME) {
87
        CastParameters parameters;
88
        if (!CastToDateOrDatetime::from_string<true>({str.data(), str.size()}, res, nullptr,
89
                                                     parameters)) {
90
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
91
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
92
                    str);
93
        }
94
        return Status::OK();
95
    }
96
    if constexpr (PType == TYPE_DATEV2) {
97
        CastParameters parameters;
98
        if (!CastToDateV2::from_string({str.data(), str.size()}, res, nullptr, parameters)) {
99
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
100
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
101
                    str);
102
        }
103
        return Status::OK();
104
    }
105
    if constexpr (PType == TYPE_DATETIMEV2) {
106
        CastParameters parameters;
107
        if (!CastToDatetimeV2::from_string({str.data(), str.size()}, res, nullptr,
108
                                           data_type->get_scale(), parameters)) {
109
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
110
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
111
                    str);
112
        }
113
        return Status::OK();
114
    }
115
    if constexpr (PType == TYPE_TIMESTAMPTZ) {
116
        CastParameters parameters;
117
        if (!CastToTimstampTz::from_string({str.data(), str.size()}, res, parameters, nullptr,
118
                                           data_type->get_scale())) {
119
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
120
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
121
                    str);
122
        }
123
        return Status::OK();
124
    }
125
    if constexpr (PType == TYPE_CHAR) {
126
        size_t target = assert_cast<const DataTypeString*>(remove_nullable(data_type).get())->len();
127
        res = {str.data(), str.size()};
128
        if (target > str.size()) {
129
            char* buffer = arena.alloc(target);
130
            memset(buffer, 0, target);
131
            memcpy(buffer, str.data(), str.size());
132
            res = {buffer, target};
133
        }
134
        return Status::OK();
135
    }
136
    if constexpr (PType == TYPE_STRING || PType == TYPE_VARCHAR) {
137
        char* buffer = arena.alloc(str.size());
138
        memcpy(buffer, str.data(), str.size());
139
        res = {buffer, str.size()};
140
        return Status::OK();
141
    }
142
    if constexpr (PType == TYPE_BOOLEAN) {
143
        CastParameters parameters;
144
        UInt8 tmp;
145
        if (!CastToBool::from_string({str.data(), str.size()}, tmp, parameters)) {
146
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
147
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
148
                    str);
149
        }
150
        res = tmp != 0;
151
        return Status::OK();
152
    }
153
    if constexpr (PType == TYPE_IPV4) {
154
        CastParameters parameters;
155
        if (!CastToIPv4::from_string({str.data(), str.size()}, res, parameters)) {
156
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
157
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
158
                    str);
159
        }
160
        return Status::OK();
161
    }
162
    if constexpr (PType == TYPE_IPV6) {
163
        CastParameters parameters;
164
        if (!CastToIPv6::from_string({str.data(), str.size()}, res, parameters)) {
165
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
166
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
167
                    str);
168
        }
169
        return Status::OK();
170
    }
171
    if constexpr (PType == TYPE_DECIMALV2) {
172
        CastParameters parameters;
173
        Decimal128V2 tmp;
174
        if (!CastToDecimal::from_string({str.data(), str.size()}, tmp, data_type->get_precision(),
175
                                        data_type->get_scale(), parameters)) {
176
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
177
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
178
                    str);
179
        }
180
        res = DecimalV2Value(tmp.value);
181
        return Status::OK();
182
75
    } else if constexpr (is_decimal(PType)) {
183
75
        CastParameters parameters;
184
75
        if (!CastToDecimal::from_string({str.data(), str.size()}, res, data_type->get_precision(),
185
75
                                        data_type->get_scale(), parameters)) {
186
75
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
187
75
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
188
75
                    str);
189
75
        }
190
75
        return Status::OK();
191
75
    }
192
75
    return Status::Error<ErrorCode::INVALID_ARGUMENT>(
193
75
            "unsupported data type in delete handler. type={}",
194
75
            type_to_string(data_type->get_primitive_type()));
195
75
}
Unexecuted instantiation: _ZN5doris7convertILNS_13PrimitiveTypeE6EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Unexecuted instantiation: _ZN5doris7convertILNS_13PrimitiveTypeE7EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Unexecuted instantiation: _ZN5doris7convertILNS_13PrimitiveTypeE8EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Unexecuted instantiation: _ZN5doris7convertILNS_13PrimitiveTypeE9EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Unexecuted instantiation: _ZN5doris7convertILNS_13PrimitiveTypeE11EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Unexecuted instantiation: _ZN5doris7convertILNS_13PrimitiveTypeE12EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Unexecuted instantiation: _ZN5doris7convertILNS_13PrimitiveTypeE25EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Unexecuted instantiation: _ZN5doris7convertILNS_13PrimitiveTypeE26EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
_ZN5doris7convertILNS_13PrimitiveTypeE42EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Line
Count
Source
56
18
               typename PrimitiveTypeTraits<PType>::CppType& res) {
57
    if constexpr (PType == TYPE_TINYINT || PType == TYPE_SMALLINT || PType == TYPE_INT ||
58
                  PType == TYPE_BIGINT || PType == TYPE_LARGEINT) {
59
        CastParameters parameters;
60
        if (!CastToInt::from_string<false>({str.data(), str.size()}, res, parameters)) {
61
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
62
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
63
                    str);
64
        }
65
        return Status::OK();
66
    }
67
    if constexpr (PType == TYPE_FLOAT || PType == TYPE_DOUBLE) {
68
        CastParameters parameters;
69
        if (!CastToFloat::from_string({str.data(), str.size()}, res, parameters)) {
70
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
71
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
72
                    str);
73
        }
74
        return Status::OK();
75
    }
76
    if constexpr (PType == TYPE_DATE) {
77
        CastParameters parameters;
78
        if (!CastToDateOrDatetime::from_string<false>({str.data(), str.size()}, res, nullptr,
79
                                                      parameters)) {
80
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
81
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
82
                    str);
83
        }
84
        return Status::OK();
85
    }
86
    if constexpr (PType == TYPE_DATETIME) {
87
        CastParameters parameters;
88
        if (!CastToDateOrDatetime::from_string<true>({str.data(), str.size()}, res, nullptr,
89
                                                     parameters)) {
90
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
91
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
92
                    str);
93
        }
94
        return Status::OK();
95
    }
96
    if constexpr (PType == TYPE_DATEV2) {
97
        CastParameters parameters;
98
        if (!CastToDateV2::from_string({str.data(), str.size()}, res, nullptr, parameters)) {
99
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
100
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
101
                    str);
102
        }
103
        return Status::OK();
104
    }
105
    if constexpr (PType == TYPE_DATETIMEV2) {
106
        CastParameters parameters;
107
        if (!CastToDatetimeV2::from_string({str.data(), str.size()}, res, nullptr,
108
                                           data_type->get_scale(), parameters)) {
109
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
110
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
111
                    str);
112
        }
113
        return Status::OK();
114
    }
115
18
    if constexpr (PType == TYPE_TIMESTAMPTZ) {
116
18
        CastParameters parameters;
117
18
        if (!CastToTimstampTz::from_string({str.data(), str.size()}, res, parameters, nullptr,
118
18
                                           data_type->get_scale())) {
119
5
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
120
5
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
121
5
                    str);
122
5
        }
123
13
        return Status::OK();
124
18
    }
125
    if constexpr (PType == TYPE_CHAR) {
126
        size_t target = assert_cast<const DataTypeString*>(remove_nullable(data_type).get())->len();
127
        res = {str.data(), str.size()};
128
        if (target > str.size()) {
129
            char* buffer = arena.alloc(target);
130
            memset(buffer, 0, target);
131
            memcpy(buffer, str.data(), str.size());
132
            res = {buffer, target};
133
        }
134
        return Status::OK();
135
    }
136
    if constexpr (PType == TYPE_STRING || PType == TYPE_VARCHAR) {
137
        char* buffer = arena.alloc(str.size());
138
        memcpy(buffer, str.data(), str.size());
139
        res = {buffer, str.size()};
140
        return Status::OK();
141
    }
142
    if constexpr (PType == TYPE_BOOLEAN) {
143
        CastParameters parameters;
144
        UInt8 tmp;
145
        if (!CastToBool::from_string({str.data(), str.size()}, tmp, parameters)) {
146
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
147
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
148
                    str);
149
        }
150
        res = tmp != 0;
151
        return Status::OK();
152
    }
153
    if constexpr (PType == TYPE_IPV4) {
154
        CastParameters parameters;
155
        if (!CastToIPv4::from_string({str.data(), str.size()}, res, parameters)) {
156
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
157
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
158
                    str);
159
        }
160
        return Status::OK();
161
    }
162
    if constexpr (PType == TYPE_IPV6) {
163
        CastParameters parameters;
164
        if (!CastToIPv6::from_string({str.data(), str.size()}, res, parameters)) {
165
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
166
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
167
                    str);
168
        }
169
        return Status::OK();
170
    }
171
    if constexpr (PType == TYPE_DECIMALV2) {
172
        CastParameters parameters;
173
        Decimal128V2 tmp;
174
        if (!CastToDecimal::from_string({str.data(), str.size()}, tmp, data_type->get_precision(),
175
                                        data_type->get_scale(), parameters)) {
176
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
177
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
178
                    str);
179
        }
180
        res = DecimalV2Value(tmp.value);
181
        return Status::OK();
182
18
    } else if constexpr (is_decimal(PType)) {
183
18
        CastParameters parameters;
184
18
        if (!CastToDecimal::from_string({str.data(), str.size()}, res, data_type->get_precision(),
185
18
                                        data_type->get_scale(), parameters)) {
186
18
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
187
18
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
188
18
                    str);
189
18
        }
190
18
        return Status::OK();
191
18
    }
192
18
    return Status::Error<ErrorCode::INVALID_ARGUMENT>(
193
18
            "unsupported data type in delete handler. type={}",
194
18
            type_to_string(data_type->get_primitive_type()));
195
18
}
Unexecuted instantiation: _ZN5doris7convertILNS_13PrimitiveTypeE2EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
_ZN5doris7convertILNS_13PrimitiveTypeE36EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Line
Count
Source
56
1
               typename PrimitiveTypeTraits<PType>::CppType& res) {
57
    if constexpr (PType == TYPE_TINYINT || PType == TYPE_SMALLINT || PType == TYPE_INT ||
58
                  PType == TYPE_BIGINT || PType == TYPE_LARGEINT) {
59
        CastParameters parameters;
60
        if (!CastToInt::from_string<false>({str.data(), str.size()}, res, parameters)) {
61
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
62
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
63
                    str);
64
        }
65
        return Status::OK();
66
    }
67
    if constexpr (PType == TYPE_FLOAT || PType == TYPE_DOUBLE) {
68
        CastParameters parameters;
69
        if (!CastToFloat::from_string({str.data(), str.size()}, res, parameters)) {
70
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
71
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
72
                    str);
73
        }
74
        return Status::OK();
75
    }
76
    if constexpr (PType == TYPE_DATE) {
77
        CastParameters parameters;
78
        if (!CastToDateOrDatetime::from_string<false>({str.data(), str.size()}, res, nullptr,
79
                                                      parameters)) {
80
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
81
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
82
                    str);
83
        }
84
        return Status::OK();
85
    }
86
    if constexpr (PType == TYPE_DATETIME) {
87
        CastParameters parameters;
88
        if (!CastToDateOrDatetime::from_string<true>({str.data(), str.size()}, res, nullptr,
89
                                                     parameters)) {
90
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
91
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
92
                    str);
93
        }
94
        return Status::OK();
95
    }
96
    if constexpr (PType == TYPE_DATEV2) {
97
        CastParameters parameters;
98
        if (!CastToDateV2::from_string({str.data(), str.size()}, res, nullptr, parameters)) {
99
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
100
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
101
                    str);
102
        }
103
        return Status::OK();
104
    }
105
    if constexpr (PType == TYPE_DATETIMEV2) {
106
        CastParameters parameters;
107
        if (!CastToDatetimeV2::from_string({str.data(), str.size()}, res, nullptr,
108
                                           data_type->get_scale(), parameters)) {
109
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
110
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
111
                    str);
112
        }
113
        return Status::OK();
114
    }
115
    if constexpr (PType == TYPE_TIMESTAMPTZ) {
116
        CastParameters parameters;
117
        if (!CastToTimstampTz::from_string({str.data(), str.size()}, res, parameters, nullptr,
118
                                           data_type->get_scale())) {
119
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
120
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
121
                    str);
122
        }
123
        return Status::OK();
124
    }
125
    if constexpr (PType == TYPE_CHAR) {
126
        size_t target = assert_cast<const DataTypeString*>(remove_nullable(data_type).get())->len();
127
        res = {str.data(), str.size()};
128
        if (target > str.size()) {
129
            char* buffer = arena.alloc(target);
130
            memset(buffer, 0, target);
131
            memcpy(buffer, str.data(), str.size());
132
            res = {buffer, target};
133
        }
134
        return Status::OK();
135
    }
136
    if constexpr (PType == TYPE_STRING || PType == TYPE_VARCHAR) {
137
        char* buffer = arena.alloc(str.size());
138
        memcpy(buffer, str.data(), str.size());
139
        res = {buffer, str.size()};
140
        return Status::OK();
141
    }
142
    if constexpr (PType == TYPE_BOOLEAN) {
143
        CastParameters parameters;
144
        UInt8 tmp;
145
        if (!CastToBool::from_string({str.data(), str.size()}, tmp, parameters)) {
146
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
147
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
148
                    str);
149
        }
150
        res = tmp != 0;
151
        return Status::OK();
152
    }
153
1
    if constexpr (PType == TYPE_IPV4) {
154
1
        CastParameters parameters;
155
1
        if (!CastToIPv4::from_string({str.data(), str.size()}, res, parameters)) {
156
0
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
157
0
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
158
0
                    str);
159
0
        }
160
1
        return Status::OK();
161
1
    }
162
    if constexpr (PType == TYPE_IPV6) {
163
        CastParameters parameters;
164
        if (!CastToIPv6::from_string({str.data(), str.size()}, res, parameters)) {
165
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
166
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
167
                    str);
168
        }
169
        return Status::OK();
170
    }
171
    if constexpr (PType == TYPE_DECIMALV2) {
172
        CastParameters parameters;
173
        Decimal128V2 tmp;
174
        if (!CastToDecimal::from_string({str.data(), str.size()}, tmp, data_type->get_precision(),
175
                                        data_type->get_scale(), parameters)) {
176
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
177
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
178
                    str);
179
        }
180
        res = DecimalV2Value(tmp.value);
181
        return Status::OK();
182
1
    } else if constexpr (is_decimal(PType)) {
183
1
        CastParameters parameters;
184
1
        if (!CastToDecimal::from_string({str.data(), str.size()}, res, data_type->get_precision(),
185
1
                                        data_type->get_scale(), parameters)) {
186
1
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
187
1
                    "invalid {} string. str={}", type_to_string(data_type->get_primitive_type()),
188
1
                    str);
189
1
        }
190
1
        return Status::OK();
191
1
    }
192
1
    return Status::Error<ErrorCode::INVALID_ARGUMENT>(
193
1
            "unsupported data type in delete handler. type={}",
194
1
            type_to_string(data_type->get_primitive_type()));
195
1
}
Unexecuted instantiation: _ZN5doris7convertILNS_13PrimitiveTypeE37EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Unexecuted instantiation: _ZN5doris7convertILNS_13PrimitiveTypeE20EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Unexecuted instantiation: _ZN5doris7convertILNS_13PrimitiveTypeE28EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Unexecuted instantiation: _ZN5doris7convertILNS_13PrimitiveTypeE29EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Unexecuted instantiation: _ZN5doris7convertILNS_13PrimitiveTypeE30EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Unexecuted instantiation: _ZN5doris7convertILNS_13PrimitiveTypeE35EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Unexecuted instantiation: _ZN5doris7convertILNS_13PrimitiveTypeE15EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Unexecuted instantiation: _ZN5doris7convertILNS_13PrimitiveTypeE10EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
Unexecuted instantiation: _ZN5doris7convertILNS_13PrimitiveTypeE23EEENS_6StatusERKSt10shared_ptrIKNS_9IDataTypeEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_5ArenaERNS_19PrimitiveTypeTraitsIXT_EE7CppTypeE
196
197
#define CONVERT_CASE(PType)                                            \
198
2
    case PType: {                                                      \
199
2
        set = build_set<PType>();                                      \
200
5
        for (const auto& s : str) {                                    \
201
5
            typename PrimitiveTypeTraits<PType>::CppType tmp;          \
202
5
            RETURN_IF_ERROR(convert<PType>(data_type, s, arena, tmp)); \
203
5
            set->insert(reinterpret_cast<const void*>(&tmp));          \
204
5
        }                                                              \
205
2
        return Status::OK();                                           \
206
2
    }
207
Status convert(const DataTypePtr& data_type, const std::list<std::string>& str, Arena& arena,
208
2
               std::shared_ptr<HybridSetBase>& set) {
209
2
    switch (data_type->get_primitive_type()) {
210
0
        CONVERT_CASE(TYPE_TINYINT);
211
0
        CONVERT_CASE(TYPE_SMALLINT);
212
0
        CONVERT_CASE(TYPE_INT);
213
0
        CONVERT_CASE(TYPE_BIGINT);
214
0
        CONVERT_CASE(TYPE_LARGEINT);
215
0
        CONVERT_CASE(TYPE_FLOAT);
216
0
        CONVERT_CASE(TYPE_DOUBLE);
217
0
        CONVERT_CASE(TYPE_DATE);
218
0
        CONVERT_CASE(TYPE_DATETIME);
219
0
        CONVERT_CASE(TYPE_DATEV2);
220
0
        CONVERT_CASE(TYPE_DATETIMEV2);
221
2
        CONVERT_CASE(TYPE_TIMESTAMPTZ);
222
0
        CONVERT_CASE(TYPE_BOOLEAN);
223
0
        CONVERT_CASE(TYPE_IPV4);
224
0
        CONVERT_CASE(TYPE_IPV6);
225
0
        CONVERT_CASE(TYPE_DECIMALV2);
226
0
        CONVERT_CASE(TYPE_DECIMAL32);
227
0
        CONVERT_CASE(TYPE_DECIMAL64);
228
0
        CONVERT_CASE(TYPE_DECIMAL128I);
229
0
        CONVERT_CASE(TYPE_DECIMAL256);
230
0
        CONVERT_CASE(TYPE_CHAR);
231
0
        CONVERT_CASE(TYPE_VARCHAR);
232
0
        CONVERT_CASE(TYPE_STRING);
233
0
    default:
234
0
        return Status::Error<ErrorCode::INVALID_ARGUMENT>(
235
0
                "unsupported data type in delete handler. type={}",
236
0
                type_to_string(data_type->get_primitive_type()));
237
2
    }
238
0
    return Status::OK();
239
2
}
240
#undef CONVERT_CASE
241
242
#define CONVERT_CASE(PType)                                                                       \
243
106
    case PType: {                                                                                 \
244
106
        typename PrimitiveTypeTraits<PType>::CppType tmp;                                         \
245
106
        RETURN_IF_ERROR(convert<PType>(type, res.value_str.front(), arena, tmp));                 \
246
106
        v = Field::create_field<PType>(tmp);                                                      \
247
99
        switch (res.condition_op) {                                                               \
248
10
        case PredicateType::EQ:                                                                   \
249
10
            predicate = create_comparison_predicate<PredicateType::EQ>(index, col_name, type, v,  \
250
10
                                                                       true);                     \
251
10
            return Status::OK();                                                                  \
252
7
        case PredicateType::NE:                                                                   \
253
7
            predicate = create_comparison_predicate<PredicateType::NE>(index, col_name, type, v,  \
254
7
                                                                       true);                     \
255
7
            return Status::OK();                                                                  \
256
2
        case PredicateType::GT:                                                                   \
257
2
            predicate = create_comparison_predicate<PredicateType::GT>(index, col_name, type, v,  \
258
2
                                                                       true);                     \
259
2
            return Status::OK();                                                                  \
260
2
        case PredicateType::GE:                                                                   \
261
2
            predicate = create_comparison_predicate<PredicateType::GE>(index, col_name, type, v,  \
262
2
                                                                       true);                     \
263
2
            return Status::OK();                                                                  \
264
76
        case PredicateType::LT:                                                                   \
265
76
            predicate = create_comparison_predicate<PredicateType::LT>(index, col_name, type, v,  \
266
76
                                                                       true);                     \
267
76
            return Status::OK();                                                                  \
268
2
        case PredicateType::LE:                                                                   \
269
2
            predicate = create_comparison_predicate<PredicateType::LE>(index, col_name, type, v,  \
270
2
                                                                       true);                     \
271
2
            return Status::OK();                                                                  \
272
0
        default:                                                                                  \
273
0
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(                                    \
274
0
                    "invalid condition operator. operator={}", type_to_op_str(res.condition_op)); \
275
99
        }                                                                                         \
276
99
    }
277
Status parse_to_predicate(const uint32_t index, const std::string col_name, const DataTypePtr& type,
278
                          DeleteHandler::ConditionParseResult& res, Arena& arena,
279
181
                          std::shared_ptr<ColumnPredicate>& predicate) {
280
181
    DCHECK_EQ(res.value_str.size(), 1);
281
181
    if (res.condition_op == PredicateType::IS_NULL ||
282
181
        res.condition_op == PredicateType::IS_NOT_NULL) {
283
37
        predicate = NullPredicate::create_shared(index, col_name,
284
37
                                                 res.condition_op == PredicateType::IS_NOT_NULL,
285
37
                                                 type->get_primitive_type());
286
37
        return Status::OK();
287
37
    }
288
144
    Field v;
289
144
    switch (type->get_primitive_type()) {
290
16
        CONVERT_CASE(TYPE_TINYINT);
291
16
        CONVERT_CASE(TYPE_SMALLINT);
292
150
        CONVERT_CASE(TYPE_INT);
293
0
        CONVERT_CASE(TYPE_BIGINT);
294
0
        CONVERT_CASE(TYPE_LARGEINT);
295
0
        CONVERT_CASE(TYPE_FLOAT);
296
0
        CONVERT_CASE(TYPE_DOUBLE);
297
0
        CONVERT_CASE(TYPE_DATE);
298
0
        CONVERT_CASE(TYPE_DATETIME);
299
0
        CONVERT_CASE(TYPE_DATEV2);
300
0
        CONVERT_CASE(TYPE_DATETIMEV2);
301
21
        CONVERT_CASE(TYPE_TIMESTAMPTZ);
302
0
        CONVERT_CASE(TYPE_BOOLEAN);
303
2
        CONVERT_CASE(TYPE_IPV4);
304
0
        CONVERT_CASE(TYPE_IPV6);
305
0
        CONVERT_CASE(TYPE_DECIMALV2);
306
0
        CONVERT_CASE(TYPE_DECIMAL32);
307
0
        CONVERT_CASE(TYPE_DECIMAL64);
308
0
        CONVERT_CASE(TYPE_DECIMAL128I);
309
0
        CONVERT_CASE(TYPE_DECIMAL256);
310
0
    case TYPE_CHAR:
311
0
    case TYPE_VARCHAR:
312
38
    case TYPE_STRING: {
313
38
        v = Field::create_field<TYPE_STRING>(res.value_str.front());
314
38
        switch (res.condition_op) {
315
38
        case PredicateType::EQ:
316
38
            predicate =
317
38
                    create_comparison_predicate<PredicateType::EQ>(index, col_name, type, v, true);
318
38
            return Status::OK();
319
0
        case PredicateType::NE:
320
0
            predicate =
321
0
                    create_comparison_predicate<PredicateType::NE>(index, col_name, type, v, true);
322
0
            return Status::OK();
323
0
        case PredicateType::GT:
324
0
            predicate =
325
0
                    create_comparison_predicate<PredicateType::GT>(index, col_name, type, v, true);
326
0
            return Status::OK();
327
0
        case PredicateType::GE:
328
0
            predicate =
329
0
                    create_comparison_predicate<PredicateType::GE>(index, col_name, type, v, true);
330
0
            return Status::OK();
331
0
        case PredicateType::LT:
332
0
            predicate =
333
0
                    create_comparison_predicate<PredicateType::LT>(index, col_name, type, v, true);
334
0
            return Status::OK();
335
0
        case PredicateType::LE:
336
0
            predicate =
337
0
                    create_comparison_predicate<PredicateType::LE>(index, col_name, type, v, true);
338
0
            return Status::OK();
339
0
        default:
340
0
            return Status::Error<ErrorCode::INVALID_ARGUMENT>(
341
0
                    "invalid condition operator. operator={}", type_to_op_str(res.condition_op));
342
38
        }
343
0
        break;
344
38
    }
345
0
    default:
346
0
        return Status::Error<ErrorCode::INVALID_ARGUMENT>(
347
0
                "unsupported data type in delete handler. type={}",
348
0
                type_to_string(type->get_primitive_type()));
349
144
    }
350
0
    return Status::OK();
351
144
#undef CONVERT_CASE
352
144
}
353
354
Status parse_to_in_predicate(const uint32_t index, const std::string& col_name,
355
                             const DataTypePtr& type, DeleteHandler::ConditionParseResult& res,
356
2
                             Arena& arena, std::shared_ptr<ColumnPredicate>& predicate) {
357
2
    DCHECK_GT(res.value_str.size(), 1);
358
2
    switch (res.condition_op) {
359
1
    case PredicateType::IN_LIST: {
360
1
        std::shared_ptr<HybridSetBase> set;
361
1
        RETURN_IF_ERROR(convert(type, res.value_str, arena, set));
362
1
        predicate =
363
1
                create_in_list_predicate<PredicateType::IN_LIST>(index, col_name, type, set, true);
364
1
        break;
365
1
    }
366
1
    case PredicateType::NOT_IN_LIST: {
367
1
        std::shared_ptr<HybridSetBase> set;
368
1
        RETURN_IF_ERROR(convert(type, res.value_str, arena, set));
369
1
        predicate = create_in_list_predicate<PredicateType::NOT_IN_LIST>(index, col_name, type, set,
370
1
                                                                         true);
371
1
        break;
372
1
    }
373
0
    default:
374
0
        return Status::Error<ErrorCode::INVALID_ARGUMENT>("invalid condition operator. operator={}",
375
0
                                                          type_to_op_str(res.condition_op));
376
2
    }
377
2
    return Status::OK();
378
2
}
379
380
// construct sub condition from TCondition
381
101
std::string construct_sub_predicate(const TCondition& condition) {
382
101
    string op = condition.condition_op;
383
101
    if (op == "<") {
384
50
        op += "<";
385
51
    } else if (op == ">") {
386
3
        op += ">";
387
3
    }
388
101
    string condition_str;
389
101
    if ("IS" == op) {
390
        // ATTN: tricky! Surround IS with spaces to make it "special"
391
2
        condition_str = condition.column_name + " IS " + condition.condition_values[0];
392
99
    } else { // multi-elements IN expr has been processed with InPredicatePB
393
99
        if (op == "*=") {
394
2
            op = "=";
395
97
        } else if (op == "!*=") {
396
2
            op = "!=";
397
2
        }
398
99
        condition_str = condition.column_name + op + "'" + condition.condition_values[0] + "'";
399
99
    }
400
101
    return condition_str;
401
101
}
402
403
// make operators from FE adaptive to BE
404
101
std::string trans_op(const std::string& opt) {
405
101
    std::string op = string(opt);
406
101
    if (op == "<") {
407
50
        op += "<";
408
51
    } else if (op == ">") {
409
3
        op += ">";
410
3
    }
411
101
    if ("IS" != op) {
412
99
        if (op == "*=") {
413
2
            op = "=";
414
97
        } else if (op == "!*=") {
415
2
            op = "!=";
416
2
        }
417
99
    }
418
101
    return op;
419
101
}
420
421
Status DeleteHandler::generate_delete_predicate(const TabletSchema& schema,
422
                                                const std::vector<TCondition>& conditions,
423
106
                                                DeletePredicatePB* del_pred) {
424
106
    DBUG_EXECUTE_IF("DeleteHandler::generate_delete_predicate.inject_failure", {
425
106
        return Status::Error<false>(dp->param<int>("error_code"),
426
106
                                    dp->param<std::string>("error_msg"));
427
106
    })
428
106
    if (conditions.empty()) {
429
1
        return Status::Error<ErrorCode::INVALID_ARGUMENT>(
430
1
                "invalid parameters for store_cond. condition_size={}", conditions.size());
431
1
    }
432
433
    // Check whether the delete condition meets the requirements
434
135
    for (const TCondition& condition : conditions) {
435
135
        RETURN_IF_ERROR(check_condition_valid(schema, condition));
436
135
    }
437
438
    // Store delete condition
439
105
    for (const TCondition& condition : conditions) {
440
105
        if (condition.condition_values.size() > 1) {
441
4
            InPredicatePB* in_pred = del_pred->add_in_predicates();
442
4
            if (condition.__isset.column_unique_id) {
443
0
                in_pred->set_column_unique_id(condition.column_unique_id);
444
0
            }
445
4
            in_pred->set_column_name(condition.column_name);
446
4
            bool is_not_in = condition.condition_op == "!*=";
447
4
            in_pred->set_is_not_in(is_not_in);
448
10
            for (const auto& condition_value : condition.condition_values) {
449
10
                in_pred->add_values(condition_value);
450
10
            }
451
452
4
            LOG(INFO) << "store one sub-delete condition. condition name=" << in_pred->column_name()
453
4
                      << "condition size=" << in_pred->values().size();
454
101
        } else {
455
            // write sub predicate v1 for compactbility
456
101
            std::string condition_str = construct_sub_predicate(condition);
457
101
            VLOG_NOTICE << __PRETTY_FUNCTION__ << " condition_str: " << condition_str;
458
101
            del_pred->add_sub_predicates(condition_str);
459
101
            DeleteSubPredicatePB* sub_predicate = del_pred->add_sub_predicates_v2();
460
101
            if (condition.__isset.column_unique_id) {
461
                // only light schema change capable table set this field
462
0
                sub_predicate->set_column_unique_id(condition.column_unique_id);
463
101
            } else {
464
101
                try {
465
101
                    [[maybe_unused]] auto parsed_cond = parse_condition(condition_str);
466
101
                } catch (const Exception& e) {
467
0
                    return Status::Error<ErrorCode::INVALID_ARGUMENT>(
468
0
                            "failed to parse condition_str, condition={}, error={}",
469
0
                            ThriftDebugString(condition), e.to_string());
470
0
                }
471
101
            }
472
473
101
            sub_predicate->set_column_name(condition.column_name);
474
101
            sub_predicate->set_op(trans_op(condition.condition_op));
475
101
            sub_predicate->set_cond_value(condition.condition_values[0]);
476
101
            LOG(INFO) << "store one sub-delete condition. condition="
477
101
                      << fmt::format(" {} {} {}", condition.column_name, condition.condition_op,
478
101
                                     condition.condition_values[0]);
479
101
        }
480
105
    }
481
75
    del_pred->set_version(-1);
482
483
75
    return Status::OK();
484
75
}
485
486
Status DeleteHandler::convert_to_sub_pred_v2(DeletePredicatePB* delete_pred,
487
0
                                             TabletSchemaSPtr schema) {
488
0
    if (!delete_pred->sub_predicates().empty() && delete_pred->sub_predicates_v2().empty()) {
489
0
        for (const auto& condition_str : delete_pred->sub_predicates()) {
490
0
            auto* sub_pred = delete_pred->add_sub_predicates_v2();
491
0
            auto condition = parse_condition(condition_str);
492
0
            const auto& column = *DORIS_TRY(schema->column(condition.column_name));
493
0
            sub_pred->set_column_unique_id(column.unique_id());
494
0
            sub_pred->set_column_name(condition.column_name);
495
0
            sub_pred->set_op(type_to_op_str(condition.condition_op));
496
0
            sub_pred->set_cond_value(condition.value_str.front());
497
0
        }
498
0
    }
499
500
0
    auto* in_pred_list = delete_pred->mutable_in_predicates();
501
0
    for (auto& in_pred : *in_pred_list) {
502
0
        const auto& column = *DORIS_TRY(schema->column(in_pred.column_name()));
503
0
        in_pred.set_column_unique_id(column.unique_id());
504
0
    }
505
0
    return Status::OK();
506
0
}
507
508
bool DeleteHandler::is_condition_value_valid(const TabletColumn& column,
509
                                             const std::string& condition_op,
510
140
                                             const string& value_str) {
511
140
    if ("IS" == condition_op && ("NULL" == value_str || "NOT NULL" == value_str)) {
512
2
        return true;
513
2
    }
514
515
138
    FieldType field_type = column.type();
516
138
    switch (field_type) {
517
11
    case FieldType::OLAP_FIELD_TYPE_TINYINT:
518
11
        return valid_signed_number<int8_t>(value_str);
519
13
    case FieldType::OLAP_FIELD_TYPE_SMALLINT:
520
13
        return valid_signed_number<int16_t>(value_str);
521
54
    case FieldType::OLAP_FIELD_TYPE_INT:
522
54
        return valid_signed_number<int32_t>(value_str);
523
5
    case FieldType::OLAP_FIELD_TYPE_BIGINT:
524
5
        return valid_signed_number<int64_t>(value_str);
525
4
    case FieldType::OLAP_FIELD_TYPE_LARGEINT:
526
4
        return valid_signed_number<int128_t>(value_str);
527
0
    case FieldType::OLAP_FIELD_TYPE_UNSIGNED_TINYINT:
528
0
        return valid_unsigned_number<uint8_t>(value_str);
529
0
    case FieldType::OLAP_FIELD_TYPE_UNSIGNED_SMALLINT:
530
0
        return valid_unsigned_number<uint16_t>(value_str);
531
0
    case FieldType::OLAP_FIELD_TYPE_UNSIGNED_INT:
532
0
        return valid_unsigned_number<uint32_t>(value_str);
533
0
    case FieldType::OLAP_FIELD_TYPE_UNSIGNED_BIGINT:
534
0
        return valid_unsigned_number<uint64_t>(value_str);
535
7
    case FieldType::OLAP_FIELD_TYPE_DECIMAL:
536
7
        return valid_decimal(value_str, column.precision(), column.frac());
537
0
    case FieldType::OLAP_FIELD_TYPE_DECIMAL32:
538
0
        return valid_decimal(value_str, column.precision(), column.frac());
539
0
    case FieldType::OLAP_FIELD_TYPE_DECIMAL64:
540
0
        return valid_decimal(value_str, column.precision(), column.frac());
541
0
    case FieldType::OLAP_FIELD_TYPE_DECIMAL128I:
542
0
        return valid_decimal(value_str, column.precision(), column.frac());
543
0
    case FieldType::OLAP_FIELD_TYPE_DECIMAL256:
544
0
        return valid_decimal(value_str, column.precision(), column.frac());
545
3
    case FieldType::OLAP_FIELD_TYPE_CHAR:
546
7
    case FieldType::OLAP_FIELD_TYPE_VARCHAR:
547
7
        return value_str.size() <= column.length();
548
0
    case FieldType::OLAP_FIELD_TYPE_STRING:
549
0
        return value_str.size() <= config::string_type_length_soft_limit_bytes;
550
5
    case FieldType::OLAP_FIELD_TYPE_DATE:
551
11
    case FieldType::OLAP_FIELD_TYPE_DATETIME:
552
11
    case FieldType::OLAP_FIELD_TYPE_DATEV2:
553
11
    case FieldType::OLAP_FIELD_TYPE_DATETIMEV2:
554
24
    case FieldType::OLAP_FIELD_TYPE_TIMESTAMPTZ:
555
24
        return valid_datetime(value_str, column.frac());
556
0
    case FieldType::OLAP_FIELD_TYPE_BOOL:
557
0
        return valid_bool(value_str);
558
5
    case FieldType::OLAP_FIELD_TYPE_IPV4:
559
5
        return valid_ipv4(value_str);
560
8
    case FieldType::OLAP_FIELD_TYPE_IPV6:
561
8
        return valid_ipv6(value_str);
562
0
    default:
563
0
        LOG(WARNING) << "unknown field type. [type=" << int(field_type) << "]";
564
138
    }
565
0
    return false;
566
138
}
567
568
135
Status DeleteHandler::check_condition_valid(const TabletSchema& schema, const TCondition& cond) {
569
    // Check whether the column exists
570
135
    int32_t field_index = schema.field_index(cond.column_name);
571
135
    if (field_index < 0) {
572
1
        return Status::Error<ErrorCode::INVALID_ARGUMENT>("field is not existent. [field_index={}]",
573
1
                                                          field_index);
574
1
    }
575
576
    // Delete condition should only applied on key columns or duplicate key table, and
577
    // the condition column type should not be float or double.
578
134
    const TabletColumn& column = schema.column(field_index);
579
580
134
    if (column.type() == FieldType::OLAP_FIELD_TYPE_DOUBLE ||
581
134
        column.type() == FieldType::OLAP_FIELD_TYPE_FLOAT) {
582
0
        return Status::Error<ErrorCode::INVALID_ARGUMENT>("data type is float or double.");
583
0
    }
584
585
    // Check operator and operands size are matched.
586
134
    if ("*=" != cond.condition_op && "!*=" != cond.condition_op &&
587
134
        cond.condition_values.size() != 1) {
588
0
        return Status::Error<ErrorCode::INVALID_ARGUMENT>("invalid condition value size. [size={}]",
589
0
                                                          cond.condition_values.size());
590
0
    }
591
592
    // Check each operand is valid
593
140
    for (const auto& condition_value : cond.condition_values) {
594
140
        if (!is_condition_value_valid(column, cond.condition_op, condition_value)) {
595
29
            return Status::Error<ErrorCode::INVALID_ARGUMENT>("invalid condition value. [value={}]",
596
29
                                                              condition_value);
597
29
        }
598
140
    }
599
600
105
    if (!cond.__isset.column_unique_id) {
601
105
        LOG(WARNING) << "column=" << cond.column_name
602
105
                     << " in predicate does not have uid, table id=" << schema.table_id();
603
        // TODO(tsy): make it fail here after FE forbidding hard-link-schema-change
604
105
        return Status::OK();
605
105
    }
606
0
    if (schema.field_index(cond.column_unique_id) == -1) {
607
0
        const auto& err_msg =
608
0
                fmt::format("column id does not exists in table={}, schema version={},",
609
0
                            schema.table_id(), schema.schema_version());
610
0
        return Status::Error<ErrorCode::INVALID_ARGUMENT>(err_msg);
611
0
    }
612
0
    if (!iequal(schema.column_by_uid(cond.column_unique_id).name(), cond.column_name)) {
613
0
        const auto& err_msg = fmt::format(
614
0
                "colum name={} does not belongs to column uid={}, which "
615
0
                "column name={}, "
616
0
                "delete_cond.column_name ={}",
617
0
                cond.column_name, cond.column_unique_id,
618
0
                schema.column_by_uid(cond.column_unique_id).name(), cond.column_name);
619
0
        return Status::Error<ErrorCode::INVALID_ARGUMENT>(err_msg);
620
0
    }
621
622
0
    return Status::OK();
623
0
}
624
625
PredicateType DeleteHandler::parse_condition_op(const std::string& op_str,
626
302
                                                const std::list<std::string>& cond_values) {
627
302
    if (trim(to_lower(op_str)) == "=") {
628
92
        return PredicateType::EQ;
629
210
    } else if (trim(to_lower(op_str)) == "!=") {
630
18
        return PredicateType::NE;
631
192
    } else if (trim(to_lower(op_str)) == ">>") {
632
9
        return PredicateType::GT;
633
183
    } else if (trim(to_lower(op_str)) == "<<") {
634
129
        return PredicateType::LT;
635
129
    } else if (trim(to_lower(op_str)) == ">=") {
636
5
        return PredicateType::GE;
637
49
    } else if (trim(to_lower(op_str)) == "<=") {
638
7
        return PredicateType::LE;
639
42
    } else if (trim(to_lower(op_str)) == "*=") {
640
0
        return cond_values.size() > 1 ? PredicateType::IN_LIST : PredicateType::EQ;
641
42
    } else if (trim(to_lower(op_str)) == "!*=") {
642
0
        return cond_values.size() > 1 ? PredicateType::NOT_IN_LIST : PredicateType::NE;
643
42
    } else if (trim(to_lower(op_str)) == "is") {
644
42
        return to_lower(cond_values.front()) == "null" ? PredicateType::IS_NULL
645
42
                                                       : PredicateType::IS_NOT_NULL;
646
42
    } else {
647
0
        throw Exception(Status::Error<ErrorCode::INVALID_ARGUMENT>(
648
0
                "invalid condition operator. operator={}", op_str));
649
0
    }
650
0
    return PredicateType::UNKNOWN;
651
302
}
652
653
DeleteHandler::ConditionParseResult DeleteHandler::parse_condition(
654
100
        const DeleteSubPredicatePB& sub_cond) {
655
100
    ConditionParseResult res;
656
100
    if (!sub_cond.has_column_name() || !sub_cond.has_op() || !sub_cond.has_cond_value()) {
657
0
        throw Exception(Status::Error<ErrorCode::INVALID_ARGUMENT>(
658
0
                "fail to parse condition. condition={} {} {}", sub_cond.column_name(),
659
0
                sub_cond.op(), sub_cond.cond_value()));
660
0
    }
661
100
    if (sub_cond.has_column_unique_id()) {
662
0
        res.col_unique_id = sub_cond.column_unique_id();
663
0
    }
664
100
    res.column_name = sub_cond.column_name();
665
100
    res.value_str.push_back(sub_cond.cond_value());
666
100
    res.condition_op = parse_condition_op(sub_cond.op(), res.value_str);
667
100
    return res;
668
100
}
669
670
// clang-format off
671
// Condition string format, the format is (column_name)(op)(value)
672
// eg: condition_str="c1 = 1597751948193618247 and length(source)<1;\n;\n"
673
// column_name: matches "c1", must include FeNameFormat.java COLUMN_NAME_REGEX
674
//              and compactible with any the lagacy
675
// operator: matches "="
676
// value: matches "1597751948193618247  and length(source)<1;\n;\n"
677
//
678
// For more info, see DeleteHandler::construct_sub_predicates
679
// FIXME(gavin): This is a tricky implementation, it should not be the final resolution, refactor it.
680
const char* const CONDITION_STR_PATTERN =
681
    // .----------------- column-name --------------------------.   .----------------------- operator ------------------------.   .------------ value ----------.
682
    R"(([_a-zA-Z@0-9\s/\p{L}][.a-zA-Z0-9_+-/?@#$%^&*"\s,:\p{L}]*)\s*((?:=)|(?:!=)|(?:>>)|(?:<<)|(?:>=)|(?:<=)|(?:\*=)|(?: IS ))\s*('((?:[\s\S]+)?)'|(?:[\s\S]+)?))";
683
    // '----------------- group 1 ------------------------------'   '--------------------- group 2 ---------------------------'   | '-- group 4--'              |
684
    //                                                                   match any of: = != >> << >= <= *= " IS "                 '----------- group 3 ---------'
685
    //                                                                                                                             match **ANY THING** without(4)
686
    //                                                                                                                             or with(3) single quote
687
// clang-format on
688
RE2 DELETE_HANDLER_REGEX(CONDITION_STR_PATTERN);
689
690
DeleteHandler::ConditionParseResult DeleteHandler::parse_condition(
691
182
        const std::string& condition_str) {
692
182
    ConditionParseResult res;
693
182
    std::string col_name, op, value, g4;
694
695
182
    bool matched = RE2::FullMatch(condition_str, DELETE_HANDLER_REGEX, &col_name, &op, &value,
696
182
                                  &g4); // exact match
697
698
182
    if (!matched) {
699
0
        throw Exception(
700
0
                Status::InvalidArgument("fail to sub condition. condition={}", condition_str));
701
0
    }
702
703
182
    res.column_name = col_name;
704
705
    // match string with single quotes, a = b  or a = 'b'
706
182
    if (!g4.empty()) {
707
141
        res.value_str.push_back(g4);
708
141
    } else {
709
41
        res.value_str.push_back(value);
710
41
    }
711
182
    res.condition_op = DeleteHandler::parse_condition_op(op, res.value_str);
712
182
    VLOG_NOTICE << "parsed condition_str: col_name={" << col_name << "} op={" << op << "} val={"
713
48
                << res.value_str.back() << "}";
714
182
    return res;
715
182
}
716
717
template <typename SubPredType>
718
    requires(std::is_same_v<SubPredType, DeleteSubPredicatePB> or
719
             std::is_same_v<SubPredType, std::string>)
720
Status DeleteHandler::_parse_column_pred(TabletSchemaSPtr complete_schema,
721
                                         TabletSchemaSPtr delete_pred_related_schema,
722
                                         const RepeatedPtrField<SubPredType>& sub_pred_list,
723
169
                                         DeleteConditions* delete_conditions) {
724
181
    for (const auto& sub_predicate : sub_pred_list) {
725
181
        auto condition = parse_condition(sub_predicate);
726
181
        int32_t col_unique_id = -1;
727
181
        if constexpr (std::is_same_v<SubPredType, DeleteSubPredicatePB>) {
728
100
            if (sub_predicate.has_column_unique_id()) [[likely]] {
729
0
                col_unique_id = sub_predicate.column_unique_id();
730
0
            }
731
100
        }
732
181
        if (col_unique_id < 0) {
733
181
            const auto& column =
734
181
                    *DORIS_TRY(delete_pred_related_schema->column(condition.column_name));
735
181
            col_unique_id = column.unique_id();
736
181
        }
737
181
        condition.col_unique_id = col_unique_id;
738
181
        const auto& column = complete_schema->column_by_uid(col_unique_id);
739
181
        uint32_t index = complete_schema->field_index(col_unique_id);
740
181
        std::shared_ptr<ColumnPredicate> predicate;
741
181
        RETURN_IF_ERROR(parse_to_predicate(index, column.name(), column.get_vec_type(), condition,
742
181
                                           _predicate_arena, predicate));
743
174
        if (predicate != nullptr) {
744
174
            delete_conditions->column_predicate_vec.push_back(predicate);
745
174
        }
746
174
    }
747
162
    return Status::OK();
748
169
}
_ZN5doris13DeleteHandler18_parse_column_predINS_20DeleteSubPredicatePBEQoosr3stdE9is_same_vIT_S2_Esr3stdE9is_same_vIS3_NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEENS_6StatusESt10shared_ptrINS_12TabletSchemaEESD_RKN6google8protobuf16RepeatedPtrFieldIS3_EEPNS_16DeleteConditionsE
Line
Count
Source
723
87
                                         DeleteConditions* delete_conditions) {
724
100
    for (const auto& sub_predicate : sub_pred_list) {
725
100
        auto condition = parse_condition(sub_predicate);
726
100
        int32_t col_unique_id = -1;
727
100
        if constexpr (std::is_same_v<SubPredType, DeleteSubPredicatePB>) {
728
100
            if (sub_predicate.has_column_unique_id()) [[likely]] {
729
0
                col_unique_id = sub_predicate.column_unique_id();
730
0
            }
731
100
        }
732
100
        if (col_unique_id < 0) {
733
100
            const auto& column =
734
100
                    *DORIS_TRY(delete_pred_related_schema->column(condition.column_name));
735
100
            col_unique_id = column.unique_id();
736
100
        }
737
100
        condition.col_unique_id = col_unique_id;
738
100
        const auto& column = complete_schema->column_by_uid(col_unique_id);
739
100
        uint32_t index = complete_schema->field_index(col_unique_id);
740
100
        std::shared_ptr<ColumnPredicate> predicate;
741
100
        RETURN_IF_ERROR(parse_to_predicate(index, column.name(), column.get_vec_type(), condition,
742
100
                                           _predicate_arena, predicate));
743
100
        if (predicate != nullptr) {
744
100
            delete_conditions->column_predicate_vec.push_back(predicate);
745
100
        }
746
100
    }
747
87
    return Status::OK();
748
87
}
_ZN5doris13DeleteHandler18_parse_column_predINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEQoosr3stdE9is_same_vIT_NS_20DeleteSubPredicatePBEEsr3stdE9is_same_vIS8_S7_EEENS_6StatusESt10shared_ptrINS_12TabletSchemaEESD_RKN6google8protobuf16RepeatedPtrFieldIS8_EEPNS_16DeleteConditionsE
Line
Count
Source
723
82
                                         DeleteConditions* delete_conditions) {
724
82
    for (const auto& sub_predicate : sub_pred_list) {
725
81
        auto condition = parse_condition(sub_predicate);
726
81
        int32_t col_unique_id = -1;
727
        if constexpr (std::is_same_v<SubPredType, DeleteSubPredicatePB>) {
728
            if (sub_predicate.has_column_unique_id()) [[likely]] {
729
                col_unique_id = sub_predicate.column_unique_id();
730
            }
731
        }
732
81
        if (col_unique_id < 0) {
733
81
            const auto& column =
734
81
                    *DORIS_TRY(delete_pred_related_schema->column(condition.column_name));
735
81
            col_unique_id = column.unique_id();
736
81
        }
737
81
        condition.col_unique_id = col_unique_id;
738
81
        const auto& column = complete_schema->column_by_uid(col_unique_id);
739
81
        uint32_t index = complete_schema->field_index(col_unique_id);
740
81
        std::shared_ptr<ColumnPredicate> predicate;
741
81
        RETURN_IF_ERROR(parse_to_predicate(index, column.name(), column.get_vec_type(), condition,
742
81
                                           _predicate_arena, predicate));
743
74
        if (predicate != nullptr) {
744
74
            delete_conditions->column_predicate_vec.push_back(predicate);
745
74
        }
746
74
    }
747
75
    return Status::OK();
748
82
}
749
750
Status DeleteHandler::init(TabletSchemaSPtr tablet_schema,
751
373
                           const std::vector<RowsetMetaSharedPtr>& delete_preds, int64_t version) {
752
373
    DCHECK(!_is_inited) << "reinitialize delete handler.";
753
373
    DCHECK(version >= 0) << "invalid parameters. version=" << version;
754
755
373
    for (const auto& delete_pred : delete_preds) {
756
        // Skip the delete condition with large version
757
169
        if (delete_pred->version().first > version) {
758
0
            continue;
759
0
        }
760
        // Need the tablet schema at the delete condition to parse the accurate column
761
169
        const auto& delete_pred_related_schema = delete_pred->tablet_schema();
762
169
        const auto& delete_condition = delete_pred->delete_predicate();
763
169
        DeleteConditions temp;
764
169
        temp.filter_version = delete_pred->version().first;
765
169
        if (!delete_condition.sub_predicates_v2().empty()) {
766
87
            RETURN_IF_ERROR(_parse_column_pred(tablet_schema, delete_pred_related_schema,
767
87
                                               delete_condition.sub_predicates_v2(), &temp));
768
87
        } else {
769
            // make it compatible with the former versions
770
82
            RETURN_IF_ERROR(_parse_column_pred(tablet_schema, delete_pred_related_schema,
771
82
                                               delete_condition.sub_predicates(), &temp));
772
82
        }
773
162
        for (const auto& in_predicate : delete_condition.in_predicates()) {
774
2
            ConditionParseResult condition;
775
2
            condition.column_name = in_predicate.column_name();
776
777
2
            int32_t col_unique_id = -1;
778
2
            if (in_predicate.has_column_unique_id()) {
779
0
                col_unique_id = in_predicate.column_unique_id();
780
2
            } else {
781
                // if upgrade from version 2.0.x, column_unique_id maybe not set
782
2
                const auto& pre_column =
783
2
                        *DORIS_TRY(delete_pred_related_schema->column(condition.column_name));
784
2
                col_unique_id = pre_column.unique_id();
785
2
            }
786
2
            if (col_unique_id == -1) {
787
0
                return Status::Error<ErrorCode::DELETE_INVALID_CONDITION>(
788
0
                        "cannot get column_unique_id for column {}", condition.column_name);
789
0
            }
790
2
            condition.col_unique_id = col_unique_id;
791
792
2
            condition.condition_op =
793
2
                    in_predicate.is_not_in() ? PredicateType::NOT_IN_LIST : PredicateType::IN_LIST;
794
5
            for (const auto& value : in_predicate.values()) {
795
5
                condition.value_str.push_back(value);
796
5
            }
797
2
            const auto& column = tablet_schema->column_by_uid(col_unique_id);
798
2
            uint32_t index = tablet_schema->field_index(col_unique_id);
799
2
            std::shared_ptr<ColumnPredicate> predicate;
800
2
            RETURN_IF_ERROR(parse_to_in_predicate(index, column.name(), column.get_vec_type(),
801
2
                                                  condition, _predicate_arena, predicate));
802
2
            temp.column_predicate_vec.push_back(predicate);
803
2
        }
804
805
162
        _del_conds.emplace_back(std::move(temp));
806
162
    }
807
808
366
    _is_inited = true;
809
810
366
    return Status::OK();
811
373
}
812
813
390
DeleteHandler::~DeleteHandler() {
814
390
    if (!_is_inited) {
815
24
        return;
816
24
    }
817
818
366
    _del_conds.clear();
819
366
    _is_inited = false;
820
366
}
821
822
void DeleteHandler::get_delete_conditions_after_version(
823
        int64_t version, AndBlockColumnPredicate* and_block_column_predicate_ptr,
824
        std::unordered_map<int32_t, std::vector<std::shared_ptr<const ColumnPredicate>>>*
825
1.08k
                del_predicates_for_zone_map) const {
826
1.08k
    for (const auto& del_cond : _del_conds) {
827
555
        if (del_cond.filter_version > version) {
828
            // now, only query support delete column predicate operator
829
406
            if (!del_cond.column_predicate_vec.empty()) {
830
406
                if (del_cond.column_predicate_vec.size() == 1) {
831
406
                    auto single_column_block_predicate = SingleColumnBlockPredicate::create_unique(
832
406
                            del_cond.column_predicate_vec[0]);
833
406
                    and_block_column_predicate_ptr->add_column_predicate(
834
406
                            std::move(single_column_block_predicate));
835
406
                    if (del_predicates_for_zone_map->count(
836
406
                                del_cond.column_predicate_vec[0]->column_id()) < 1) {
837
406
                        del_predicates_for_zone_map->insert(
838
406
                                {del_cond.column_predicate_vec[0]->column_id(),
839
406
                                 std::vector<std::shared_ptr<const ColumnPredicate>> {}});
840
406
                    }
841
406
                    (*del_predicates_for_zone_map)[del_cond.column_predicate_vec[0]->column_id()]
842
406
                            .push_back(del_cond.column_predicate_vec[0]);
843
406
                } else {
844
0
                    auto or_column_predicate = OrBlockColumnPredicate::create_unique();
845
846
                    // build or_column_predicate
847
                    // when delete from where a = 1 and b = 2, we can not use del_predicates_for_zone_map to filter zone page,
848
                    // so here do not put predicate to del_predicates_for_zone_map,
849
                    // refer #17145 for more details.
850
                    // // TODO: need refactor design and code to use more version delete and more column delete to filter zone page.
851
0
                    std::for_each(del_cond.column_predicate_vec.cbegin(),
852
0
                                  del_cond.column_predicate_vec.cend(),
853
0
                                  [&or_column_predicate](
854
0
                                          const std::shared_ptr<const ColumnPredicate> predicate) {
855
0
                                      or_column_predicate->add_column_predicate(
856
0
                                              SingleColumnBlockPredicate::create_unique(predicate));
857
0
                                  });
858
0
                    and_block_column_predicate_ptr->add_column_predicate(
859
0
                            std::move(or_column_predicate));
860
0
                }
861
406
            }
862
406
        }
863
555
    }
864
1.08k
}
865
866
} // namespace doris