be/src/storage/tablet/tablet_schema.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 <gen_cpp/AgentService_types.h> |
21 | | #include <gen_cpp/Types_types.h> |
22 | | #include <gen_cpp/olap_common.pb.h> |
23 | | #include <gen_cpp/olap_file.pb.h> |
24 | | #include <gen_cpp/segment_v2.pb.h> |
25 | | #include <parallel_hashmap/phmap.h> |
26 | | |
27 | | #include <algorithm> |
28 | | #include <cstdint> |
29 | | #include <map> |
30 | | #include <memory> |
31 | | #include <string> |
32 | | #include <unordered_map> |
33 | | #include <unordered_set> |
34 | | #include <utility> |
35 | | #include <vector> |
36 | | |
37 | | #include "common/consts.h" |
38 | | #include "common/status.h" |
39 | | #include "core/data_type/define_primitive_type.h" |
40 | | #include "core/string_ref.h" |
41 | | #include "core/types.h" |
42 | | #include "exec/common/string_utils/string_utils.h" |
43 | | #include "exprs/aggregate/aggregate_function.h" |
44 | | #include "runtime/descriptors.h" |
45 | | #include "runtime/memory/lru_cache_policy.h" |
46 | | #include "storage/index/inverted/inverted_index_parser.h" |
47 | | #include "storage/metadata_adder.h" |
48 | | #include "storage/olap_common.h" |
49 | | #include "storage/segment/options.h" |
50 | | #include "util/debug_points.h" |
51 | | #include "util/json/path_in_data.h" |
52 | | #include "util/string_parser.hpp" |
53 | | #include "util/string_util.h" |
54 | | |
55 | | namespace doris { |
56 | | class Block; |
57 | | class PathInData; |
58 | | class IDataType; |
59 | | |
60 | | struct OlapTableIndexSchema; |
61 | | class TColumn; |
62 | | class TOlapTableIndex; |
63 | | class TabletColumn; |
64 | | |
65 | | using TabletColumnPtr = std::shared_ptr<TabletColumn>; |
66 | | |
67 | | class TabletColumn : public MetadataAdder<TabletColumn> { |
68 | | public: |
69 | | struct VariantParams { |
70 | | int32_t max_subcolumns_count = 0; |
71 | | bool enable_typed_paths_to_sparse = false; |
72 | | int32_t max_sparse_column_statistics_size = |
73 | | BeConsts::DEFAULT_VARIANT_MAX_SPARSE_COLUMN_STATS_SIZE; |
74 | | // default to 0, no shard |
75 | | int32_t sparse_hash_shard_count = 0; |
76 | | |
77 | | bool enable_doc_mode = false; |
78 | | int64_t doc_materialization_min_rows = 0; |
79 | | int32_t doc_hash_shard_count = 64; |
80 | | |
81 | | bool enable_nested_group = false; |
82 | | }; |
83 | | |
84 | | TabletColumn(); |
85 | | TabletColumn(const ColumnPB& column); |
86 | | TabletColumn(const TColumn& column); |
87 | | TabletColumn(FieldAggregationMethod agg, FieldType type); |
88 | | TabletColumn(FieldAggregationMethod agg, FieldType filed_type, bool is_nullable); |
89 | | TabletColumn(FieldAggregationMethod agg, FieldType filed_type, bool is_nullable, |
90 | | int32_t unique_id, size_t length); |
91 | | |
92 | | #ifdef BE_TEST |
93 | | virtual ~TabletColumn() = default; |
94 | | #endif |
95 | | |
96 | | void init_from_pb(const ColumnPB& column); |
97 | | void init_from_thrift(const TColumn& column); |
98 | | void to_schema_pb(ColumnPB* column) const; |
99 | | |
100 | 250M | int32_t unique_id() const { return _unique_id; } |
101 | 2.31k | void set_unique_id(int32_t id) { _unique_id = id; } |
102 | 1.19G | const std::string& name() const { return _col_name; } |
103 | 194k | const std::string& name_lower_case() const { return _col_name_lower_case; } |
104 | 400k | void set_name(std::string col_name) { |
105 | 400k | _col_name = col_name; |
106 | 400k | _col_name_lower_case = to_lower(_col_name); |
107 | 400k | } |
108 | 727M | MOCK_FUNCTION FieldType type() const { return _type; } |
109 | 336k | void set_type(FieldType type) { _type = type; } |
110 | 180M | bool is_key() const { return _is_key; } |
111 | 144M | bool is_nullable() const { return _is_nullable; } |
112 | 32 | bool is_auto_increment() const { return _is_auto_increment; } |
113 | 36 | bool is_seqeunce_col() const { return _col_name == SEQUENCE_COL; } |
114 | 7.60k | bool is_on_update_current_timestamp() const { return _is_on_update_current_timestamp; } |
115 | 118M | bool is_variant_type() const { return _type == FieldType::OLAP_FIELD_TYPE_VARIANT; } |
116 | 1.69M | bool is_bf_column() const { return _is_bf_column; } |
117 | 38.9M | bool is_array_type() const { return _type == FieldType::OLAP_FIELD_TYPE_ARRAY; } |
118 | 18.3M | bool is_agg_state_type() const { return _type == FieldType::OLAP_FIELD_TYPE_AGG_STATE; } |
119 | 0 | bool is_jsonb_type() const { return _type == FieldType::OLAP_FIELD_TYPE_JSONB; } |
120 | 21.2k | bool is_length_variable_type() const { |
121 | 21.2k | return _type == FieldType::OLAP_FIELD_TYPE_CHAR || |
122 | 21.2k | _type == FieldType::OLAP_FIELD_TYPE_VARCHAR || |
123 | 21.2k | _type == FieldType::OLAP_FIELD_TYPE_STRING || |
124 | 21.2k | _type == FieldType::OLAP_FIELD_TYPE_HLL || |
125 | 21.2k | _type == FieldType::OLAP_FIELD_TYPE_BITMAP || |
126 | 21.2k | _type == FieldType::OLAP_FIELD_TYPE_QUANTILE_STATE || |
127 | 21.2k | _type == FieldType::OLAP_FIELD_TYPE_AGG_STATE; |
128 | 21.2k | } |
129 | 74.9k | bool has_default_value() const { return _has_default_value; } |
130 | 940k | std::string default_value() const { return _default_value; } |
131 | 20 | bool has_default_value_expr() const { return _has_default_value_expr; } |
132 | 5 | const std::string& default_value_expr() const { return _default_value_expr; } |
133 | 96.8M | int32_t length() const { return _length; } |
134 | 130k | void set_length(int32_t length) { _length = length; } |
135 | 21.5k | void set_default_value(const std::string& default_value) { |
136 | 21.5k | _default_value = default_value; |
137 | 21.5k | _has_default_value = true; |
138 | 21.5k | } |
139 | | void set_default_value_expr(const std::string& default_value_expr) { |
140 | | _default_value_expr = default_value_expr; |
141 | | _has_default_value_expr = true; |
142 | | } |
143 | 188k | int32_t index_length() const { return _index_length; } |
144 | 102k | void set_index_length(int32_t index_length) { _index_length = index_length; } |
145 | | void set_is_key(bool is_key) { _is_key = is_key; } |
146 | 142k | void set_is_nullable(bool is_nullable) { _is_nullable = is_nullable; } |
147 | 0 | void set_is_auto_increment(bool is_auto_increment) { _is_auto_increment = is_auto_increment; } |
148 | 0 | void set_is_on_update_current_timestamp(bool is_on_update_current_timestamp) { |
149 | 0 | _is_on_update_current_timestamp = is_on_update_current_timestamp; |
150 | 0 | } |
151 | | void set_path_info(const PathInData& path); |
152 | 813k | FieldAggregationMethod aggregation() const { return _aggregation; } |
153 | | AggregateFunctionPtr get_aggregate_function_union(DataTypePtr type, |
154 | | int current_be_exec_version) const; |
155 | | AggregateFunctionPtr get_aggregate_function(std::string suffix, |
156 | | int current_be_exec_version) const; |
157 | | AggregateFunctionPtr get_aggregate_function(std::string suffix, int current_be_exec_version, |
158 | | DataTypePtr runtime_type) const; |
159 | 95.5M | int precision() const { return _precision; } |
160 | 112M | int frac() const { return _frac; } |
161 | 652 | inline bool visible() const { return _visible; } |
162 | | bool has_char_type() const; |
163 | | |
164 | 158k | void set_aggregation_method(FieldAggregationMethod agg) { |
165 | 158k | _aggregation = agg; |
166 | 158k | _aggregation_name = get_string_by_aggregation_type(agg); |
167 | 158k | } |
168 | | |
169 | | /** |
170 | | * Add a sub column. |
171 | | */ |
172 | | void add_sub_column(TabletColumn& sub_column); |
173 | | |
174 | 2.44M | uint32_t get_subtype_count() const { return _sub_column_count; } |
175 | 1.81M | MOCK_FUNCTION const TabletColumn& get_sub_column(uint64_t i) const { return *_sub_columns[i]; } |
176 | 183k | const std::vector<TabletColumnPtr>& get_sub_columns() const { return _sub_columns; } |
177 | | |
178 | | friend bool operator==(const TabletColumn& a, const TabletColumn& b); |
179 | | friend bool operator!=(const TabletColumn& a, const TabletColumn& b); |
180 | | |
181 | | static std::string get_string_by_field_type(FieldType type); |
182 | | static std::string get_string_by_aggregation_type(FieldAggregationMethod aggregation_type); |
183 | | static FieldType get_field_type_by_string(const std::string& str); |
184 | | static FieldAggregationMethod get_aggregation_type_by_string(const std::string& str); |
185 | | static uint32_t get_field_length_by_type(TPrimitiveType::type type, uint32_t string_length); |
186 | | bool is_row_store_column() const; |
187 | 770k | std::string get_aggregation_name() const { return _aggregation_name; } |
188 | 770k | bool get_result_is_nullable() const { return _result_is_nullable; } |
189 | 823k | int get_be_exec_version() const { return _be_exec_version; } |
190 | 59.2M | bool has_path_info() const { return _column_path != nullptr && !_column_path->empty(); } |
191 | 21.6M | const PathInDataPtr& path_info_ptr() const { return _column_path; } |
192 | | // If it is an extracted column from variant column |
193 | 195M | bool is_extracted_column() const { |
194 | 195M | return _column_path != nullptr && !_column_path->empty() && _parent_col_unique_id >= 0; |
195 | 195M | }; |
196 | 19.6M | std::string suffix_path() const { |
197 | 19.6M | return is_extracted_column() ? _column_path->get_path() : ""; |
198 | 19.6M | } |
199 | 10.6k | bool is_nested_subcolumn() const { |
200 | 10.6k | return _column_path != nullptr && _column_path->has_nested_part(); |
201 | 10.6k | } |
202 | 497k | int32_t parent_unique_id() const { return _parent_col_unique_id; } |
203 | 163k | void set_parent_unique_id(int32_t col_unique_id) { _parent_col_unique_id = col_unique_id; } |
204 | 123k | void set_is_bf_column(bool is_bf_column) { _is_bf_column = is_bf_column; } |
205 | | std::shared_ptr<const IDataType> get_vec_type() const; |
206 | | |
207 | 102k | Status check_valid() const { |
208 | 102k | if (type() != FieldType::OLAP_FIELD_TYPE_ARRAY && |
209 | 102k | type() != FieldType::OLAP_FIELD_TYPE_STRUCT && |
210 | 102k | type() != FieldType::OLAP_FIELD_TYPE_MAP) { |
211 | 98.4k | return Status::OK(); |
212 | 98.4k | } |
213 | 3.89k | if (is_bf_column()) { |
214 | 0 | return Status::NotSupported("Do not support bloom filter index, type={}", |
215 | 0 | get_string_by_field_type(type())); |
216 | 0 | } |
217 | 3.89k | return Status::OK(); |
218 | 3.89k | } |
219 | | |
220 | 2.97k | void set_precision(int precision) { |
221 | 2.97k | _precision = precision; |
222 | 2.97k | _is_decimal = true; |
223 | 2.97k | } |
224 | | |
225 | 3.24k | void set_frac(int frac) { _frac = frac; } |
226 | | |
227 | 0 | const VariantParams& variant_params() const { return _variant; } |
228 | 0 | VariantParams* mutable_variant_params() { return &_variant; } |
229 | | |
230 | 157k | int32_t variant_max_subcolumns_count() const { return _variant.max_subcolumns_count; } |
231 | | |
232 | 7.72k | void set_variant_max_subcolumns_count(int32_t variant_max_subcolumns_count) { |
233 | 7.72k | _variant.max_subcolumns_count = variant_max_subcolumns_count; |
234 | 7.72k | } |
235 | | |
236 | 143k | bool variant_is_v2() const { return _variant_is_v2; } |
237 | 7.83k | void set_variant_is_v2(bool is_v2) { _variant_is_v2 = is_v2; } |
238 | | |
239 | 24.1k | PatternTypePB pattern_type() const { return _pattern_type; } |
240 | | |
241 | 6.49k | bool variant_enable_typed_paths_to_sparse() const { |
242 | 6.49k | return _variant.enable_typed_paths_to_sparse; |
243 | 6.49k | } |
244 | | |
245 | 41.4k | int32_t variant_max_sparse_column_statistics_size() const { |
246 | 41.4k | return _variant.max_sparse_column_statistics_size; |
247 | 41.4k | } |
248 | | |
249 | 3.19k | int32_t variant_sparse_hash_shard_count() const { return _variant.sparse_hash_shard_count; } |
250 | | |
251 | 184k | bool variant_enable_doc_mode() const { return _variant.enable_doc_mode; } |
252 | | |
253 | 2.49k | int64_t variant_doc_materialization_min_rows() const { |
254 | 2.49k | return _variant.doc_materialization_min_rows; |
255 | 2.49k | } |
256 | | |
257 | 2.54k | int32_t variant_doc_hash_shard_count() const { return _variant.doc_hash_shard_count; } |
258 | | |
259 | | void set_variant_doc_materialization_min_rows(int64_t variant_doc_materialization_min_rows) { |
260 | | _variant.doc_materialization_min_rows = variant_doc_materialization_min_rows; |
261 | | } |
262 | | |
263 | | void set_variant_doc_hash_shard_count(int32_t variant_doc_hash_shard_count) { |
264 | | _variant.doc_hash_shard_count = variant_doc_hash_shard_count; |
265 | | } |
266 | | |
267 | | void set_variant_max_sparse_column_statistics_size( |
268 | | int32_t variant_max_sparse_column_statistics_size) { |
269 | | _variant.max_sparse_column_statistics_size = variant_max_sparse_column_statistics_size; |
270 | | } |
271 | | |
272 | | void set_variant_sparse_hash_shard_count(int32_t variant_sparse_hash_shard_count) { |
273 | | _variant.sparse_hash_shard_count = variant_sparse_hash_shard_count; |
274 | | } |
275 | | |
276 | 8.54k | void set_variant_enable_doc_mode(bool variant_enable_doc_mode) { |
277 | 8.54k | _variant.enable_doc_mode = variant_enable_doc_mode; |
278 | 8.54k | } |
279 | | |
280 | | void set_variant_enable_typed_paths_to_sparse(bool variant_enable_typed_paths_to_sparse) { |
281 | | _variant.enable_typed_paths_to_sparse = variant_enable_typed_paths_to_sparse; |
282 | | } |
283 | | |
284 | 196k | bool variant_enable_nested_group() const { return _variant.enable_nested_group; } |
285 | | |
286 | | void set_variant_enable_nested_group(bool val) { _variant.enable_nested_group = val; } |
287 | | |
288 | 3.23k | bool is_decimal() const { return _is_decimal; } |
289 | | |
290 | | private: |
291 | | int32_t _unique_id = -1; |
292 | | std::string _col_name; |
293 | | std::string _col_name_lower_case; |
294 | | // the field _type will change from TPrimitiveType |
295 | | // to string by 'EnumToString(TPrimitiveType, tcolumn.column_type.type, data_type);' (reference: TabletMeta::init_column_from_tcolumn) |
296 | | // to FieldType by 'TabletColumn::get_field_type_by_string' (reference: TabletColumn::init_from_pb). |
297 | | // And the _type in columnPB is string and it changed from FieldType by 'get_string_by_field_type' (reference: TabletColumn::to_schema_pb). |
298 | | FieldType _type; |
299 | | bool _is_key = false; |
300 | | FieldAggregationMethod _aggregation; |
301 | | std::string _aggregation_name; |
302 | | bool _is_nullable = false; |
303 | | bool _is_auto_increment = false; |
304 | | bool _is_on_update_current_timestamp {false}; |
305 | | |
306 | | bool _has_default_value = false; |
307 | | std::string _default_value; |
308 | | bool _has_default_value_expr = false; |
309 | | std::string _default_value_expr; |
310 | | |
311 | | bool _is_decimal = false; |
312 | | int32_t _precision = -1; |
313 | | int32_t _frac = -1; |
314 | | |
315 | | int32_t _length = -1; |
316 | | int32_t _index_length = -1; |
317 | | |
318 | | bool _is_bf_column = false; |
319 | | |
320 | | bool _visible = true; |
321 | | |
322 | | std::vector<TabletColumnPtr> _sub_columns; |
323 | | uint32_t _sub_column_count = 0; |
324 | | |
325 | | bool _result_is_nullable = false; |
326 | | int _be_exec_version = -1; |
327 | | |
328 | | // The extracted sub-columns from "variant" contain the following information: |
329 | | int32_t _parent_col_unique_id = -1; // "variant" -> col_unique_id |
330 | | PathInDataPtr _column_path; // the path of the sub-columns themselves |
331 | | PatternTypePB _pattern_type = PatternTypePB::MATCH_NAME_GLOB; |
332 | | |
333 | | VariantParams _variant; |
334 | | // TODO: Remove this transient read-schema marker after legacy ColumnVariant destinations are |
335 | | // deleted and Variant readers always produce ColumnVariantV2. It only selects the in-memory |
336 | | // compute destination and must never be serialized into tablet or segment metadata. |
337 | | bool _variant_is_v2 = false; |
338 | | }; |
339 | | |
340 | | bool operator==(const TabletColumn& a, const TabletColumn& b); |
341 | | bool operator!=(const TabletColumn& a, const TabletColumn& b); |
342 | | |
343 | | class TabletIndex : public MetadataAdder<TabletIndex> { |
344 | | public: |
345 | 1.23M | TabletIndex() = default; |
346 | | void init_from_thrift(const TOlapTableIndex& index, const TabletSchema& tablet_schema); |
347 | | void init_from_thrift(const TOlapTableIndex& index, const std::vector<int32_t>& column_uids); |
348 | | void init_from_pb(const TabletIndexPB& index); |
349 | | void to_schema_pb(TabletIndexPB* index) const; |
350 | | |
351 | 478k | int64_t index_id() const { return _index_id; } |
352 | | const std::string& index_name() const { return _index_name; } |
353 | 1.58M | MOCK_FUNCTION IndexType index_type() const { return _index_type; } |
354 | 1.39M | const std::vector<int32_t>& col_unique_ids() const { return _col_unique_ids; } |
355 | 866k | MOCK_FUNCTION const std::map<std::string, std::string>& properties() const { |
356 | 866k | return _properties; |
357 | 866k | } |
358 | 3.37k | int32_t get_gram_size() const { |
359 | 3.37k | if (_properties.contains("gram_size")) { |
360 | 3.37k | return std::stoi(_properties.at("gram_size")); |
361 | 3.37k | } |
362 | | |
363 | 18.4E | return 0; |
364 | 3.37k | } |
365 | 3.37k | int32_t get_gram_bf_size() const { |
366 | 3.37k | if (_properties.contains("bf_size")) { |
367 | 3.37k | return std::stoi(_properties.at("bf_size")); |
368 | 3.37k | } |
369 | | |
370 | 18.4E | return 0; |
371 | 3.37k | } |
372 | | |
373 | 1.51M | const std::string& get_index_suffix() const { return _escaped_index_suffix_path; } |
374 | | |
375 | | void set_escaped_escaped_index_suffix_path(const std::string& name); |
376 | | |
377 | 41.6k | bool is_inverted_index() const { return _index_type == IndexType::INVERTED; } |
378 | | |
379 | 26 | bool is_ann_index() const { return _index_type == IndexType::ANN; } |
380 | | |
381 | 2.28k | void remove_parser_and_analyzer() { |
382 | 2.28k | _properties.erase(INVERTED_INDEX_PARSER_KEY); |
383 | 2.28k | _properties.erase(INVERTED_INDEX_PARSER_KEY_ALIAS); |
384 | 2.28k | _properties.erase(INVERTED_INDEX_ANALYZER_NAME_KEY); |
385 | 2.28k | _properties.erase(INVERTED_INDEX_NORMALIZER_NAME_KEY); |
386 | 2.28k | } |
387 | | |
388 | 1.29M | std::string field_pattern() const { |
389 | 1.29M | if (_properties.contains("field_pattern")) { |
390 | 6.74k | return _properties.at("field_pattern"); |
391 | 6.74k | } |
392 | 1.28M | return ""; |
393 | 1.29M | } |
394 | | |
395 | 398 | bool is_same_except_id(const TabletIndex* other) const { |
396 | 398 | return _escaped_index_suffix_path == other->_escaped_index_suffix_path && |
397 | 398 | _index_name == other->_index_name && _index_type == other->_index_type && |
398 | 398 | _col_unique_ids == other->_col_unique_ids && _properties == other->_properties; |
399 | 398 | } |
400 | | |
401 | | private: |
402 | | int64_t _index_id = -1; |
403 | | // Identify the different index with the same _index_id |
404 | | std::string _escaped_index_suffix_path; |
405 | | std::string _index_name; |
406 | | IndexType _index_type; |
407 | | std::vector<int32_t> _col_unique_ids; |
408 | | std::map<std::string, std::string> _properties; |
409 | | }; |
410 | | |
411 | | using TabletIndexPtr = std::shared_ptr<TabletIndex>; |
412 | | using TabletIndexes = std::vector<std::shared_ptr<TabletIndex>>; |
413 | | using PathSet = phmap::flat_hash_set<std::string>; |
414 | | |
415 | | class TabletSchema : public MetadataAdder<TabletSchema> { |
416 | | public: |
417 | | enum class ColumnType { NORMAL = 0, DROPPED = 1, VARIANT = 2 }; |
418 | | // TODO(yingchun): better to make constructor as private to avoid |
419 | | // manually init members incorrectly, and define a new function like |
420 | | // void create_from_pb(const TabletSchemaPB& schema, TabletSchema* tablet_schema). |
421 | | TabletSchema(); |
422 | | ~TabletSchema() override; |
423 | | |
424 | | // Init from pb |
425 | | // ignore_extracted_columns: ignore the extracted columns from variant column |
426 | | // reuse_cached_column: reuse the cached column in the schema if they are the same, to reduce memory usage |
427 | | void init_from_pb(const TabletSchemaPB& schema, bool ignore_extracted_columns = false, |
428 | | bool reuse_cached_column = false); |
429 | | // Notice: Use deterministic way to serialize protobuf, |
430 | | // since serialize Map in protobuf may could lead to un-deterministic by default |
431 | | template <class PbType> |
432 | 3.40M | static std::string deterministic_string_serialize(const PbType& pb) { |
433 | 3.40M | std::string output; |
434 | 3.40M | google::protobuf::io::StringOutputStream string_output_stream(&output); |
435 | 3.40M | google::protobuf::io::CodedOutputStream output_stream(&string_output_stream); |
436 | 3.40M | output_stream.SetSerializationDeterministic(true); |
437 | 3.40M | pb.SerializeToCodedStream(&output_stream); |
438 | 3.40M | return output; |
439 | 3.40M | } _ZN5doris12TabletSchema30deterministic_string_serializeINS_8ColumnPBEEENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKT_ Line | Count | Source | 432 | 1.13M | static std::string deterministic_string_serialize(const PbType& pb) { | 433 | 1.13M | std::string output; | 434 | 1.13M | google::protobuf::io::StringOutputStream string_output_stream(&output); | 435 | 1.13M | google::protobuf::io::CodedOutputStream output_stream(&string_output_stream); | 436 | 1.13M | output_stream.SetSerializationDeterministic(true); | 437 | 1.13M | pb.SerializeToCodedStream(&output_stream); | 438 | 1.13M | return output; | 439 | 1.13M | } |
_ZN5doris12TabletSchema30deterministic_string_serializeINS_13TabletIndexPBEEENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKT_ Line | Count | Source | 432 | 90.2k | static std::string deterministic_string_serialize(const PbType& pb) { | 433 | 90.2k | std::string output; | 434 | 90.2k | google::protobuf::io::StringOutputStream string_output_stream(&output); | 435 | 90.2k | google::protobuf::io::CodedOutputStream output_stream(&string_output_stream); | 436 | 90.2k | output_stream.SetSerializationDeterministic(true); | 437 | 90.2k | pb.SerializeToCodedStream(&output_stream); | 438 | 90.2k | return output; | 439 | 90.2k | } |
_ZN5doris12TabletSchema30deterministic_string_serializeINS_14TabletSchemaPBEEENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKT_ Line | Count | Source | 432 | 2.00M | static std::string deterministic_string_serialize(const PbType& pb) { | 433 | 2.00M | std::string output; | 434 | 2.00M | google::protobuf::io::StringOutputStream string_output_stream(&output); | 435 | 2.00M | google::protobuf::io::CodedOutputStream output_stream(&string_output_stream); | 436 | 2.00M | output_stream.SetSerializationDeterministic(true); | 437 | 2.00M | pb.SerializeToCodedStream(&output_stream); | 438 | 2.00M | return output; | 439 | 2.00M | } |
_ZN5doris12TabletSchema30deterministic_string_serializeINS_21POlapTableIndexSchemaEEENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKT_ Line | Count | Source | 432 | 170k | static std::string deterministic_string_serialize(const PbType& pb) { | 433 | 170k | std::string output; | 434 | 170k | google::protobuf::io::StringOutputStream string_output_stream(&output); | 435 | 170k | google::protobuf::io::CodedOutputStream output_stream(&string_output_stream); | 436 | 170k | output_stream.SetSerializationDeterministic(true); | 437 | 170k | pb.SerializeToCodedStream(&output_stream); | 438 | 170k | return output; | 439 | 170k | } |
|
440 | | void to_schema_pb(TabletSchemaPB* tablet_meta_pb) const; |
441 | | void append_column(TabletColumn column, ColumnType col_type = ColumnType::NORMAL); |
442 | | void append_index(TabletIndex&& index); |
443 | | void remove_index(int64_t index_id); |
444 | | void clear_index(); |
445 | | // Must make sure the row column is always the last column |
446 | | void add_row_column(); |
447 | | void copy_from(const TabletSchema& tablet_schema); |
448 | | // lightweight copy, take care of lifecycle of TabletColumn |
449 | | void shawdow_copy_without_columns(const TabletSchema& tablet_schema); |
450 | | void update_index_info_from(const TabletSchema& tablet_schema); |
451 | | std::string to_key() const; |
452 | | // get_metadata_size is only the memory of the TabletSchema itself, not include child objects. |
453 | 102k | int64_t mem_size() const { return get_metadata_size(); } |
454 | | size_t row_size() const; |
455 | | int32_t field_index(const std::string& field_name) const; |
456 | | int32_t field_index(const PathInData& path) const; |
457 | | int32_t field_index(int32_t col_unique_id) const; |
458 | | const TabletColumn& column(size_t ordinal) const; |
459 | | Result<const TabletColumn*> column(const std::string& field_name) const; |
460 | | Status have_column(const std::string& field_name) const; |
461 | | bool exist_column(const std::string& field_name) const; |
462 | | bool has_column_unique_id(int32_t col_unique_id) const; |
463 | | const TabletColumn& column_by_uid(int32_t col_unique_id) const; |
464 | | TabletColumn& mutable_column_by_uid(int32_t col_unique_id); |
465 | | TabletColumn& mutable_column(size_t ordinal); |
466 | | void replace_column(size_t pos, TabletColumn new_col); |
467 | | const std::vector<TabletColumnPtr>& columns() const; |
468 | 27.6M | size_t num_columns() const { return _num_columns; } |
469 | 0 | size_t num_visible_columns() const { |
470 | 0 | return std::count_if(_cols.begin(), _cols.end(), |
471 | 0 | [](const TabletColumnPtr& column) { return column->visible(); }); |
472 | 0 | } |
473 | | size_t num_visible_value_columns() const { |
474 | | return std::count_if(_cols.begin(), _cols.end(), [](const TabletColumnPtr& column) { |
475 | | return column->visible() && !column->is_key(); |
476 | | }); |
477 | | } |
478 | | // num_key_columns: Total number of sort key columns in the table, determined by the key columns |
479 | | // specified in DUPLICATE KEY/UNIQUE KEY/AGGREGATE KEY when creating the table, used for complete data sorting |
480 | | // Example: CREATE TABLE t(a INT, b DATE, c VARCHAR) DUPLICATE KEY(a, b, c) |
481 | | // Then num_key_columns = 3 (columns a, b, c are all sort keys) |
482 | 30.9M | size_t num_key_columns() const { return _num_key_columns; } |
483 | 14.7M | const std::vector<uint32_t>& cluster_key_uids() const { return _cluster_key_uids; } |
484 | 0 | size_t num_null_columns() const { return _num_null_columns; } |
485 | | // num_short_key_columns: Number of columns used to build the Short Key Index, automatically calculated by FE |
486 | | // Limited by max column count (default 3) and max bytes (default 36 bytes). Types like float/double/STRING/JSONB |
487 | | // cannot be used as short keys. VARCHAR can only be the last short key column. Optimizes index size and query performance. |
488 | | // Example: CREATE TABLE t(a INT, b DATE, c VARCHAR) DUPLICATE KEY(a, b, c) |
489 | | // Then num_short_key_columns = 3 (a, b, c all meet criteria, c as VARCHAR is the last short key) |
490 | | // Example: CREATE TABLE t(a INT, b DOUBLE, c DATE) DUPLICATE KEY(a, b, c) |
491 | | // Then num_short_key_columns = 1 (b is DOUBLE type which cannot be short key, stops at b) |
492 | | // short key's size is limited to 36 bytes, because it will be loaded to memory during segment loaded. |
493 | 1.04M | size_t num_short_key_columns() const { return _num_short_key_columns; } |
494 | 58.0k | size_t num_rows_per_row_block() const { return _num_rows_per_row_block; } |
495 | 1.86M | size_t num_variant_columns() const { return _num_variant_columns; }; |
496 | 0 | size_t num_virtual_columns() const { return _num_virtual_columns; } |
497 | 49.0M | KeysType keys_type() const { return _keys_type; } |
498 | 1.45M | SortType sort_type() const { return _sort_type; } |
499 | 58.1k | size_t sort_col_num() const { return _sort_col_num; } |
500 | 187k | CompressKind compress_kind() const { return _compress_kind; } |
501 | 57.8k | size_t next_column_unique_id() const { return _next_column_unique_id; } |
502 | 2.12k | bool has_bf_fpp() const { return _has_bf_fpp; } |
503 | 5.88k | double bloom_filter_fpp() const { return _bf_fpp; } |
504 | 20.9M | bool is_in_memory() const { return _is_in_memory; } |
505 | 1 | void set_is_in_memory(bool is_in_memory) { _is_in_memory = is_in_memory; } |
506 | 18 | void set_disable_auto_compaction(bool disable_auto_compaction) { |
507 | 18 | _disable_auto_compaction = disable_auto_compaction; |
508 | 18 | } |
509 | 1.22G | bool disable_auto_compaction() const { return _disable_auto_compaction; } |
510 | | // Deprecated legacy switch for flatten-nested variant behavior. |
511 | | // It is distinct from variant_enable_nested_group. |
512 | 0 | void set_deprecated_variant_flatten_nested(bool flatten_nested) { |
513 | 0 | _deprecated_enable_variant_flatten_nested = flatten_nested; |
514 | 0 | } |
515 | 62.5k | bool deprecated_variant_flatten_nested() const { |
516 | 62.5k | return _deprecated_enable_variant_flatten_nested; |
517 | 62.5k | } |
518 | | // indicate if full row store column(all the columns encodes as row) exists |
519 | 4.68k | bool has_row_store_for_all_columns() const { |
520 | 4.68k | return _store_row_column && row_columns_uids().empty(); |
521 | 4.68k | } |
522 | 0 | void set_skip_write_index_on_load(bool skip) { _skip_write_index_on_load = skip; } |
523 | 639k | bool skip_write_index_on_load() const { return _skip_write_index_on_load; } |
524 | 935k | int32_t delete_sign_idx() const { return _delete_sign_idx; } |
525 | 23.4M | bool has_sequence_col() const { return _sequence_col_idx != -1; } |
526 | 171k | int32_t sequence_col_idx() const { return _sequence_col_idx; } |
527 | 0 | void set_version_col_idx(int32_t version_col_idx) { _version_col_idx = version_col_idx; } |
528 | 9.06k | int32_t version_col_idx() const { return _version_col_idx; } |
529 | 573 | bool has_skip_bitmap_col() const { return _skip_bitmap_col_idx != -1; } |
530 | 11.4k | int32_t skip_bitmap_col_idx() const { return _skip_bitmap_col_idx; } |
531 | 298k | bool is_tso_enabled() const { return _commit_tso_col_idx != -1 || _binlog_tso_col_idx != -1; } |
532 | 4 | int32_t commit_tso_col_idx() const { return _commit_tso_col_idx; } |
533 | 2.92M | int32_t binlog_tso_col_idx() const { return _binlog_tso_col_idx; } |
534 | 73 | int32_t binlog_lsn_col_idx() const { return _binlog_lsn_col_idx; } |
535 | 74 | int32_t binlog_op_col_idx() const { return _binlog_op_col_idx; } |
536 | 13.8k | segment_v2::CompressionTypePB compression_type() const { return _compression_type; } |
537 | 0 | void set_row_store_page_size(long page_size) { _row_store_page_size = page_size; } |
538 | 59.5k | long row_store_page_size() const { return _row_store_page_size; } |
539 | | void set_storage_page_size(long storage_page_size) { _storage_page_size = storage_page_size; } |
540 | 728k | long storage_page_size() const { return _storage_page_size; } |
541 | 0 | void set_storage_dict_page_size(long storage_dict_page_size) { |
542 | 0 | _storage_dict_page_size = storage_dict_page_size; |
543 | 0 | } |
544 | 727k | long storage_dict_page_size() const { return _storage_dict_page_size; } |
545 | 886k | bool has_global_row_id() const { |
546 | 13.8M | for (auto [col_name, _] : _field_name_to_index) { |
547 | 13.8M | if (col_name.start_with(StringRef(BeConsts::GLOBAL_ROWID_COL.data(), |
548 | 13.8M | BeConsts::GLOBAL_ROWID_COL.size()))) { |
549 | 8.26k | return true; |
550 | 8.26k | } |
551 | 13.8M | } |
552 | 877k | return false; |
553 | 886k | } |
554 | | |
555 | 11.7k | const std::vector<const TabletIndex*> inverted_indexes() const { |
556 | 11.7k | std::vector<const TabletIndex*> inverted_indexes; |
557 | 11.7k | for (const auto& index : _indexes) { |
558 | 6.51k | if (index->index_type() == IndexType::INVERTED) { |
559 | 5.74k | inverted_indexes.emplace_back(index.get()); |
560 | 5.74k | } |
561 | 6.51k | } |
562 | 11.7k | return inverted_indexes; |
563 | 11.7k | } |
564 | | // True when anything at all lives in this schema's inverted index FILE. |
565 | | // |
566 | | // Spelled out as `has_inverted_index() || has_ann_index()` at ~27 call sites |
567 | | // before this existed -- rowset writers, segment creation, segcompaction, |
568 | | // snapshot and migration, and most of the cloud paths. Every one of them is |
569 | | // asking the same question ("is there an index file to carry, warm, link or |
570 | | // rewrite?"), and each open-coded copy is a place a third index type would |
571 | | // have to be remembered. |
572 | 387k | bool has_inverted_or_ann_index() const { return has_inverted_index() || has_ann_index(); } |
573 | | |
574 | | // Both index types that live in the inverted index FILE, in schema order. |
575 | | // Every storage format stores them together: V1/V2/V3 as CLucene directories, |
576 | | // SNII as text metadata groups plus an ANN blob logical index. A rewrite that |
577 | | // enumerated only the inverted ones would seal a file missing every ANN index |
578 | | // while the schema still claimed them. |
579 | 25 | const std::vector<const TabletIndex*> inverted_and_ann_indexes() const { |
580 | 25 | std::vector<const TabletIndex*> indexes; |
581 | 31 | for (const auto& index : _indexes) { |
582 | 31 | if (index->index_type() == IndexType::INVERTED || |
583 | 31 | index->index_type() == IndexType::ANN) { |
584 | 31 | indexes.emplace_back(index.get()); |
585 | 31 | } |
586 | 31 | } |
587 | 25 | return indexes; |
588 | 25 | } |
589 | 449k | bool has_inverted_index() const { |
590 | 449k | for (const auto& index : _indexes) { |
591 | 46.4k | DBUG_EXECUTE_IF("tablet_schema::has_inverted_index", { |
592 | 46.4k | if (index->col_unique_ids().empty()) { |
593 | 46.4k | throw Exception(Status::InternalError("col unique ids cannot be empty")); |
594 | 46.4k | } |
595 | 46.4k | }); |
596 | | |
597 | 46.4k | if (index->index_type() == IndexType::INVERTED) { |
598 | | //if index_id == -1, ignore it. |
599 | 45.6k | if (!index->col_unique_ids().empty() && index->col_unique_ids()[0] >= 0) { |
600 | 45.6k | return true; |
601 | 45.6k | } |
602 | 45.6k | } |
603 | 46.4k | } |
604 | 403k | return false; |
605 | 449k | } |
606 | | |
607 | 346k | bool has_ann_index() const { |
608 | 346k | for (const auto& index : _indexes) { |
609 | 728 | if (index->index_type() == IndexType::ANN) { |
610 | 385 | if (!index->col_unique_ids().empty() && index->col_unique_ids()[0] >= 0) { |
611 | 384 | return true; |
612 | 384 | } |
613 | 384 | } |
614 | 728 | } |
615 | 345k | return false; |
616 | 346k | } |
617 | | |
618 | | bool has_inverted_index_with_index_id(int64_t index_id) const; |
619 | | |
620 | | std::vector<const TabletIndex*> inverted_indexs(const TabletColumn& col) const; |
621 | | |
622 | | std::vector<const TabletIndex*> inverted_indexs(int32_t col_unique_id, |
623 | | const std::string& suffix_path = "") const; |
624 | | const TabletIndex* ann_index(const TabletColumn& col) const; |
625 | | |
626 | | // Regardless of whether this column supports inverted index |
627 | | // TabletIndex information will be returned as long as it exists. |
628 | | const TabletIndex* ann_index(int32_t col_unique_id, const std::string& suffix_path = "") const; |
629 | | |
630 | | std::vector<TabletIndexPtr> inverted_index_by_field_pattern( |
631 | | int32_t col_unique_id, const std::string& field_pattern) const; |
632 | | |
633 | | bool has_ngram_bf_index(int32_t col_unique_id) const; |
634 | | const TabletIndex* get_ngram_bf_index(int32_t col_unique_id) const; |
635 | | const TabletIndex* get_index(int32_t col_unique_id, IndexType index_type, |
636 | | const std::string& suffix_path) const; |
637 | | void update_indexes_from_thrift(const std::vector<doris::TOlapTableIndex>& indexes); |
638 | | // If schema version is not set, it should be -1 |
639 | 1.70M | int32_t schema_version() const { return _schema_version; } |
640 | | void clear_columns(); |
641 | | Block create_block( |
642 | | const std::vector<uint32_t>& return_columns, |
643 | | const std::unordered_set<uint32_t>* tablet_columns_need_convert_null = nullptr) const; |
644 | | Block create_block() const; |
645 | 1.05M | void set_schema_version(int32_t version) { _schema_version = version; } |
646 | 1.36k | void set_auto_increment_column(const std::string& auto_increment_column) { |
647 | 1.36k | _auto_increment_column = auto_increment_column; |
648 | 1.36k | } |
649 | 2.45k | std::string auto_increment_column() const { return _auto_increment_column; } |
650 | | |
651 | 59.2k | void set_table_id(int64_t table_id) { _table_id = table_id; } |
652 | 935k | int64_t table_id() const { return _table_id; } |
653 | 59.3k | void set_db_id(int64_t db_id) { _db_id = db_id; } |
654 | 427 | int64_t db_id() const { return _db_id; } |
655 | | void build_current_tablet_schema(int64_t index_id, int32_t version, |
656 | | const OlapTableIndexSchema* index, |
657 | | const TabletSchema& out_tablet_schema); |
658 | | |
659 | | // Merge columns that not exit in current schema, these column is dropped in current schema |
660 | | // but they are useful in some cases. For example, |
661 | | // 1. origin schema is ColA, ColB |
662 | | // 2. insert values 1, 2 |
663 | | // 3. delete where ColB = 2 |
664 | | // 4. drop ColB |
665 | | // 5. insert values 3 |
666 | | // 6. add column ColB, although it is name ColB, but it is different with previous ColB, the new ColB we name could call ColB' |
667 | | // 7. insert value 4, 5 |
668 | | // Then the read schema should be ColA, ColB, ColB' because the delete predicate need ColB to remove related data. |
669 | | // Because they have same name, so that the dropped column should not be added to the map, only with unique id. |
670 | | void merge_dropped_columns(const TabletSchema& src_schema); |
671 | | |
672 | | bool is_dropped_column(const TabletColumn& col) const; |
673 | | |
674 | | // copy extracted columns from src_schema |
675 | | void copy_extracted_columns(const TabletSchema& src_schema); |
676 | | |
677 | | // only reserve extracted columns |
678 | | void reserve_extracted_columns(); |
679 | | |
680 | 4.04k | std::string get_all_field_names() const { |
681 | 4.04k | std::string str = "["; |
682 | 4.04k | for (auto p : _field_name_to_index) { |
683 | 4.04k | if (str.size() > 1) { |
684 | 0 | str += ", "; |
685 | 0 | } |
686 | 4.04k | str += p.first.to_string() + "(" + std::to_string(_cols[p.second]->unique_id()) + ")"; |
687 | 4.04k | } |
688 | 4.04k | str += "]"; |
689 | 4.04k | return str; |
690 | 4.04k | } |
691 | | |
692 | | // Dump [(name, type, is_nullable), ...] |
693 | 5 | std::string dump_structure() const { |
694 | 5 | std::string str = "["; |
695 | 28 | for (auto p : _cols) { |
696 | 28 | if (str.size() > 1) { |
697 | 23 | str += ", "; |
698 | 23 | } |
699 | 28 | str += "("; |
700 | 28 | str += p->name(); |
701 | 28 | str += ", "; |
702 | 28 | str += TabletColumn::get_string_by_field_type(p->type()); |
703 | 28 | str += ", "; |
704 | 28 | str += "is_nullable:"; |
705 | 28 | str += (p->is_nullable() ? "true" : "false"); |
706 | 28 | str += ")"; |
707 | 28 | } |
708 | 5 | str += "]"; |
709 | 5 | return str; |
710 | 5 | } |
711 | | |
712 | 1 | std::string dump_full_schema() const { |
713 | 1 | std::string str = "["; |
714 | 4 | for (auto p : _cols) { |
715 | 4 | if (str.size() > 1) { |
716 | 3 | str += ", "; |
717 | 3 | } |
718 | 4 | ColumnPB col_pb; |
719 | 4 | p->to_schema_pb(&col_pb); |
720 | 4 | str += "("; |
721 | 4 | str += col_pb.ShortDebugString(); |
722 | 4 | str += ")"; |
723 | 4 | } |
724 | 1 | str += "]"; |
725 | 1 | return str; |
726 | 1 | } |
727 | | |
728 | | Block create_block_by_cids(const std::vector<uint32_t>& cids) const; |
729 | | |
730 | | std::shared_ptr<TabletSchema> copy_without_variant_extracted_columns(); |
731 | 1.80M | InvertedIndexStorageFormatPB get_inverted_index_storage_format() const { |
732 | 1.80M | return _inverted_index_storage_format; |
733 | 1.80M | } |
734 | | |
735 | | void update_tablet_columns(const TabletSchema& tablet_schema, |
736 | | const std::vector<TColumn>& t_columns); |
737 | | |
738 | 15.8k | const std::vector<int32_t>& row_columns_uids() const { return _row_store_column_unique_ids; } |
739 | | |
740 | | int64_t get_metadata_size() const override; |
741 | | |
742 | | struct SubColumnInfo { |
743 | | TabletColumn column; |
744 | | TabletIndexes indexes; |
745 | | }; |
746 | | |
747 | | // all path in path_set_info are relative to the parent column |
748 | | struct PathsSetInfo { |
749 | | std::unordered_map<std::string, SubColumnInfo> typed_path_set; // typed columns |
750 | | std::unordered_map<std::string, TabletIndexes> subcolumn_indexes; // subcolumns indexes |
751 | | PathSet sub_path_set; // extracted columns |
752 | | PathSet sparse_path_set; // sparse columns |
753 | | |
754 | | // "Materialized regular path" means compaction chose to store this path as a dedicated |
755 | | // column in the schema, either typed or extracted, instead of re-emitting it dynamically. |
756 | 0 | bool contains_materialized_regular_path(const std::string& path) const { |
757 | 0 | return typed_path_set.contains(path) || sub_path_set.contains(path); |
758 | 0 | } |
759 | | }; |
760 | | |
761 | 10.2k | void set_path_set_info(std::unordered_map<int32_t, PathsSetInfo>&& path_set_info_map) { |
762 | 10.2k | _path_set_info_map = std::move(path_set_info_map); |
763 | 10.2k | } |
764 | | |
765 | 1.97k | const PathsSetInfo& path_set_info(int32_t unique_id) const { |
766 | 1.97k | return _path_set_info_map.at(unique_id); |
767 | 1.97k | } |
768 | | |
769 | 7 | const PathsSetInfo* try_path_set_info(int32_t unique_id) const { |
770 | 7 | auto it = _path_set_info_map.find(unique_id); |
771 | 7 | return it == _path_set_info_map.end() ? nullptr : &it->second; |
772 | 7 | } |
773 | | |
774 | | bool need_record_variant_extended_schema() const { return variant_max_subcolumns_count() == 0; } |
775 | | |
776 | | int32_t variant_max_subcolumns_count() const { |
777 | | for (const auto& col : _cols) { |
778 | | if (col->is_variant_type()) { |
779 | | return col->variant_max_subcolumns_count(); |
780 | | } |
781 | | } |
782 | | return 0; |
783 | | } |
784 | | const std::unordered_map<uint32_t, std::vector<uint32_t>>& seq_col_idx_to_value_cols_idx() |
785 | 76 | const { |
786 | 76 | return _seq_col_idx_to_value_cols_idx; |
787 | 76 | } |
788 | | |
789 | 3.40M | bool has_seq_map() const { return !_seq_col_idx_to_value_cols_idx.empty(); } |
790 | | |
791 | 39 | const std::unordered_map<uint32_t, uint32_t>& value_col_idx_to_seq_col_idx() const { |
792 | 39 | return _value_col_idx_to_seq_col_idx; |
793 | 39 | } |
794 | | |
795 | 54.4k | void add_pruned_columns_data_type(int32_t col_unique_id, DataTypePtr data_type) { |
796 | 54.4k | _pruned_columns_data_type[col_unique_id] = std::move(data_type); |
797 | 54.4k | } |
798 | | |
799 | 0 | void clear_pruned_columns_data_type() { _pruned_columns_data_type.clear(); } |
800 | | |
801 | 0 | bool has_pruned_columns() const { return !_pruned_columns_data_type.empty(); } |
802 | | |
803 | 737k | TabletStorageFormatPB storage_format() const { return _storage_format; } |
804 | 184 | void set_storage_format(TabletStorageFormatPB v) { _storage_format = v; } |
805 | | |
806 | | private: |
807 | | friend bool operator==(const TabletSchema& a, const TabletSchema& b); |
808 | | friend bool operator!=(const TabletSchema& a, const TabletSchema& b); |
809 | | TabletSchema(const TabletSchema&) = default; |
810 | | |
811 | | KeysType _keys_type = DUP_KEYS; |
812 | | SortType _sort_type = SortType::LEXICAL; |
813 | | size_t _sort_col_num = 0; |
814 | | std::vector<TabletColumnPtr> _cols; |
815 | | |
816 | | std::vector<TabletIndexPtr> _indexes; |
817 | | std::unordered_map<StringRef, int32_t, StringRefHash> _field_name_to_index; |
818 | | std::unordered_map<int32_t, int32_t> _field_uniqueid_to_index; |
819 | | std::unordered_map<PathInDataRef, int32_t, PathInDataRef::Hash> _field_path_to_index; |
820 | | |
821 | | // index_type/col_unique_id/suffix -> idxs in _indexes |
822 | | using IndexKey = std::tuple<IndexType, int32_t, std::string>; |
823 | | struct IndexKeyHash { |
824 | 21.8M | size_t operator()(const IndexKey& t) const { |
825 | 21.8M | uint32_t seed = 0; |
826 | 21.8M | seed = doris::HashUtil::hash((const char*)&std::get<0>(t), sizeof(std::get<0>(t)), |
827 | 21.8M | seed); |
828 | 21.8M | seed = doris::HashUtil::hash((const char*)&std::get<1>(t), sizeof(std::get<1>(t)), |
829 | 21.8M | seed); |
830 | 21.8M | seed = doris::HashUtil::hash((const char*)std::get<2>(t).c_str(), |
831 | 21.8M | static_cast<uint32_t>(std::get<2>(t).size()), seed); |
832 | 21.8M | return seed; |
833 | 21.8M | } |
834 | | }; |
835 | | std::unordered_map<IndexKey, std::vector<size_t>, IndexKeyHash> _col_id_suffix_to_index; |
836 | | |
837 | | int32_t _num_columns = 0; |
838 | | size_t _num_variant_columns = 0; |
839 | | size_t _num_virtual_columns = 0; |
840 | | size_t _num_key_columns = 0; |
841 | | std::vector<uint32_t> _cluster_key_uids; |
842 | | size_t _num_null_columns = 0; |
843 | | size_t _num_short_key_columns = 0; |
844 | | size_t _num_rows_per_row_block = 0; |
845 | | CompressKind _compress_kind = COMPRESS_NONE; |
846 | | segment_v2::CompressionTypePB _compression_type = segment_v2::CompressionTypePB::LZ4F; |
847 | | long _row_store_page_size = segment_v2::ROW_STORE_PAGE_SIZE_DEFAULT_VALUE; |
848 | | long _storage_page_size = segment_v2::STORAGE_PAGE_SIZE_DEFAULT_VALUE; |
849 | | long _storage_dict_page_size = segment_v2::STORAGE_DICT_PAGE_SIZE_DEFAULT_VALUE; |
850 | | size_t _next_column_unique_id = 0; |
851 | | std::string _auto_increment_column; |
852 | | |
853 | | bool _has_bf_fpp = false; |
854 | | double _bf_fpp = 0; |
855 | | bool _is_in_memory = false; |
856 | | int32_t _delete_sign_idx = -1; |
857 | | int32_t _sequence_col_idx = -1; |
858 | | int32_t _version_col_idx = -1; |
859 | | int32_t _skip_bitmap_col_idx = -1; |
860 | | int32_t _commit_tso_col_idx = -1; |
861 | | int32_t _binlog_tso_col_idx = -1; |
862 | | int32_t _binlog_lsn_col_idx = -1; |
863 | | int32_t _binlog_op_col_idx = -1; |
864 | | int32_t _schema_version = -1; |
865 | | int64_t _table_id = -1; |
866 | | int64_t _db_id = -1; |
867 | | bool _disable_auto_compaction = false; |
868 | | bool _store_row_column = false; |
869 | | bool _skip_write_index_on_load = false; |
870 | | InvertedIndexStorageFormatPB _inverted_index_storage_format = InvertedIndexStorageFormatPB::V1; |
871 | | |
872 | | // Contains column ids of which columns should be encoded into row store. |
873 | | // ATTN: For compability reason empty cids means all columns of tablet schema are encoded to row column |
874 | | std::vector<int32_t> _row_store_column_unique_ids; |
875 | | bool _deprecated_enable_variant_flatten_nested = false; |
876 | | |
877 | | std::map<size_t, int32_t> _vir_col_idx_to_unique_id; |
878 | | std::map<int32_t, DataTypePtr> _pruned_columns_data_type; |
879 | | |
880 | | // value: extracted path set and sparse path set |
881 | | std::unordered_map<int32_t, PathsSetInfo> _path_set_info_map; |
882 | | |
883 | | // key: field_pattern |
884 | | // value: indexes |
885 | | using PatternToIndex = std::unordered_map<std::string, std::vector<TabletIndexPtr>>; |
886 | | std::unordered_map<int32_t, PatternToIndex> _index_by_unique_id_with_pattern; |
887 | | |
888 | | // Default behavior for new segments: use external ColumnMeta region + CMO table if true |
889 | | // Persisted tablet storage format. Authoritative source for "is this tablet V3?" |
890 | | // decisions in the segment write paths. Old PBs without this field are upgraded in |
891 | | // init_from_pb() by deriving V3 from any of the three legacy V3-flavor flags. |
892 | | TabletStorageFormatPB _storage_format {TabletStorageFormatPB::TABLET_STORAGE_FORMAT_V2}; |
893 | | // Sequence column unique id mapping to value columns unique id |
894 | | std::unordered_map<uint32_t, std::vector<uint32_t>> _seq_col_uid_to_value_cols_uid; |
895 | | // Value column unique id mapping to sequence column unique id(also map sequence column it self) |
896 | | std::unordered_map<uint32_t, uint32_t> _value_col_uid_to_seq_col_uid; |
897 | | // Sequence column index mapping to value column index |
898 | | std::unordered_map<uint32_t, std::vector<uint32_t>> _seq_col_idx_to_value_cols_idx; |
899 | | // Value column index mapping to sequence column index(also map sequence column it self) |
900 | | std::unordered_map<uint32_t, uint32_t> _value_col_idx_to_seq_col_idx; |
901 | | }; |
902 | | |
903 | | bool operator==(const TabletSchema& a, const TabletSchema& b); |
904 | | bool operator!=(const TabletSchema& a, const TabletSchema& b); |
905 | | |
906 | | using TabletSchemaSPtr = std::shared_ptr<TabletSchema>; |
907 | | |
908 | | } // namespace doris |