/Users/deen/code/yugabyte-db/src/yb/docdb/primitive_value.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) YugaByte, Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
4 | | // in compliance with the License. You may obtain a copy of the License at |
5 | | // |
6 | | // http://www.apache.org/licenses/LICENSE-2.0 |
7 | | // |
8 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
9 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
10 | | // or implied. See the License for the specific language governing permissions and limitations |
11 | | // under the License. |
12 | | // |
13 | | |
14 | | #include "yb/docdb/primitive_value.h" |
15 | | |
16 | | #include <string> |
17 | | |
18 | | #include <glog/logging.h> |
19 | | |
20 | | #include "yb/common/ql_type.h" |
21 | | #include "yb/common/ql_value.h" |
22 | | |
23 | | #include "yb/docdb/doc_key.h" |
24 | | #include "yb/docdb/doc_kv_util.h" |
25 | | #include "yb/docdb/intent.h" |
26 | | #include "yb/docdb/value_type.h" |
27 | | |
28 | | #include "yb/gutil/macros.h" |
29 | | #include "yb/gutil/stringprintf.h" |
30 | | #include "yb/gutil/strings/substitute.h" |
31 | | |
32 | | #include "yb/util/bytes_formatter.h" |
33 | | #include "yb/util/compare_util.h" |
34 | | #include "yb/util/decimal.h" |
35 | | #include "yb/util/fast_varint.h" |
36 | | #include "yb/util/net/inetaddress.h" |
37 | | #include "yb/util/result.h" |
38 | | #include "yb/util/status_format.h" |
39 | | #include "yb/util/status_log.h" |
40 | | |
41 | | using std::string; |
42 | | using strings::Substitute; |
43 | | using yb::QLValuePB; |
44 | | using yb::common::Jsonb; |
45 | | using yb::util::Decimal; |
46 | | using yb::util::VarInt; |
47 | | using yb::FormatBytesAsStr; |
48 | | using yb::util::CompareUsingLessThan; |
49 | | using yb::util::FastDecodeSignedVarIntUnsafe; |
50 | | using yb::util::kInt32SignBitFlipMask; |
51 | | using yb::util::AppendBigEndianUInt64; |
52 | | using yb::util::AppendBigEndianUInt32; |
53 | | using yb::util::DecodeInt64FromKey; |
54 | | using yb::util::DecodeFloatFromKey; |
55 | | using yb::util::DecodeDoubleFromKey; |
56 | | |
57 | | // We're listing all non-primitive value types at the end of switch statement instead of using a |
58 | | // default clause so that we can ensure that we're handling all possible primitive value types |
59 | | // at compile time. |
60 | | #define IGNORE_NON_PRIMITIVE_VALUE_TYPES_IN_SWITCH \ |
61 | 0 | case ValueType::kArray: FALLTHROUGH_INTENDED; \ |
62 | 0 | case ValueType::kBitSet: FALLTHROUGH_INTENDED; \ |
63 | 0 | case ValueType::kExternalIntents: FALLTHROUGH_INTENDED; \ |
64 | 0 | case ValueType::kGreaterThanIntentType: FALLTHROUGH_INTENDED; \ |
65 | 0 | case ValueType::kGroupEnd: FALLTHROUGH_INTENDED; \ |
66 | 0 | case ValueType::kGroupEndDescending: FALLTHROUGH_INTENDED; \ |
67 | 0 | case ValueType::kInvalid: FALLTHROUGH_INTENDED; \ |
68 | 0 | case ValueType::kJsonb: FALLTHROUGH_INTENDED; \ |
69 | 0 | case ValueType::kMergeFlags: FALLTHROUGH_INTENDED; \ |
70 | 0 | case ValueType::kObject: FALLTHROUGH_INTENDED; \ |
71 | 0 | case ValueType::kObsoleteIntentPrefix: FALLTHROUGH_INTENDED; \ |
72 | 0 | case ValueType::kRedisList: FALLTHROUGH_INTENDED; \ |
73 | 0 | case ValueType::kRedisSet: FALLTHROUGH_INTENDED; \ |
74 | 0 | case ValueType::kRedisSortedSet: FALLTHROUGH_INTENDED; \ |
75 | 0 | case ValueType::kRedisTS: FALLTHROUGH_INTENDED; \ |
76 | 0 | case ValueType::kRowLock: FALLTHROUGH_INTENDED; \ |
77 | 0 | case ValueType::kTombstone: FALLTHROUGH_INTENDED; \ |
78 | 0 | case ValueType::kTtl: FALLTHROUGH_INTENDED; \ |
79 | 0 | case ValueType::kUserTimestamp: \ |
80 | 0 | break |
81 | | |
82 | | namespace yb { |
83 | | namespace docdb { |
84 | | |
85 | | namespace { |
86 | | |
87 | | template <class T> |
88 | 0 | string RealToString(T val) { |
89 | 0 | string s = std::to_string(val); |
90 | | // Remove trailing zeros. |
91 | 0 | auto dot_pos = s.find('.'); |
92 | 0 | if (dot_pos != string::npos) { |
93 | 0 | s.erase(std::max(dot_pos + 1, s.find_last_not_of('0')) + 1, string::npos); |
94 | 0 | } |
95 | 0 | if (s == "0.0" && val != 0.0) { |
96 | | // Use the exponential notation for small numbers that would otherwise look like a zero. |
97 | 0 | return StringPrintf("%E", val); |
98 | 0 | } |
99 | 0 | return s; |
100 | 0 | } Unexecuted instantiation: primitive_value.cc:_ZN2yb5docdb12_GLOBAL__N_112RealToStringIfEENSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEET_ Unexecuted instantiation: primitive_value.cc:_ZN2yb5docdb12_GLOBAL__N_112RealToStringIdEENSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEET_ |
101 | | |
102 | | } // anonymous namespace |
103 | | |
104 | | const PrimitiveValue PrimitiveValue::kInvalid = PrimitiveValue(ValueType::kInvalid); |
105 | | const PrimitiveValue PrimitiveValue::kTombstone = PrimitiveValue(ValueType::kTombstone); |
106 | | const PrimitiveValue PrimitiveValue::kObject = PrimitiveValue(ValueType::kObject); |
107 | | const PrimitiveValue PrimitiveValue::kLivenessColumn = PrimitiveValue::SystemColumnId( |
108 | | SystemColumnIds::kLivenessColumn); |
109 | | |
110 | 540k | string PrimitiveValue::ToString(AutoDecodeKeys auto_decode_keys) const { |
111 | 540k | switch (type_) { |
112 | 0 | case ValueType::kNullHigh: FALLTHROUGH_INTENDED; |
113 | 90.0k | case ValueType::kNullLow: |
114 | 90.0k | return "null"; |
115 | 0 | case ValueType::kGinNull: |
116 | 0 | switch (gin_null_val_) { |
117 | | // case 0, gin:norm-key, should not exist since the actual data would be used instead. |
118 | 0 | case 1: |
119 | 0 | return "GinNullKey"; |
120 | 0 | case 2: |
121 | 0 | return "GinEmptyItem"; |
122 | 0 | case 3: |
123 | 0 | return "GinNullItem"; |
124 | | // case -1, gin:empty-query, should not exist since that's internal to postgres. |
125 | 0 | default: |
126 | 0 | LOG(FATAL) << "Unexpected gin null category: " << gin_null_val_; |
127 | 0 | } |
128 | 0 | case ValueType::kCounter: |
129 | 0 | return "counter"; |
130 | 0 | case ValueType::kSSForward: |
131 | 0 | return "SSforward"; |
132 | 0 | case ValueType::kSSReverse: |
133 | 0 | return "SSreverse"; |
134 | 0 | case ValueType::kFalse: FALLTHROUGH_INTENDED; |
135 | 0 | case ValueType::kFalseDescending: |
136 | 0 | return "false"; |
137 | 0 | case ValueType::kTrue: FALLTHROUGH_INTENDED; |
138 | 0 | case ValueType::kTrueDescending: |
139 | 0 | return "true"; |
140 | 0 | case ValueType::kInvalid: |
141 | 0 | return "invalid"; |
142 | 0 | case ValueType::kCollStringDescending: FALLTHROUGH_INTENDED; |
143 | 0 | case ValueType::kCollString: FALLTHROUGH_INTENDED; |
144 | 24 | case ValueType::kStringDescending: FALLTHROUGH_INTENDED; |
145 | 90.0k | case ValueType::kString: |
146 | 90.0k | if (auto_decode_keys) { |
147 | | // This is useful when logging write batches for secondary indexes. |
148 | 0 | SubDocKey sub_doc_key; |
149 | 0 | Status decode_status = sub_doc_key.FullyDecodeFrom(str_val_, HybridTimeRequired::kFalse); |
150 | 0 | if (decode_status.ok()) { |
151 | | // This gives us "EncodedSubDocKey(...)". |
152 | 0 | return Format("Encoded$0", sub_doc_key); |
153 | 0 | } |
154 | 90.0k | } |
155 | 90.0k | return FormatBytesAsStr(str_val_); |
156 | 6 | case ValueType::kInt32Descending: FALLTHROUGH_INTENDED; |
157 | 180k | case ValueType::kInt32: |
158 | 180k | return std::to_string(int32_val_); |
159 | 0 | case ValueType::kUInt32: |
160 | 0 | case ValueType::kUInt32Descending: |
161 | 0 | return std::to_string(uint32_val_); |
162 | 0 | case ValueType::kUInt64: FALLTHROUGH_INTENDED; |
163 | 0 | case ValueType::kUInt64Descending: |
164 | 0 | return std::to_string(uint64_val_); |
165 | 0 | case ValueType::kInt64Descending: FALLTHROUGH_INTENDED; |
166 | 0 | case ValueType::kInt64: |
167 | 0 | return std::to_string(int64_val_); |
168 | 0 | case ValueType::kFloatDescending: FALLTHROUGH_INTENDED; |
169 | 0 | case ValueType::kFloat: |
170 | 0 | return RealToString(float_val_); |
171 | 0 | case ValueType::kFrozenDescending: FALLTHROUGH_INTENDED; |
172 | 0 | case ValueType::kFrozen: { |
173 | 0 | std::stringstream ss; |
174 | 0 | bool first = true; |
175 | 0 | ss << "<"; |
176 | 0 | for (const auto& pv : *frozen_val_) { |
177 | 0 | if (first) { |
178 | 0 | first = false; |
179 | 0 | } else { |
180 | 0 | ss << ","; |
181 | 0 | } |
182 | 0 | ss << pv.ToString(); |
183 | 0 | } |
184 | 0 | ss << ">"; |
185 | 0 | return ss.str(); |
186 | 0 | } |
187 | 0 | case ValueType::kDoubleDescending: FALLTHROUGH_INTENDED; |
188 | 0 | case ValueType::kDouble: |
189 | 0 | return RealToString(double_val_); |
190 | 0 | case ValueType::kDecimalDescending: FALLTHROUGH_INTENDED; |
191 | 0 | case ValueType::kDecimal: { |
192 | 0 | util::Decimal decimal; |
193 | 0 | auto status = decimal.DecodeFromComparable(decimal_val_); |
194 | 0 | if (!status.ok()) { |
195 | 0 | LOG(ERROR) << "Unable to decode decimal"; |
196 | 0 | return ""; |
197 | 0 | } |
198 | 0 | return decimal.ToString(); |
199 | 0 | } |
200 | 0 | case ValueType::kVarIntDescending: FALLTHROUGH_INTENDED; |
201 | 0 | case ValueType::kVarInt: { |
202 | 0 | util::VarInt varint; |
203 | 0 | auto status = varint.DecodeFromComparable(varint_val_); |
204 | 0 | if (!status.ok()) { |
205 | 0 | LOG(ERROR) << "Unable to decode varint: " << status.message().ToString(); |
206 | 0 | return ""; |
207 | 0 | } |
208 | 0 | return varint.ToString(); |
209 | 0 | } |
210 | 0 | case ValueType::kTimestampDescending: FALLTHROUGH_INTENDED; |
211 | 0 | case ValueType::kTimestamp: |
212 | 0 | return timestamp_val_.ToString(); |
213 | 0 | case ValueType::kInetaddressDescending: FALLTHROUGH_INTENDED; |
214 | 0 | case ValueType::kInetaddress: |
215 | 0 | return inetaddress_val_->ToString(); |
216 | 0 | case ValueType::kJsonb: |
217 | 0 | return FormatBytesAsStr(json_val_); |
218 | 0 | case ValueType::kUuidDescending: FALLTHROUGH_INTENDED; |
219 | 0 | case ValueType::kUuid: |
220 | 0 | return uuid_val_.ToString(); |
221 | 0 | case ValueType::kArrayIndex: |
222 | 0 | return Substitute("ArrayIndex($0)", int64_val_); |
223 | 0 | case ValueType::kHybridTime: |
224 | 0 | return hybrid_time_val_.ToString(); |
225 | 0 | case ValueType::kUInt16Hash: |
226 | 0 | return Substitute("UInt16Hash($0)", uint16_val_); |
227 | 90.0k | case ValueType::kColumnId: |
228 | 90.0k | return Format("ColumnId($0)", column_id_val_); |
229 | 90.0k | case ValueType::kSystemColumnId: |
230 | 90.0k | return Format("SystemColumnId($0)", column_id_val_); |
231 | 0 | case ValueType::kObject: |
232 | 0 | return "{}"; |
233 | 0 | case ValueType::kRedisSet: |
234 | 0 | return "()"; |
235 | 0 | case ValueType::kRedisTS: |
236 | 0 | return "<>"; |
237 | 0 | case ValueType::kRedisSortedSet: |
238 | 0 | return "(->)"; |
239 | 0 | case ValueType::kTombstone: |
240 | 0 | return "DEL"; |
241 | 0 | case ValueType::kRedisList: FALLTHROUGH_INTENDED; |
242 | 0 | case ValueType::kArray: |
243 | 0 | return "[]"; |
244 | 0 | case ValueType::kTableId: |
245 | 0 | return Format("TableId($0)", uuid_val_.ToString()); |
246 | 0 | case ValueType::kPgTableOid: |
247 | 0 | return Format("PgTableOid($0)", uint32_val_); |
248 | 0 | case ValueType::kTransactionApplyState: FALLTHROUGH_INTENDED; |
249 | 0 | case ValueType::kExternalTransactionId: FALLTHROUGH_INTENDED; |
250 | 0 | case ValueType::kTransactionId: |
251 | 0 | return Substitute("TransactionId($0)", uuid_val_.ToString()); |
252 | 0 | case ValueType::kSubTransactionId: |
253 | 0 | return Substitute("SubTransactionId($0)", uint32_val_); |
254 | 0 | case ValueType::kWriteId: |
255 | 0 | return Format("WriteId($0)", int32_val_); |
256 | 0 | case ValueType::kIntentTypeSet: |
257 | 0 | return Format("Intents($0)", IntentTypeSet(uint16_val_)); |
258 | 0 | case ValueType::kObsoleteIntentTypeSet: |
259 | 0 | return Format("ObsoleteIntents($0)", uint16_val_); |
260 | 0 | case ValueType::kObsoleteIntentType: |
261 | 0 | return Format("Intent($0)", uint16_val_); |
262 | 0 | case ValueType::kMergeFlags: FALLTHROUGH_INTENDED; |
263 | 0 | case ValueType::kRowLock: FALLTHROUGH_INTENDED; |
264 | 0 | case ValueType::kBitSet: FALLTHROUGH_INTENDED; |
265 | 0 | case ValueType::kGroupEnd: FALLTHROUGH_INTENDED; |
266 | 0 | case ValueType::kGroupEndDescending: FALLTHROUGH_INTENDED; |
267 | 0 | case ValueType::kTtl: FALLTHROUGH_INTENDED; |
268 | 0 | case ValueType::kUserTimestamp: FALLTHROUGH_INTENDED; |
269 | 0 | case ValueType::kObsoleteIntentPrefix: FALLTHROUGH_INTENDED; |
270 | 0 | case ValueType::kExternalIntents: FALLTHROUGH_INTENDED; |
271 | 0 | case ValueType::kGreaterThanIntentType: |
272 | 0 | break; |
273 | 48 | case ValueType::kLowest: |
274 | 48 | return "-Inf"; |
275 | 0 | case ValueType::kHighest: |
276 | 0 | return "+Inf"; |
277 | 0 | case ValueType::kMaxByte: |
278 | 0 | return "0xff"; |
279 | 0 | } |
280 | 0 | FATAL_INVALID_ENUM_VALUE(ValueType, type_); |
281 | 0 | } |
282 | | |
283 | 359M | void PrimitiveValue::AppendToKey(KeyBytes* key_bytes) const { |
284 | 359M | key_bytes->AppendValueType(type_); |
285 | 359M | switch (type_) { |
286 | 310k | case ValueType::kLowest: return; |
287 | 18.2M | case ValueType::kHighest: return; |
288 | 0 | case ValueType::kMaxByte: return; |
289 | 91 | case ValueType::kNullHigh: return; |
290 | 609k | case ValueType::kNullLow: return; |
291 | 21.0k | case ValueType::kCounter: return; |
292 | 10.5k | case ValueType::kSSForward: return; |
293 | 21.0k | case ValueType::kSSReverse: return; |
294 | 5.75k | case ValueType::kFalse: return; |
295 | 445 | case ValueType::kTrue: return; |
296 | 12 | case ValueType::kFalseDescending: return; |
297 | 12 | case ValueType::kTrueDescending: return; |
298 | | |
299 | 0 | case ValueType::kCollString: FALLTHROUGH_INTENDED; |
300 | 13.4M | case ValueType::kString: |
301 | 13.4M | key_bytes->AppendString(str_val_); |
302 | 13.4M | return; |
303 | |
|
304 | 0 | case ValueType::kCollStringDescending: FALLTHROUGH_INTENDED; |
305 | 76.9k | case ValueType::kStringDescending: |
306 | 76.9k | key_bytes->AppendDescendingString(str_val_); |
307 | 76.9k | return; |
308 | |
|
309 | 1.49M | case ValueType::kInt64: |
310 | 1.49M | key_bytes->AppendInt64(int64_val_); |
311 | 1.49M | return; |
312 | |
|
313 | 41.0M | case ValueType::kInt32: FALLTHROUGH_INTENDED; |
314 | 41.0M | case ValueType::kWriteId: |
315 | 41.0M | key_bytes->AppendInt32(int32_val_); |
316 | 41.0M | return; |
317 | | |
318 | 0 | case ValueType::kPgTableOid: FALLTHROUGH_INTENDED; |
319 | 0 | case ValueType::kSubTransactionId: FALLTHROUGH_INTENDED; |
320 | 4.20M | case ValueType::kUInt32: |
321 | 4.20M | key_bytes->AppendUInt32(uint32_val_); |
322 | 4.20M | return; |
323 | |
|
324 | 114 | case ValueType::kUInt32Descending: |
325 | 114 | key_bytes->AppendDescendingUInt32(uint32_val_); |
326 | 114 | return; |
327 | |
|
328 | 5.38k | case ValueType::kInt32Descending: |
329 | 5.38k | key_bytes->AppendDescendingInt32(int32_val_); |
330 | 5.38k | return; |
331 | |
|
332 | 27.1k | case ValueType::kInt64Descending: |
333 | 27.1k | key_bytes->AppendDescendingInt64(int64_val_); |
334 | 27.1k | return; |
335 | |
|
336 | 0 | case ValueType::kUInt64: |
337 | 0 | key_bytes->AppendUInt64(uint64_val_); |
338 | 0 | return; |
339 | |
|
340 | 0 | case ValueType::kUInt64Descending: |
341 | 0 | key_bytes->AppendDescendingUInt64(uint64_val_); |
342 | 0 | return; |
343 | |
|
344 | 524k | case ValueType::kDouble: |
345 | 524k | key_bytes->AppendDouble(double_val_); |
346 | 524k | return; |
347 | |
|
348 | 420 | case ValueType::kDoubleDescending: |
349 | 420 | key_bytes->AppendDescendingDouble(double_val_); |
350 | 420 | return; |
351 | |
|
352 | 253 | case ValueType::kFloat: |
353 | 253 | key_bytes->AppendFloat(float_val_); |
354 | 253 | return; |
355 | |
|
356 | 420 | case ValueType::kFloatDescending: |
357 | 420 | key_bytes->AppendDescendingFloat(float_val_); |
358 | 420 | return; |
359 | |
|
360 | 86 | case ValueType::kFrozenDescending: FALLTHROUGH_INTENDED; |
361 | 590 | case ValueType::kFrozen: { |
362 | 1.22k | for (const auto& pv : *frozen_val_) { |
363 | 1.22k | pv.AppendToKey(key_bytes); |
364 | 1.22k | } |
365 | 590 | if (type_ == ValueType::kFrozenDescending) { |
366 | 86 | key_bytes->AppendValueType(ValueType::kGroupEndDescending); |
367 | 504 | } else { |
368 | 504 | key_bytes->AppendValueType(ValueType::kGroupEnd); |
369 | 504 | } |
370 | 590 | return; |
371 | 86 | } |
372 | | |
373 | 24.0k | case ValueType::kDecimal: |
374 | 24.0k | key_bytes->AppendDecimal(decimal_val_); |
375 | 24.0k | return; |
376 | | |
377 | 124 | case ValueType::kDecimalDescending: |
378 | 124 | key_bytes->AppendDecimalDescending(decimal_val_); |
379 | 124 | return; |
380 | | |
381 | 23.0k | case ValueType::kVarInt: |
382 | 23.0k | key_bytes->AppendVarInt(varint_val_); |
383 | 23.0k | return; |
384 | | |
385 | 122 | case ValueType::kVarIntDescending: |
386 | 122 | key_bytes->AppendVarIntDescending(varint_val_); |
387 | 122 | return; |
388 | | |
389 | 1.49k | case ValueType::kTimestamp: |
390 | 1.49k | key_bytes->AppendInt64(timestamp_val_.ToInt64()); |
391 | 1.49k | return; |
392 | | |
393 | 671k | case ValueType::kTimestampDescending: |
394 | 671k | key_bytes->AppendDescendingInt64(timestamp_val_.ToInt64()); |
395 | 671k | return; |
396 | | |
397 | 98 | case ValueType::kInetaddress: { |
398 | 98 | std::string bytes; |
399 | 98 | CHECK_OK(inetaddress_val_->ToBytes(&bytes)); |
400 | 98 | key_bytes->AppendString(bytes); |
401 | 98 | return; |
402 | 86 | } |
403 | | |
404 | 304 | case ValueType::kInetaddressDescending: { |
405 | 304 | std::string bytes; |
406 | 304 | CHECK_OK(inetaddress_val_->ToBytes(&bytes)); |
407 | 304 | key_bytes->AppendDescendingString(bytes); |
408 | 304 | return; |
409 | 86 | } |
410 | | |
411 | 0 | case ValueType::kTransactionApplyState: FALLTHROUGH_INTENDED; |
412 | 0 | case ValueType::kExternalTransactionId: FALLTHROUGH_INTENDED; |
413 | 0 | case ValueType::kTransactionId: FALLTHROUGH_INTENDED; |
414 | 0 | case ValueType::kTableId: FALLTHROUGH_INTENDED; |
415 | 436 | case ValueType::kUuid: { |
416 | 436 | std::string bytes; |
417 | 436 | uuid_val_.EncodeToComparable(&bytes); |
418 | 436 | key_bytes->AppendString(bytes); |
419 | 436 | return; |
420 | 0 | } |
421 | |
|
422 | 1.28k | case ValueType::kUuidDescending: { |
423 | 1.28k | std::string bytes; |
424 | 1.28k | uuid_val_.EncodeToComparable(&bytes); |
425 | 1.28k | key_bytes->AppendDescendingString(bytes); |
426 | 1.28k | return; |
427 | 0 | } |
428 | |
|
429 | 143 | case ValueType::kArrayIndex: |
430 | 143 | key_bytes->AppendInt64(int64_val_); |
431 | 143 | return; |
432 | |
|
433 | 0 | case ValueType::kHybridTime: |
434 | 0 | hybrid_time_val_.AppendEncodedInDocDbFormat(key_bytes->mutable_data()); |
435 | 0 | return; |
436 | |
|
437 | 0 | case ValueType::kUInt16Hash: |
438 | 0 | key_bytes->AppendUInt16(uint16_val_); |
439 | 0 | return; |
440 | |
|
441 | 239M | case ValueType::kColumnId: FALLTHROUGH_INTENDED; |
442 | 279M | case ValueType::kSystemColumnId: |
443 | 279M | key_bytes->AppendColumnId(column_id_val_); |
444 | 279M | return; |
445 | | |
446 | 0 | case ValueType::kObsoleteIntentType: |
447 | 0 | key_bytes->AppendIntentTypeSet(ObsoleteIntentTypeToSet(uint16_val_)); |
448 | 0 | return; |
449 | | |
450 | 0 | case ValueType::kObsoleteIntentTypeSet: |
451 | 0 | key_bytes->AppendIntentTypeSet(ObsoleteIntentTypeSetToNew(uint16_val_)); |
452 | 0 | return; |
453 | | |
454 | 0 | case ValueType::kIntentTypeSet: |
455 | 0 | key_bytes->AppendIntentTypeSet(IntentTypeSet(uint16_val_)); |
456 | 0 | return; |
457 | | |
458 | 351 | case ValueType::kGinNull: |
459 | 351 | key_bytes->AppendUint8(gin_null_val_); |
460 | 351 | return; |
461 | | |
462 | 0 | IGNORE_NON_PRIMITIVE_VALUE_TYPES_IN_SWITCH; |
463 | 359M | } |
464 | 0 | FATAL_INVALID_ENUM_VALUE(ValueType, type_); |
465 | 0 | } |
466 | | |
467 | 23.3M | string PrimitiveValue::ToValue() const { |
468 | 23.3M | string result; |
469 | 23.3M | result.push_back(static_cast<char>(type_)); |
470 | 23.3M | switch (type_) { |
471 | 0 | case ValueType::kNullHigh: FALLTHROUGH_INTENDED; |
472 | 5.82M | case ValueType::kNullLow: FALLTHROUGH_INTENDED; |
473 | 5.82M | case ValueType::kCounter: FALLTHROUGH_INTENDED; |
474 | 5.82M | case ValueType::kSSForward: FALLTHROUGH_INTENDED; |
475 | 5.82M | case ValueType::kSSReverse: FALLTHROUGH_INTENDED; |
476 | 6.44M | case ValueType::kFalse: FALLTHROUGH_INTENDED; |
477 | 6.79M | case ValueType::kTrue: FALLTHROUGH_INTENDED; |
478 | 6.79M | case ValueType::kFalseDescending: FALLTHROUGH_INTENDED; |
479 | 6.79M | case ValueType::kTrueDescending: FALLTHROUGH_INTENDED; |
480 | 8.19M | case ValueType::kTombstone: FALLTHROUGH_INTENDED; |
481 | 8.19M | case ValueType::kObject: FALLTHROUGH_INTENDED; |
482 | 8.19M | case ValueType::kArray: FALLTHROUGH_INTENDED; |
483 | 8.19M | case ValueType::kRedisTS: FALLTHROUGH_INTENDED; |
484 | 8.19M | case ValueType::kRedisList: FALLTHROUGH_INTENDED; |
485 | 8.20M | case ValueType::kRedisSortedSet: FALLTHROUGH_INTENDED; |
486 | 8.20M | case ValueType::kRedisSet: return result; |
487 | | |
488 | 0 | case ValueType::kCollStringDescending: FALLTHROUGH_INTENDED; |
489 | 0 | case ValueType::kCollString: |
490 | 0 | LOG(DFATAL) << "collation encoded string found for docdb value"; |
491 | 0 | FALLTHROUGH_INTENDED; |
492 | 0 | case ValueType::kStringDescending: FALLTHROUGH_INTENDED; |
493 | 5.75M | case ValueType::kString: |
494 | | // No zero encoding necessary when storing the string in a value. |
495 | 5.75M | result.append(str_val_); |
496 | 5.75M | return result; |
497 | |
|
498 | 0 | case ValueType::kInt32Descending: FALLTHROUGH_INTENDED; |
499 | 7.08M | case ValueType::kInt32: FALLTHROUGH_INTENDED; |
500 | 7.08M | case ValueType::kWriteId: |
501 | 7.08M | AppendBigEndianUInt32(int32_val_, &result); |
502 | 7.08M | return result; |
503 | | |
504 | 0 | case ValueType::kPgTableOid: FALLTHROUGH_INTENDED; |
505 | 0 | case ValueType::kSubTransactionId: FALLTHROUGH_INTENDED; |
506 | 0 | case ValueType::kUInt32Descending: FALLTHROUGH_INTENDED; |
507 | 1.99M | case ValueType::kUInt32: |
508 | 1.99M | AppendBigEndianUInt32(uint32_val_, &result); |
509 | 1.99M | return result; |
510 | |
|
511 | 0 | case ValueType::kUInt64Descending: FALLTHROUGH_INTENDED; |
512 | 0 | case ValueType::kUInt64: |
513 | 0 | AppendBigEndianUInt64(uint64_val_, &result); |
514 | 0 | return result; |
515 | |
|
516 | 0 | case ValueType::kInt64Descending: FALLTHROUGH_INTENDED; |
517 | 199k | case ValueType::kInt64: |
518 | 199k | AppendBigEndianUInt64(int64_val_, &result); |
519 | 199k | return result; |
520 | |
|
521 | 0 | case ValueType::kArrayIndex: |
522 | 0 | LOG(FATAL) << "Array index cannot be stored in a value"; |
523 | 0 | return result; |
524 | |
|
525 | 0 | case ValueType::kDoubleDescending: FALLTHROUGH_INTENDED; |
526 | 11.1k | case ValueType::kDouble: |
527 | 11.1k | static_assert(sizeof(double) == sizeof(uint64_t), |
528 | 11.1k | "Expected double to be the same size as uint64_t"); |
529 | | // TODO: make sure this is a safe and reasonable representation for doubles. |
530 | 11.1k | AppendBigEndianUInt64(int64_val_, &result); |
531 | 11.1k | return result; |
532 | |
|
533 | 0 | case ValueType::kFloatDescending: FALLTHROUGH_INTENDED; |
534 | 136k | case ValueType::kFloat: |
535 | 136k | static_assert(sizeof(float) == sizeof(uint32_t), |
536 | 136k | "Expected float to be the same size as uint32_t"); |
537 | | // TODO: make sure this is a safe and reasonable representation for floats. |
538 | 136k | AppendBigEndianUInt32(int32_val_, &result); |
539 | 136k | return result; |
540 | |
|
541 | 0 | case ValueType::kFrozenDescending: FALLTHROUGH_INTENDED; |
542 | 61 | case ValueType::kFrozen: { |
543 | 61 | KeyBytes key(result); |
544 | 123 | for (const auto &pv : *frozen_val_) { |
545 | 123 | pv.AppendToKey(&key); |
546 | 123 | } |
547 | | |
548 | | // Still need the end marker for values in case of nested frozen collections. |
549 | 61 | if (type_ == ValueType::kFrozenDescending) { |
550 | 0 | key.AppendValueType(ValueType::kGroupEndDescending); |
551 | 61 | } else { |
552 | 61 | key.AppendValueType(ValueType::kGroupEnd); |
553 | 61 | } |
554 | 61 | return key.ToStringBuffer(); |
555 | 0 | } |
556 | |
|
557 | 0 | case ValueType::kDecimalDescending: FALLTHROUGH_INTENDED; |
558 | 435 | case ValueType::kDecimal: |
559 | 435 | result.append(decimal_val_); |
560 | 435 | return result; |
561 | |
|
562 | 0 | case ValueType::kVarIntDescending: FALLTHROUGH_INTENDED; |
563 | 234 | case ValueType::kVarInt: |
564 | 234 | result.append(varint_val_); |
565 | 234 | return result; |
566 | |
|
567 | 0 | case ValueType::kTimestampDescending: FALLTHROUGH_INTENDED; |
568 | 459 | case ValueType::kTimestamp: |
569 | 459 | AppendBigEndianUInt64(timestamp_val_.ToInt64(), &result); |
570 | 459 | return result; |
571 | |
|
572 | 0 | case ValueType::kInetaddressDescending: FALLTHROUGH_INTENDED; |
573 | 9 | case ValueType::kInetaddress: { |
574 | 9 | std::string bytes; |
575 | 9 | CHECK_OK(inetaddress_val_->ToBytes(&bytes)) |
576 | 9 | result.append(bytes); |
577 | 9 | return result; |
578 | 0 | } |
579 | |
|
580 | 7.41k | case ValueType::kJsonb: { |
581 | | // Append the jsonb flags. |
582 | 7.41k | int64_t jsonb_flags = kCompleteJsonb; |
583 | 7.41k | AppendBigEndianUInt64(jsonb_flags, &result); |
584 | | |
585 | | // Append the jsonb serialized blob. |
586 | 7.41k | result.append(json_val_); |
587 | 7.41k | return result; |
588 | 0 | } |
589 | |
|
590 | 0 | case ValueType::kUuidDescending: FALLTHROUGH_INTENDED; |
591 | 0 | case ValueType::kTransactionApplyState: FALLTHROUGH_INTENDED; |
592 | 0 | case ValueType::kExternalTransactionId: FALLTHROUGH_INTENDED; |
593 | 0 | case ValueType::kTransactionId: FALLTHROUGH_INTENDED; |
594 | 0 | case ValueType::kTableId: FALLTHROUGH_INTENDED; |
595 | 42 | case ValueType::kUuid: { |
596 | 42 | std::string bytes; |
597 | 42 | uuid_val_.EncodeToComparable(&bytes); |
598 | 42 | result.append(bytes); |
599 | 42 | return result; |
600 | 0 | } |
601 | |
|
602 | 0 | case ValueType::kUInt16Hash: |
603 | | // Hashes are not allowed in a value. |
604 | 0 | break; |
605 | |
|
606 | 0 | case ValueType::kGinNull: |
607 | 0 | result.push_back(static_cast<char>(gin_null_val_)); |
608 | 0 | return result; |
609 | |
|
610 | 0 | case ValueType::kIntentTypeSet: FALLTHROUGH_INTENDED; |
611 | 0 | case ValueType::kObsoleteIntentTypeSet: FALLTHROUGH_INTENDED; |
612 | 0 | case ValueType::kObsoleteIntentType: FALLTHROUGH_INTENDED; |
613 | 0 | case ValueType::kMergeFlags: FALLTHROUGH_INTENDED; |
614 | 0 | case ValueType::kRowLock: FALLTHROUGH_INTENDED; |
615 | 0 | case ValueType::kBitSet: FALLTHROUGH_INTENDED; |
616 | 0 | case ValueType::kGroupEnd: FALLTHROUGH_INTENDED; |
617 | 0 | case ValueType::kGroupEndDescending: FALLTHROUGH_INTENDED; |
618 | 0 | case ValueType::kObsoleteIntentPrefix: FALLTHROUGH_INTENDED; |
619 | 0 | case ValueType::kGreaterThanIntentType: FALLTHROUGH_INTENDED; |
620 | 0 | case ValueType::kTtl: FALLTHROUGH_INTENDED; |
621 | 0 | case ValueType::kUserTimestamp: FALLTHROUGH_INTENDED; |
622 | 0 | case ValueType::kColumnId: FALLTHROUGH_INTENDED; |
623 | 0 | case ValueType::kSystemColumnId: FALLTHROUGH_INTENDED; |
624 | 0 | case ValueType::kHybridTime: FALLTHROUGH_INTENDED; |
625 | 0 | case ValueType::kExternalIntents: FALLTHROUGH_INTENDED; |
626 | 0 | case ValueType::kInvalid: FALLTHROUGH_INTENDED; |
627 | 0 | case ValueType::kLowest: FALLTHROUGH_INTENDED; |
628 | 0 | case ValueType::kHighest: FALLTHROUGH_INTENDED; |
629 | 0 | case ValueType::kMaxByte: |
630 | 0 | break; |
631 | 0 | } |
632 | 0 | FATAL_INVALID_ENUM_VALUE(ValueType, type_); |
633 | 0 | } |
634 | | |
635 | 236M | Status PrimitiveValue::DecodeFromKey(rocksdb::Slice* slice) { |
636 | 236M | return DecodeKey(slice, this); |
637 | 236M | } |
638 | | |
639 | 843M | Status PrimitiveValue::DecodeKey(rocksdb::Slice* slice, PrimitiveValue* out) { |
640 | | // A copy for error reporting. |
641 | 843M | const rocksdb::Slice input_slice(*slice); |
642 | | |
643 | 843M | if (slice->empty()) { |
644 | 0 | return STATUS_SUBSTITUTE(Corruption, |
645 | 0 | "Cannot decode a primitive value in the key encoding format from an empty slice: $0", |
646 | 0 | ToShortDebugStr(input_slice)); |
647 | 0 | } |
648 | 843M | ValueType value_type = ConsumeValueType(slice); |
649 | 843M | ValueType dummy_type; |
650 | 428M | ValueType& type_ref = out ? out->type_ : dummy_type; |
651 | | |
652 | 843M | if (out) { |
653 | 428M | out->~PrimitiveValue(); |
654 | | // Ensure we are not leaving the object in an invalid state in case e.g. an exception is thrown |
655 | | // due to inability to allocate memory. |
656 | 428M | } |
657 | 843M | type_ref = ValueType::kNullLow; |
658 | | |
659 | 843M | switch (value_type) { |
660 | 269 | case ValueType::kNullHigh: FALLTHROUGH_INTENDED; |
661 | 5.82M | case ValueType::kNullLow: FALLTHROUGH_INTENDED; |
662 | 5.87M | case ValueType::kCounter: FALLTHROUGH_INTENDED; |
663 | 5.97M | case ValueType::kSSForward: FALLTHROUGH_INTENDED; |
664 | 6.06M | case ValueType::kSSReverse: FALLTHROUGH_INTENDED; |
665 | 6.11M | case ValueType::kFalse: FALLTHROUGH_INTENDED; |
666 | 6.11M | case ValueType::kTrue: FALLTHROUGH_INTENDED; |
667 | 6.11M | case ValueType::kFalseDescending: FALLTHROUGH_INTENDED; |
668 | 6.11M | case ValueType::kTrueDescending: FALLTHROUGH_INTENDED; |
669 | 6.11M | case ValueType::kHighest: FALLTHROUGH_INTENDED; |
670 | 6.11M | case ValueType::kLowest: |
671 | 6.11M | type_ref = value_type; |
672 | 6.11M | return Status::OK(); |
673 | | |
674 | 0 | case ValueType::kCollStringDescending: FALLTHROUGH_INTENDED; |
675 | 534k | case ValueType::kStringDescending: { |
676 | 534k | if (out) { |
677 | 326k | string result; |
678 | 326k | RETURN_NOT_OK(DecodeComplementZeroEncodedStr(slice, &result)); |
679 | 326k | new (&out->str_val_) string(std::move(result)); |
680 | 207k | } else { |
681 | 207k | RETURN_NOT_OK(DecodeComplementZeroEncodedStr(slice, nullptr)); |
682 | 207k | } |
683 | | // Only set type to string after string field initialization succeeds. |
684 | 534k | type_ref = value_type; |
685 | 534k | return Status::OK(); |
686 | 534k | } |
687 | | |
688 | 0 | case ValueType::kCollString: FALLTHROUGH_INTENDED; |
689 | 195M | case ValueType::kString: { |
690 | 195M | if (out) { |
691 | 86.7M | string result; |
692 | 86.7M | RETURN_NOT_OK(DecodeZeroEncodedStr(slice, &result)); |
693 | 86.7M | new (&out->str_val_) string(std::move(result)); |
694 | 108M | } else { |
695 | 108M | RETURN_NOT_OK(DecodeZeroEncodedStr(slice, nullptr)); |
696 | 108M | } |
697 | | // Only set type to string after string field initialization succeeds. |
698 | 195M | type_ref = value_type; |
699 | 195M | return Status::OK(); |
700 | 195M | } |
701 | | |
702 | 500 | case ValueType::kFrozenDescending: |
703 | 3.52k | case ValueType::kFrozen: { |
704 | 3.52k | ValueType end_marker_value_type = ValueType::kGroupEnd; |
705 | 3.52k | if (value_type == ValueType::kFrozenDescending) { |
706 | 500 | end_marker_value_type = ValueType::kGroupEndDescending; |
707 | 500 | } |
708 | | |
709 | 3.52k | if (out) { |
710 | 2.09k | out->frozen_val_ = new FrozenContainer(); |
711 | 6.35k | while (!slice->empty()) { |
712 | 6.35k | ValueType current_value_type = static_cast<ValueType>(*slice->data()); |
713 | 6.35k | if (current_value_type == end_marker_value_type) { |
714 | 2.09k | slice->consume_byte(); |
715 | 2.09k | type_ref = value_type; |
716 | 2.09k | return Status::OK(); |
717 | 4.25k | } else { |
718 | 4.25k | PrimitiveValue pv; |
719 | 4.25k | RETURN_NOT_OK(DecodeKey(slice, &pv)); |
720 | 4.25k | out->frozen_val_->push_back(pv); |
721 | 4.25k | } |
722 | 6.35k | } |
723 | 1.42k | } else { |
724 | 4.41k | while (!slice->empty()) { |
725 | 4.41k | ValueType current_value_type = static_cast<ValueType>(*slice->data()); |
726 | 4.41k | if (current_value_type == end_marker_value_type) { |
727 | 1.42k | slice->consume_byte(); |
728 | 1.42k | return Status::OK(); |
729 | 2.99k | } else { |
730 | 2.99k | RETURN_NOT_OK(DecodeKey(slice, nullptr)); |
731 | 2.99k | } |
732 | 4.41k | } |
733 | 1.42k | } |
734 | | |
735 | 0 | return STATUS(Corruption, "Reached end of slice looking for frozen group end marker"); |
736 | 3.52k | } |
737 | | |
738 | 1.36k | case ValueType::kDecimalDescending: FALLTHROUGH_INTENDED; |
739 | 166k | case ValueType::kDecimal: { |
740 | 166k | util::Decimal decimal; |
741 | 166k | Slice slice_temp(slice->data(), slice->size()); |
742 | 166k | size_t num_decoded_bytes = 0; |
743 | 166k | RETURN_NOT_OK(decimal.DecodeFromComparable(slice_temp, &num_decoded_bytes)); |
744 | 166k | if (value_type == ValueType::kDecimalDescending) { |
745 | | // When we encode a descending decimal, we do a bitwise negation of each byte, which changes |
746 | | // the sign of the number. This way we reverse the sorting order. decimal.Negate() restores |
747 | | // the original sign of the number. |
748 | 1.36k | decimal.Negate(); |
749 | 1.36k | } |
750 | 166k | if (out) { // TODO avoid using temp variable, when out is nullptr |
751 | 99.0k | new(&out->decimal_val_) string(decimal.EncodeToComparable()); |
752 | 99.0k | } |
753 | 166k | slice->remove_prefix(num_decoded_bytes); |
754 | 166k | type_ref = value_type; |
755 | 166k | return Status::OK(); |
756 | 166k | } |
757 | | |
758 | 1.34k | case ValueType::kVarIntDescending: FALLTHROUGH_INTENDED; |
759 | 154k | case ValueType::kVarInt: { |
760 | 154k | util::VarInt varint; |
761 | 154k | Slice slice_temp(slice->data(), slice->size()); |
762 | 154k | size_t num_decoded_bytes = 0; |
763 | 154k | RETURN_NOT_OK(varint.DecodeFromComparable(slice_temp, &num_decoded_bytes)); |
764 | 154k | if (value_type == ValueType::kVarIntDescending) { |
765 | 1.34k | varint.Negate(); |
766 | 1.34k | } |
767 | 154k | if (out) { // TODO avoid using temp variable, when out is nullptr |
768 | 89.3k | new(&out->varint_val_) string(varint.EncodeToComparable()); |
769 | 89.3k | } |
770 | 154k | slice->remove_prefix(num_decoded_bytes); |
771 | 154k | type_ref = value_type; |
772 | 154k | return Status::OK(); |
773 | 154k | } |
774 | | |
775 | 585 | case ValueType::kGinNull: { |
776 | 585 | if (slice->size() < sizeof(uint8_t)) { |
777 | 0 | return STATUS_SUBSTITUTE(Corruption, |
778 | 0 | "Not enough bytes to decode an 8-bit integer: $0", |
779 | 0 | slice->size()); |
780 | 0 | } |
781 | 585 | if (out) { |
782 | 351 | out->gin_null_val_ = slice->data()[0]; |
783 | 351 | } |
784 | 585 | slice->remove_prefix(sizeof(uint8_t)); |
785 | 585 | type_ref = value_type; |
786 | 585 | return Status::OK(); |
787 | 585 | } |
788 | | |
789 | 35.6k | case ValueType::kInt32Descending: FALLTHROUGH_INTENDED; |
790 | 313M | case ValueType::kInt32: FALLTHROUGH_INTENDED; |
791 | 313M | case ValueType::kWriteId: |
792 | 313M | if (slice->size() < sizeof(int32_t)) { |
793 | 0 | return STATUS_SUBSTITUTE(Corruption, |
794 | 0 | "Not enough bytes to decode a 32-bit integer: $0", |
795 | 0 | slice->size()); |
796 | 0 | } |
797 | 313M | if (out) { |
798 | 135M | out->int32_val_ = BigEndian::Load32(slice->data()) ^ kInt32SignBitFlipMask; |
799 | 135M | if (value_type == ValueType::kInt32Descending) { |
800 | 26.2k | out->int32_val_ = ~out->int32_val_; |
801 | 26.2k | } |
802 | 135M | } |
803 | 313M | slice->remove_prefix(sizeof(int32_t)); |
804 | 313M | type_ref = value_type; |
805 | 313M | return Status::OK(); |
806 | | |
807 | 0 | case ValueType::kPgTableOid: FALLTHROUGH_INTENDED; |
808 | 1.57k | case ValueType::kUInt32Descending: FALLTHROUGH_INTENDED; |
809 | 1.57k | case ValueType::kSubTransactionId: FALLTHROUGH_INTENDED; |
810 | 78.9M | case ValueType::kUInt32: |
811 | 78.9M | if (slice->size() < sizeof(uint32_t)) { |
812 | 0 | return STATUS_SUBSTITUTE(Corruption, |
813 | 0 | "Not enough bytes to decode a 32-bit integer: $0", |
814 | 0 | slice->size()); |
815 | 0 | } |
816 | 78.9M | if (out) { |
817 | 53.7M | out->uint32_val_ = BigEndian::Load32(slice->data()); |
818 | 53.7M | if (value_type == ValueType::kUInt32Descending) { |
819 | 1.24k | out->uint32_val_ = ~out->uint32_val_; |
820 | 1.24k | } |
821 | 53.7M | } |
822 | 78.9M | slice->remove_prefix(sizeof(uint32_t)); |
823 | 78.9M | type_ref = value_type; |
824 | 78.9M | return Status::OK(); |
825 | | |
826 | 0 | case ValueType::kUInt64Descending: FALLTHROUGH_INTENDED; |
827 | 8 | case ValueType::kUInt64: |
828 | 8 | if (slice->size() < sizeof(uint64_t)) { |
829 | 8 | return STATUS_SUBSTITUTE(Corruption, |
830 | 8 | "Not enough bytes to decode a 64-bit integer: $0", |
831 | 8 | slice->size()); |
832 | 8 | } |
833 | 0 | if (out) { |
834 | 0 | out->uint64_val_ = BigEndian::Load64(slice->data()); |
835 | 0 | if (value_type == ValueType::kUInt64Descending) { |
836 | 0 | out->uint64_val_ = ~out->uint64_val_; |
837 | 0 | } |
838 | 0 | } |
839 | 0 | slice->remove_prefix(sizeof(uint64_t)); |
840 | 0 | type_ref = value_type; |
841 | 0 | return Status::OK(); |
842 | |
|
843 | 994k | case ValueType::kInt64Descending: FALLTHROUGH_INTENDED; |
844 | 63.6M | case ValueType::kInt64: FALLTHROUGH_INTENDED; |
845 | 63.6M | case ValueType::kArrayIndex: |
846 | 63.6M | if (slice->size() < sizeof(int64_t)) { |
847 | 0 | return STATUS_SUBSTITUTE(Corruption, |
848 | 0 | "Not enough bytes to decode a 64-bit integer: $0", |
849 | 0 | slice->size()); |
850 | 0 | } |
851 | 63.6M | if (out) { |
852 | 40.2M | out->int64_val_ = DecodeInt64FromKey(*slice); |
853 | 40.2M | if (value_type == ValueType::kInt64Descending) { |
854 | 992k | out->int64_val_ = ~out->int64_val_; |
855 | 992k | } |
856 | 40.2M | } |
857 | 63.6M | slice->remove_prefix(sizeof(int64_t)); |
858 | 63.6M | type_ref = value_type; |
859 | 63.6M | return Status::OK(); |
860 | | |
861 | 0 | case ValueType::kUInt16Hash: |
862 | 0 | if (slice->size() < sizeof(uint16_t)) { |
863 | 0 | return STATUS(Corruption, Substitute("Not enough bytes to decode a 16-bit hash: $0", |
864 | 0 | slice->size())); |
865 | 0 | } |
866 | 0 | if (out) { |
867 | 0 | out->uint16_val_ = BigEndian::Load16(slice->data()); |
868 | 0 | } |
869 | 0 | slice->remove_prefix(sizeof(uint16_t)); |
870 | 0 | type_ref = value_type; |
871 | 0 | return Status::OK(); |
872 | |
|
873 | 28.2M | case ValueType::kTimestampDescending: FALLTHROUGH_INTENDED; |
874 | 28.2M | case ValueType::kTimestamp: { |
875 | 28.2M | if (slice->size() < sizeof(Timestamp)) { |
876 | 0 | return STATUS(Corruption, |
877 | 0 | Substitute("Not enough bytes to decode a Timestamp: $0, need $1", |
878 | 0 | slice->size(), sizeof(Timestamp))); |
879 | 0 | } |
880 | 28.2M | if (out) { |
881 | 16.2M | const auto uint64_timestamp = DecodeInt64FromKey(*slice); |
882 | 16.2M | if (value_type == ValueType::kTimestampDescending) { |
883 | | // Flip all the bits after loading the integer. |
884 | 16.1M | out->timestamp_val_ = Timestamp(~uint64_timestamp); |
885 | 45.3k | } else { |
886 | 45.3k | out->timestamp_val_ = Timestamp(uint64_timestamp); |
887 | 45.3k | } |
888 | 16.2M | } |
889 | 28.2M | slice->remove_prefix(sizeof(Timestamp)); |
890 | 28.2M | type_ref = value_type; |
891 | 28.2M | return Status::OK(); |
892 | 28.2M | } |
893 | | |
894 | 749 | case ValueType::kInetaddress: { |
895 | 749 | if (out) { |
896 | 601 | string bytes; |
897 | 601 | RETURN_NOT_OK(DecodeZeroEncodedStr(slice, &bytes)); |
898 | 601 | out->inetaddress_val_ = new InetAddress(); |
899 | 601 | RETURN_NOT_OK(out->inetaddress_val_->FromBytes(bytes)); |
900 | 148 | } else { |
901 | 148 | RETURN_NOT_OK(DecodeZeroEncodedStr(slice, nullptr)); |
902 | 148 | } |
903 | 749 | type_ref = value_type; |
904 | 749 | return Status::OK(); |
905 | 749 | } |
906 | | |
907 | 2.68k | case ValueType::kInetaddressDescending: { |
908 | 2.68k | if (out) { |
909 | 2.11k | string bytes; |
910 | 2.11k | RETURN_NOT_OK(DecodeComplementZeroEncodedStr(slice, &bytes)); |
911 | 2.11k | out->inetaddress_val_ = new InetAddress(); |
912 | 2.11k | RETURN_NOT_OK(out->inetaddress_val_->FromBytes(bytes)); |
913 | 572 | } else { |
914 | 572 | RETURN_NOT_OK(DecodeComplementZeroEncodedStr(slice, nullptr)); |
915 | 572 | } |
916 | 2.68k | type_ref = value_type; |
917 | 2.68k | return Status::OK(); |
918 | 2.68k | } |
919 | | |
920 | 0 | case ValueType::kTransactionApplyState: FALLTHROUGH_INTENDED; |
921 | 0 | case ValueType::kExternalTransactionId: |
922 | 0 | if (slice->size() < boost::uuids::uuid::static_size()) { |
923 | 0 | return STATUS_FORMAT(Corruption, "Not enough bytes for UUID: $0", slice->size()); |
924 | 0 | } |
925 | 0 | if (out) { |
926 | 0 | RETURN_NOT_OK((new(&out->uuid_val_) Uuid())->FromSlice( |
927 | 0 | *slice, boost::uuids::uuid::static_size())); |
928 | 0 | } |
929 | 0 | slice->remove_prefix(boost::uuids::uuid::static_size()); |
930 | 0 | type_ref = value_type; |
931 | 0 | return Status::OK(); |
932 | |
|
933 | 763k | case ValueType::kTransactionId: FALLTHROUGH_INTENDED; |
934 | 763k | case ValueType::kTableId: FALLTHROUGH_INTENDED; |
935 | 767k | case ValueType::kUuid: { |
936 | 767k | if (out) { |
937 | 2.57k | string bytes; |
938 | 2.57k | RETURN_NOT_OK(DecodeZeroEncodedStr(slice, &bytes)); |
939 | 2.57k | new(&out->uuid_val_) Uuid(); |
940 | 2.57k | RETURN_NOT_OK(out->uuid_val_.DecodeFromComparable(bytes)); |
941 | 764k | } else { |
942 | 764k | RETURN_NOT_OK(DecodeZeroEncodedStr(slice, nullptr)); |
943 | 764k | } |
944 | 746k | type_ref = value_type; |
945 | 746k | return Status::OK(); |
946 | 767k | } |
947 | | |
948 | 11.6k | case ValueType::kUuidDescending: { |
949 | 11.6k | if (out) { |
950 | 8.85k | string bytes; |
951 | 8.85k | RETURN_NOT_OK(DecodeComplementZeroEncodedStr(slice, &bytes)); |
952 | 8.85k | new(&out->uuid_val_) Uuid(); |
953 | 8.85k | RETURN_NOT_OK(out->uuid_val_.DecodeFromComparable(bytes)); |
954 | 2.79k | } else { |
955 | 2.79k | RETURN_NOT_OK(DecodeComplementZeroEncodedStr(slice, nullptr)); |
956 | 2.79k | } |
957 | 11.6k | type_ref = value_type; |
958 | 11.6k | return Status::OK(); |
959 | 11.6k | } |
960 | | |
961 | 106M | case ValueType::kColumnId: FALLTHROUGH_INTENDED; |
962 | 148M | case ValueType::kSystemColumnId: { |
963 | | // Decode varint |
964 | 148M | { |
965 | 148M | ColumnId dummy_column_id; |
966 | 86.3M | ColumnId& column_id_ref = out ? out->column_id_val_ : dummy_column_id; |
967 | 148M | int64_t column_id_as_int64 = VERIFY_RESULT(FastDecodeSignedVarIntUnsafe(slice)); |
968 | 148M | RETURN_NOT_OK(ColumnId::FromInt64(column_id_as_int64, &column_id_ref)); |
969 | 148M | } |
970 | | |
971 | 148M | type_ref = value_type; |
972 | 148M | return Status::OK(); |
973 | 148M | } |
974 | | |
975 | 0 | case ValueType::kHybridTime: { |
976 | 0 | if (out) { |
977 | 0 | new(&out->hybrid_time_val_) DocHybridTime(); |
978 | 0 | RETURN_NOT_OK(out->hybrid_time_val_.DecodeFrom(slice)); |
979 | 0 | } else { |
980 | 0 | DocHybridTime dummy_hybrid_time; |
981 | 0 | RETURN_NOT_OK(dummy_hybrid_time.DecodeFrom(slice)); |
982 | 0 | } |
983 | |
|
984 | 0 | type_ref = ValueType::kHybridTime; |
985 | 0 | return Status::OK(); |
986 | 0 | } |
987 | |
|
988 | 1.52M | case ValueType::kIntentTypeSet: FALLTHROUGH_INTENDED; |
989 | 1.52M | case ValueType::kObsoleteIntentTypeSet: FALLTHROUGH_INTENDED; |
990 | 1.52M | case ValueType::kObsoleteIntentType: { |
991 | 1.52M | if (out) { |
992 | 763k | out->uint16_val_ = static_cast<uint16_t>(*slice->data()); |
993 | 763k | } |
994 | 1.52M | type_ref = value_type; |
995 | 1.52M | slice->consume_byte(); |
996 | 1.52M | return Status::OK(); |
997 | 1.52M | } |
998 | | |
999 | 3.78k | case ValueType::kFloatDescending: FALLTHROUGH_INTENDED; |
1000 | 5.37k | case ValueType::kFloat: { |
1001 | 5.37k | if (slice->size() < sizeof(float_t)) { |
1002 | 0 | return STATUS_FORMAT(Corruption, "Not enough bytes to decode a float: $0", slice->size()); |
1003 | 0 | } |
1004 | 5.37k | if (out) { |
1005 | 4.03k | if (value_type == ValueType::kFloatDescending) { |
1006 | 2.91k | out->float_val_ = DecodeFloatFromKey(*slice, /* descending */ true); |
1007 | 1.11k | } else { |
1008 | 1.11k | out->float_val_ = DecodeFloatFromKey(*slice); |
1009 | 1.11k | } |
1010 | 4.03k | } |
1011 | 5.37k | slice->remove_prefix(sizeof(float_t)); |
1012 | 5.37k | type_ref = value_type; |
1013 | 5.37k | return Status::OK(); |
1014 | 5.37k | } |
1015 | 3.78k | case ValueType::kDoubleDescending: FALLTHROUGH_INTENDED; |
1016 | 8.59M | case ValueType::kDouble: { |
1017 | 8.59M | if (slice->size() < sizeof(double_t)) { |
1018 | 0 | return STATUS_FORMAT(Corruption, "Not enough bytes to decode a float: $0", slice->size()); |
1019 | 0 | } |
1020 | 8.59M | if (out) { |
1021 | 4.21M | if (value_type == ValueType::kDoubleDescending) { |
1022 | 2.91k | out->double_val_ = DecodeDoubleFromKey(*slice, /* descending */ true); |
1023 | 4.20M | } else { |
1024 | 4.20M | out->double_val_ = DecodeDoubleFromKey(*slice); |
1025 | 4.20M | } |
1026 | 4.21M | } |
1027 | 8.59M | slice->remove_prefix(sizeof(double_t)); |
1028 | 8.59M | type_ref = value_type; |
1029 | 8.59M | return Status::OK(); |
1030 | 8.59M | } |
1031 | 0 | case ValueType::kMaxByte: |
1032 | 0 | break; |
1033 | | |
1034 | 0 | IGNORE_NON_PRIMITIVE_VALUE_TYPES_IN_SWITCH; |
1035 | 843M | } |
1036 | 0 | return STATUS_FORMAT( |
1037 | 843M | Corruption, |
1038 | 843M | "Cannot decode value type $0 from the key encoding format: $1", |
1039 | 843M | value_type, |
1040 | 843M | ToShortDebugStr(input_slice)); |
1041 | 843M | } |
1042 | | |
1043 | 250M | Status PrimitiveValue::DecodeFromValue(const rocksdb::Slice& rocksdb_slice) { |
1044 | 250M | if (rocksdb_slice.empty()) { |
1045 | 0 | return STATUS(Corruption, "Cannot decode a value from an empty slice"); |
1046 | 0 | } |
1047 | 250M | rocksdb::Slice slice(rocksdb_slice); |
1048 | 250M | this->~PrimitiveValue(); |
1049 | | // Ensure we are not leaving the object in an invalid state in case e.g. an exception is thrown |
1050 | | // due to inability to allocate memory. |
1051 | 250M | type_ = ValueType::kNullLow; |
1052 | | |
1053 | 250M | const auto value_type = ConsumeValueType(&slice); |
1054 | | |
1055 | | // TODO: ensure we consume all data from the given slice. |
1056 | 250M | switch (value_type) { |
1057 | 0 | case ValueType::kNullHigh: FALLTHROUGH_INTENDED; |
1058 | 34.3M | case ValueType::kNullLow: FALLTHROUGH_INTENDED; |
1059 | 34.3M | case ValueType::kCounter: FALLTHROUGH_INTENDED; |
1060 | 34.3M | case ValueType::kSSForward: FALLTHROUGH_INTENDED; |
1061 | 34.3M | case ValueType::kSSReverse: FALLTHROUGH_INTENDED; |
1062 | 60.9M | case ValueType::kFalse: FALLTHROUGH_INTENDED; |
1063 | 74.1M | case ValueType::kTrue: FALLTHROUGH_INTENDED; |
1064 | 74.1M | case ValueType::kFalseDescending: FALLTHROUGH_INTENDED; |
1065 | 74.1M | case ValueType::kTrueDescending: FALLTHROUGH_INTENDED; |
1066 | 74.1M | case ValueType::kObject: FALLTHROUGH_INTENDED; |
1067 | 74.1M | case ValueType::kArray: FALLTHROUGH_INTENDED; |
1068 | 74.1M | case ValueType::kRedisList: FALLTHROUGH_INTENDED; |
1069 | 74.1M | case ValueType::kRedisSet: FALLTHROUGH_INTENDED; |
1070 | 74.1M | case ValueType::kRedisTS: FALLTHROUGH_INTENDED; |
1071 | 74.1M | case ValueType::kRedisSortedSet: FALLTHROUGH_INTENDED; |
1072 | 97.2M | case ValueType::kTombstone: |
1073 | 97.2M | type_ = value_type; |
1074 | 97.2M | complex_data_structure_ = nullptr; |
1075 | 97.2M | return Status::OK(); |
1076 | | |
1077 | 0 | case ValueType::kFrozenDescending: FALLTHROUGH_INTENDED; |
1078 | 102 | case ValueType::kFrozen: { |
1079 | 102 | ValueType end_marker_value_type = ValueType::kGroupEnd; |
1080 | 102 | if (value_type == ValueType::kFrozenDescending) { |
1081 | 0 | end_marker_value_type = ValueType::kGroupEndDescending; |
1082 | 0 | } |
1083 | | |
1084 | 102 | frozen_val_ = new FrozenContainer(); |
1085 | 305 | while (!slice.empty()) { |
1086 | 305 | ValueType current_value_type = static_cast<ValueType>(*slice.data()); |
1087 | 305 | if (current_value_type == end_marker_value_type) { |
1088 | 102 | slice.consume_byte(); |
1089 | 102 | type_ = value_type; |
1090 | 102 | return Status::OK(); |
1091 | 203 | } else { |
1092 | 203 | PrimitiveValue pv; |
1093 | | // Frozen elems are encoded as keys even in values. |
1094 | 203 | RETURN_NOT_OK(pv.DecodeFromKey(&slice)); |
1095 | 203 | frozen_val_->push_back(pv); |
1096 | 203 | } |
1097 | 305 | } |
1098 | | |
1099 | 0 | return STATUS(Corruption, "Reached end of slice looking for frozen group end marker"); |
1100 | 102 | } |
1101 | 0 | case ValueType::kCollString: FALLTHROUGH_INTENDED; |
1102 | 25.9M | case ValueType::kString: |
1103 | 25.9M | new(&str_val_) string(slice.cdata(), slice.size()); |
1104 | | // Only set type to string after string field initialization succeeds. |
1105 | 25.9M | type_ = value_type; |
1106 | 25.9M | return Status::OK(); |
1107 | |
|
1108 | 0 | case ValueType::kGinNull: |
1109 | 0 | if (slice.size() != sizeof(uint8_t)) { |
1110 | 0 | return STATUS_FORMAT(Corruption, "Invalid number of bytes for a $0: $1", |
1111 | 0 | value_type, slice.size()); |
1112 | 0 | } |
1113 | 0 | type_ = value_type; |
1114 | 0 | gin_null_val_ = slice.data()[0]; |
1115 | 0 | return Status::OK(); |
1116 | |
|
1117 | 80.7M | case ValueType::kInt32: FALLTHROUGH_INTENDED; |
1118 | 80.7M | case ValueType::kInt32Descending: FALLTHROUGH_INTENDED; |
1119 | 80.7M | case ValueType::kFloatDescending: FALLTHROUGH_INTENDED; |
1120 | 80.7M | case ValueType::kWriteId: FALLTHROUGH_INTENDED; |
1121 | 81.6M | case ValueType::kFloat: |
1122 | 81.6M | if (slice.size() != sizeof(int32_t)) { |
1123 | 0 | return STATUS_FORMAT(Corruption, "Invalid number of bytes for a $0: $1", |
1124 | 0 | value_type, slice.size()); |
1125 | 0 | } |
1126 | 81.6M | type_ = value_type; |
1127 | 81.6M | int32_val_ = BigEndian::Load32(slice.data()); |
1128 | 81.6M | return Status::OK(); |
1129 | | |
1130 | 0 | case ValueType::kPgTableOid: FALLTHROUGH_INTENDED; |
1131 | 45.6M | case ValueType::kUInt32: FALLTHROUGH_INTENDED; |
1132 | 45.6M | case ValueType::kSubTransactionId: FALLTHROUGH_INTENDED; |
1133 | 45.6M | case ValueType::kUInt32Descending: |
1134 | 45.6M | if (slice.size() != sizeof(uint32_t)) { |
1135 | 0 | return STATUS_FORMAT(Corruption, "Invalid number of bytes for a $0: $1", |
1136 | 0 | value_type, slice.size()); |
1137 | 0 | } |
1138 | 45.6M | type_ = value_type; |
1139 | 45.6M | uint32_val_ = BigEndian::Load32(slice.data()); |
1140 | 45.6M | return Status::OK(); |
1141 | | |
1142 | 0 | case ValueType::kUInt64: FALLTHROUGH_INTENDED; |
1143 | 0 | case ValueType::kUInt64Descending: |
1144 | 0 | if (slice.size() != sizeof(uint64_t)) { |
1145 | 0 | return STATUS_FORMAT(Corruption, "Invalid number of bytes for a $0: $1", |
1146 | 0 | value_type, slice.size()); |
1147 | 0 | } |
1148 | 0 | type_ = value_type; |
1149 | 0 | uint64_val_ = BigEndian::Load64(slice.data()); |
1150 | 0 | return Status::OK(); |
1151 | |
|
1152 | 1.01M | case ValueType::kInt64: FALLTHROUGH_INTENDED; |
1153 | 1.01M | case ValueType::kInt64Descending: FALLTHROUGH_INTENDED; |
1154 | 1.01M | case ValueType::kArrayIndex: FALLTHROUGH_INTENDED; |
1155 | 1.01M | case ValueType::kDoubleDescending: FALLTHROUGH_INTENDED; |
1156 | 1.01M | case ValueType::kDouble: |
1157 | 1.01M | if (slice.size() != sizeof(int64_t)) { |
1158 | 0 | return STATUS_FORMAT(Corruption, "Invalid number of bytes for a $0: $1", |
1159 | 0 | value_type, slice.size()); |
1160 | 0 | } |
1161 | 1.01M | type_ = value_type; |
1162 | 1.01M | int64_val_ = BigEndian::Load64(slice.data()); |
1163 | 1.01M | return Status::OK(); |
1164 | | |
1165 | 8.76k | case ValueType::kDecimal: { |
1166 | 8.76k | util::Decimal decimal; |
1167 | 8.76k | size_t num_decoded_bytes = 0; |
1168 | 8.76k | RETURN_NOT_OK(decimal.DecodeFromComparable(slice.ToString(), &num_decoded_bytes)); |
1169 | 8.76k | type_ = value_type; |
1170 | 8.76k | new(&decimal_val_) string(decimal.EncodeToComparable()); |
1171 | 8.76k | return Status::OK(); |
1172 | 8.76k | } |
1173 | | |
1174 | 580 | case ValueType::kVarInt: { |
1175 | 580 | util::VarInt varint; |
1176 | 580 | size_t num_decoded_bytes = 0; |
1177 | 580 | RETURN_NOT_OK(varint.DecodeFromComparable(slice.ToString(), &num_decoded_bytes)); |
1178 | 580 | type_ = value_type; |
1179 | 580 | new(&varint_val_) string(varint.EncodeToComparable()); |
1180 | 580 | return Status::OK(); |
1181 | 580 | } |
1182 | | |
1183 | 306 | case ValueType::kTimestamp: |
1184 | 306 | if (slice.size() != sizeof(Timestamp)) { |
1185 | 0 | return STATUS_FORMAT(Corruption, "Invalid number of bytes for a $0: $1", |
1186 | 0 | value_type, slice.size()); |
1187 | 0 | } |
1188 | 306 | type_ = value_type; |
1189 | 306 | timestamp_val_ = Timestamp(BigEndian::Load64(slice.data())); |
1190 | 306 | return Status::OK(); |
1191 | | |
1192 | 14.2k | case ValueType::kJsonb: { |
1193 | 14.2k | if (slice.size() < sizeof(int64_t)) { |
1194 | 0 | return STATUS_FORMAT(Corruption, "Invalid number of bytes for a $0: $1", |
1195 | 0 | value_type, slice.size()); |
1196 | 0 | } |
1197 | | // Read the jsonb flags. |
1198 | 14.2k | int64_t jsonb_flags = BigEndian::Load64(slice.data()); |
1199 | 14.2k | slice.remove_prefix(sizeof(jsonb_flags)); |
1200 | | |
1201 | | // Read the serialized jsonb. |
1202 | 14.2k | new(&json_val_) string(slice.ToBuffer()); |
1203 | 14.2k | type_ = value_type; |
1204 | 14.2k | return Status::OK(); |
1205 | 14.2k | } |
1206 | | |
1207 | 8 | case ValueType::kInetaddress: { |
1208 | 8 | if (slice.size() != kInetAddressV4Size && slice.size() != kInetAddressV6Size) { |
1209 | 0 | return STATUS_FORMAT(Corruption, |
1210 | 0 | "Invalid number of bytes to decode IPv4/IPv6: $0, need $1 or $2", |
1211 | 0 | slice.size(), kInetAddressV4Size, kInetAddressV6Size); |
1212 | 0 | } |
1213 | | // Need to use a non-rocksdb slice for InetAddress. |
1214 | 8 | Slice slice_temp(slice.data(), slice.size()); |
1215 | 8 | inetaddress_val_ = new InetAddress(); |
1216 | 8 | RETURN_NOT_OK(inetaddress_val_->FromSlice(slice_temp)); |
1217 | 8 | type_ = value_type; |
1218 | 8 | return Status::OK(); |
1219 | 8 | } |
1220 | | |
1221 | 0 | case ValueType::kTransactionApplyState: FALLTHROUGH_INTENDED; |
1222 | 0 | case ValueType::kExternalTransactionId: FALLTHROUGH_INTENDED; |
1223 | 0 | case ValueType::kTransactionId: FALLTHROUGH_INTENDED; |
1224 | 0 | case ValueType::kTableId: FALLTHROUGH_INTENDED; |
1225 | 62 | case ValueType::kUuid: { |
1226 | 62 | if (slice.size() != kUuidSize) { |
1227 | 0 | return STATUS_FORMAT(Corruption, "Invalid number of bytes to decode Uuid: $0, need $1", |
1228 | 0 | slice.size(), kUuidSize); |
1229 | 0 | } |
1230 | 62 | Slice slice_temp(slice.data(), slice.size()); |
1231 | 62 | new(&uuid_val_) Uuid(); |
1232 | 62 | RETURN_NOT_OK(uuid_val_.DecodeFromComparableSlice(slice_temp)); |
1233 | 62 | type_ = value_type; |
1234 | 62 | return Status::OK(); |
1235 | 62 | } |
1236 | | |
1237 | 0 | case ValueType::kIntentTypeSet: FALLTHROUGH_INTENDED; |
1238 | 0 | case ValueType::kObsoleteIntentTypeSet: FALLTHROUGH_INTENDED; |
1239 | 0 | case ValueType::kObsoleteIntentType: FALLTHROUGH_INTENDED; |
1240 | 0 | case ValueType::kGroupEnd: FALLTHROUGH_INTENDED; |
1241 | 0 | case ValueType::kGroupEndDescending: FALLTHROUGH_INTENDED; |
1242 | 0 | case ValueType::kObsoleteIntentPrefix: FALLTHROUGH_INTENDED; |
1243 | 0 | case ValueType::kGreaterThanIntentType: FALLTHROUGH_INTENDED; |
1244 | 0 | case ValueType::kUInt16Hash: FALLTHROUGH_INTENDED; |
1245 | 0 | case ValueType::kInvalid: FALLTHROUGH_INTENDED; |
1246 | 0 | case ValueType::kMergeFlags: FALLTHROUGH_INTENDED; |
1247 | 0 | case ValueType::kRowLock: FALLTHROUGH_INTENDED; |
1248 | 0 | case ValueType::kBitSet: FALLTHROUGH_INTENDED; |
1249 | 0 | case ValueType::kTtl: FALLTHROUGH_INTENDED; |
1250 | 0 | case ValueType::kUserTimestamp: FALLTHROUGH_INTENDED; |
1251 | 0 | case ValueType::kColumnId: FALLTHROUGH_INTENDED; |
1252 | 0 | case ValueType::kSystemColumnId: FALLTHROUGH_INTENDED; |
1253 | 0 | case ValueType::kHybridTime: FALLTHROUGH_INTENDED; |
1254 | 0 | case ValueType::kCollStringDescending: FALLTHROUGH_INTENDED; |
1255 | 0 | case ValueType::kStringDescending: FALLTHROUGH_INTENDED; |
1256 | 0 | case ValueType::kInetaddressDescending: FALLTHROUGH_INTENDED; |
1257 | 0 | case ValueType::kDecimalDescending: FALLTHROUGH_INTENDED; |
1258 | 0 | case ValueType::kVarIntDescending: FALLTHROUGH_INTENDED; |
1259 | 0 | case ValueType::kUuidDescending: FALLTHROUGH_INTENDED; |
1260 | 0 | case ValueType::kTimestampDescending: FALLTHROUGH_INTENDED; |
1261 | 0 | case ValueType::kExternalIntents: FALLTHROUGH_INTENDED; |
1262 | 0 | case ValueType::kLowest: FALLTHROUGH_INTENDED; |
1263 | 0 | case ValueType::kHighest: FALLTHROUGH_INTENDED; |
1264 | 0 | case ValueType::kMaxByte: |
1265 | 0 | return STATUS_FORMAT(Corruption, "$0 is not allowed in a RocksDB PrimitiveValue", value_type); |
1266 | 0 | } |
1267 | 0 | FATAL_INVALID_ENUM_VALUE(ValueType, value_type); |
1268 | 0 | return Status::OK(); |
1269 | 0 | } |
1270 | | |
1271 | 194k | PrimitiveValue PrimitiveValue::Double(double d, SortOrder sort_order) { |
1272 | 194k | PrimitiveValue primitive_value; |
1273 | 194k | if (sort_order == SortOrder::kAscending) { |
1274 | 193k | primitive_value.type_ = ValueType::kDouble; |
1275 | 288 | } else { |
1276 | 288 | primitive_value.type_ = ValueType::kDoubleDescending; |
1277 | 288 | } |
1278 | 194k | primitive_value.double_val_ = d; |
1279 | 194k | return primitive_value; |
1280 | 194k | } |
1281 | | |
1282 | 136k | PrimitiveValue PrimitiveValue::Float(float f, SortOrder sort_order) { |
1283 | 136k | PrimitiveValue primitive_value; |
1284 | 136k | if (sort_order == SortOrder::kAscending) { |
1285 | 136k | primitive_value.type_ = ValueType::kFloat; |
1286 | 288 | } else { |
1287 | 288 | primitive_value.type_ = ValueType::kFloatDescending; |
1288 | 288 | } |
1289 | 136k | primitive_value.float_val_ = f; |
1290 | 136k | return primitive_value; |
1291 | 136k | } |
1292 | | |
1293 | 4.60k | PrimitiveValue PrimitiveValue::Decimal(const string& encoded_decimal_str, SortOrder sort_order) { |
1294 | 4.60k | PrimitiveValue primitive_value; |
1295 | 4.60k | if (sort_order == SortOrder::kDescending) { |
1296 | 124 | primitive_value.type_ = ValueType::kDecimalDescending; |
1297 | 4.48k | } else { |
1298 | 4.48k | primitive_value.type_ = ValueType::kDecimal; |
1299 | 4.48k | } |
1300 | 4.60k | new(&primitive_value.decimal_val_) string(encoded_decimal_str); |
1301 | 4.60k | return primitive_value; |
1302 | 4.60k | } |
1303 | | |
1304 | 3.63k | PrimitiveValue PrimitiveValue::VarInt(const string& encoded_varint_str, SortOrder sort_order) { |
1305 | 3.63k | PrimitiveValue primitive_value; |
1306 | 3.63k | if (sort_order == SortOrder::kDescending) { |
1307 | 122 | primitive_value.type_ = ValueType::kVarIntDescending; |
1308 | 3.51k | } else { |
1309 | 3.51k | primitive_value.type_ = ValueType::kVarInt; |
1310 | 3.51k | } |
1311 | 3.63k | new(&primitive_value.varint_val_) string(encoded_varint_str); |
1312 | 3.63k | return primitive_value; |
1313 | 3.63k | } |
1314 | | |
1315 | 133 | PrimitiveValue PrimitiveValue::ArrayIndex(int64_t index) { |
1316 | 133 | PrimitiveValue primitive_value; |
1317 | 133 | primitive_value.type_ = ValueType::kArrayIndex; |
1318 | 133 | primitive_value.int64_val_ = index; |
1319 | 133 | return primitive_value; |
1320 | 133 | } |
1321 | | |
1322 | 0 | PrimitiveValue PrimitiveValue::UInt16Hash(uint16_t hash) { |
1323 | 0 | PrimitiveValue primitive_value; |
1324 | 0 | primitive_value.type_ = ValueType::kUInt16Hash; |
1325 | 0 | primitive_value.uint16_val_ = hash; |
1326 | 0 | return primitive_value; |
1327 | 0 | } |
1328 | | |
1329 | 15.8k | PrimitiveValue PrimitiveValue::SystemColumnId(SystemColumnIds system_column_id) { |
1330 | 15.8k | return PrimitiveValue::SystemColumnId(ColumnId(static_cast<ColumnIdRep>(system_column_id))); |
1331 | 15.8k | } |
1332 | | |
1333 | 15.8k | PrimitiveValue PrimitiveValue::SystemColumnId(ColumnId column_id) { |
1334 | 15.8k | PrimitiveValue primitive_value; |
1335 | 15.8k | primitive_value.type_ = ValueType::kSystemColumnId; |
1336 | 15.8k | primitive_value.column_id_val_ = column_id; |
1337 | 15.8k | return primitive_value; |
1338 | 15.8k | } |
1339 | | |
1340 | 16.0M | PrimitiveValue PrimitiveValue::Int32(int32_t v, SortOrder sort_order) { |
1341 | 16.0M | PrimitiveValue primitive_value; |
1342 | 16.0M | if (sort_order == SortOrder::kDescending) { |
1343 | 4.31k | primitive_value.type_ = ValueType::kInt32Descending; |
1344 | 16.0M | } else { |
1345 | 16.0M | primitive_value.type_ = ValueType::kInt32; |
1346 | 16.0M | } |
1347 | 16.0M | primitive_value.int32_val_ = v; |
1348 | 16.0M | return primitive_value; |
1349 | 16.0M | } |
1350 | | |
1351 | 4.70M | PrimitiveValue PrimitiveValue::UInt32(uint32_t v, SortOrder sort_order) { |
1352 | 4.70M | PrimitiveValue primitive_value; |
1353 | 4.70M | if (sort_order == SortOrder::kDescending) { |
1354 | 89 | primitive_value.type_ = ValueType::kUInt32Descending; |
1355 | 4.70M | } else { |
1356 | 4.70M | primitive_value.type_ = ValueType::kUInt32; |
1357 | 4.70M | } |
1358 | 4.70M | primitive_value.uint32_val_ = v; |
1359 | 4.70M | return primitive_value; |
1360 | 4.70M | } |
1361 | | |
1362 | 0 | PrimitiveValue PrimitiveValue::UInt64(uint64_t v, SortOrder sort_order) { |
1363 | 0 | PrimitiveValue primitive_value; |
1364 | 0 | if (sort_order == SortOrder::kDescending) { |
1365 | 0 | primitive_value.type_ = ValueType::kUInt64Descending; |
1366 | 0 | } else { |
1367 | 0 | primitive_value.type_ = ValueType::kUInt64; |
1368 | 0 | } |
1369 | 0 | primitive_value.uint64_val_ = v; |
1370 | 0 | return primitive_value; |
1371 | 0 | } |
1372 | | |
1373 | 0 | PrimitiveValue PrimitiveValue::TransactionId(Uuid transaction_id) { |
1374 | 0 | PrimitiveValue primitive_value(transaction_id); |
1375 | 0 | primitive_value.type_ = ValueType::kTransactionId; |
1376 | 0 | return primitive_value; |
1377 | 0 | } |
1378 | | |
1379 | 0 | PrimitiveValue PrimitiveValue::TableId(Uuid table_id) { |
1380 | 0 | PrimitiveValue primitive_value(table_id); |
1381 | 0 | primitive_value.type_ = ValueType::kTableId; |
1382 | 0 | return primitive_value; |
1383 | 0 | } |
1384 | | |
1385 | 0 | PrimitiveValue PrimitiveValue::PgTableOid(const yb::PgTableOid pgtable_id) { |
1386 | 0 | PrimitiveValue primitive_value(pgtable_id); |
1387 | 0 | primitive_value.type_ = ValueType::kPgTableOid; |
1388 | 0 | return primitive_value; |
1389 | 0 | } |
1390 | | |
1391 | 7.41k | PrimitiveValue PrimitiveValue::Jsonb(const std::string& json) { |
1392 | 7.41k | PrimitiveValue primitive_value; |
1393 | 7.41k | primitive_value.type_ = ValueType::kJsonb; |
1394 | 7.41k | new(&primitive_value.json_val_) string(json); |
1395 | 7.41k | return primitive_value; |
1396 | 7.41k | } |
1397 | | |
1398 | 351 | PrimitiveValue PrimitiveValue::GinNull(uint8_t v) { |
1399 | 351 | PrimitiveValue primitive_value; |
1400 | 351 | primitive_value.type_ = ValueType::kGinNull; |
1401 | 351 | primitive_value.gin_null_val_ = v; |
1402 | 351 | return primitive_value; |
1403 | 351 | } |
1404 | | |
1405 | 0 | KeyBytes PrimitiveValue::ToKeyBytes() const { |
1406 | 0 | KeyBytes kb; |
1407 | 0 | AppendToKey(&kb); |
1408 | 0 | return kb; |
1409 | 0 | } |
1410 | | |
1411 | 39.9M | bool PrimitiveValue::operator==(const PrimitiveValue& other) const { |
1412 | 39.9M | if (type_ != other.type_) { |
1413 | 10.3M | return false; |
1414 | 10.3M | } |
1415 | 29.6M | switch (type_) { |
1416 | 0 | case ValueType::kNullHigh: FALLTHROUGH_INTENDED; |
1417 | 3.92k | case ValueType::kNullLow: FALLTHROUGH_INTENDED; |
1418 | 3.92k | case ValueType::kCounter: FALLTHROUGH_INTENDED; |
1419 | 3.92k | case ValueType::kFalse: FALLTHROUGH_INTENDED; |
1420 | 3.92k | case ValueType::kFalseDescending: FALLTHROUGH_INTENDED; |
1421 | 3.92k | case ValueType::kSSForward: FALLTHROUGH_INTENDED; |
1422 | 3.92k | case ValueType::kSSReverse: FALLTHROUGH_INTENDED; |
1423 | 3.92k | case ValueType::kTrue: FALLTHROUGH_INTENDED; |
1424 | 3.92k | case ValueType::kTrueDescending: FALLTHROUGH_INTENDED; |
1425 | 3.92k | case ValueType::kLowest: FALLTHROUGH_INTENDED; |
1426 | 3.92k | case ValueType::kHighest: FALLTHROUGH_INTENDED; |
1427 | 3.92k | case ValueType::kMaxByte: return true; |
1428 | | |
1429 | 0 | case ValueType::kCollStringDescending: FALLTHROUGH_INTENDED; |
1430 | 0 | case ValueType::kCollString: FALLTHROUGH_INTENDED; |
1431 | 10.8k | case ValueType::kStringDescending: FALLTHROUGH_INTENDED; |
1432 | 2.09M | case ValueType::kString: return str_val_ == other.str_val_; |
1433 | | |
1434 | 6 | case ValueType::kFrozenDescending: FALLTHROUGH_INTENDED; |
1435 | 28 | case ValueType::kFrozen: return *frozen_val_ == *other.frozen_val_; |
1436 | | |
1437 | 881 | case ValueType::kInt32Descending: FALLTHROUGH_INTENDED; |
1438 | 881 | case ValueType::kWriteId: FALLTHROUGH_INTENDED; |
1439 | 5.81M | case ValueType::kInt32: return int32_val_ == other.int32_val_; |
1440 | | |
1441 | 0 | case ValueType::kPgTableOid: FALLTHROUGH_INTENDED; |
1442 | 9 | case ValueType::kUInt32Descending: FALLTHROUGH_INTENDED; |
1443 | 9 | case ValueType::kSubTransactionId: FALLTHROUGH_INTENDED; |
1444 | 68.9k | case ValueType::kUInt32: return uint32_val_ == other.uint32_val_; |
1445 | | |
1446 | 0 | case ValueType::kUInt64Descending: FALLTHROUGH_INTENDED; |
1447 | 0 | case ValueType::kUInt64: return uint64_val_ == other.uint64_val_; |
1448 | |
|
1449 | 153 | case ValueType::kInt64Descending: FALLTHROUGH_INTENDED; |
1450 | 20.1M | case ValueType::kInt64: FALLTHROUGH_INTENDED; |
1451 | 20.1M | case ValueType::kArrayIndex: return int64_val_ == other.int64_val_; |
1452 | | |
1453 | 144 | case ValueType::kFloatDescending: FALLTHROUGH_INTENDED; |
1454 | 192 | case ValueType::kFloat: { |
1455 | 192 | if (util::IsNanFloat(float_val_) && util::IsNanFloat(other.float_val_)) { |
1456 | 0 | return true; |
1457 | 0 | } |
1458 | 192 | return float_val_ == other.float_val_; |
1459 | 192 | } |
1460 | 144 | case ValueType::kDoubleDescending: FALLTHROUGH_INTENDED; |
1461 | 680k | case ValueType::kDouble: { |
1462 | 680k | if (util::IsNanDouble(double_val_) && util::IsNanDouble(other.double_val_)) { |
1463 | 0 | return true; |
1464 | 0 | } |
1465 | 680k | return double_val_ == other.double_val_; |
1466 | 680k | } |
1467 | 0 | case ValueType::kDecimalDescending: FALLTHROUGH_INTENDED; |
1468 | 5.28k | case ValueType::kDecimal: return decimal_val_ == other.decimal_val_; |
1469 | 0 | case ValueType::kVarIntDescending: FALLTHROUGH_INTENDED; |
1470 | 5.28k | case ValueType::kVarInt: return varint_val_ == other.varint_val_; |
1471 | 0 | case ValueType::kIntentTypeSet: FALLTHROUGH_INTENDED; |
1472 | 0 | case ValueType::kObsoleteIntentTypeSet: FALLTHROUGH_INTENDED; |
1473 | 0 | case ValueType::kObsoleteIntentType: FALLTHROUGH_INTENDED; |
1474 | 0 | case ValueType::kUInt16Hash: return uint16_val_ == other.uint16_val_; |
1475 | |
|
1476 | 875k | case ValueType::kTimestampDescending: FALLTHROUGH_INTENDED; |
1477 | 875k | case ValueType::kTimestamp: return timestamp_val_ == other.timestamp_val_; |
1478 | 84 | case ValueType::kInetaddressDescending: FALLTHROUGH_INTENDED; |
1479 | 109 | case ValueType::kInetaddress: return *inetaddress_val_ == *(other.inetaddress_val_); |
1480 | 0 | case ValueType::kTransactionApplyState: FALLTHROUGH_INTENDED; |
1481 | 0 | case ValueType::kExternalTransactionId: FALLTHROUGH_INTENDED; |
1482 | 0 | case ValueType::kTransactionId: FALLTHROUGH_INTENDED; |
1483 | 0 | case ValueType::kTableId: FALLTHROUGH_INTENDED; |
1484 | 492 | case ValueType::kUuidDescending: FALLTHROUGH_INTENDED; |
1485 | 636 | case ValueType::kUuid: return uuid_val_ == other.uuid_val_; |
1486 | | |
1487 | 0 | case ValueType::kColumnId: FALLTHROUGH_INTENDED; |
1488 | 0 | case ValueType::kSystemColumnId: return column_id_val_ == other.column_id_val_; |
1489 | 0 | case ValueType::kHybridTime: return hybrid_time_val_.CompareTo(other.hybrid_time_val_) == 0; |
1490 | 0 | case ValueType::kGinNull: return gin_null_val_ == other.gin_null_val_; |
1491 | 0 | IGNORE_NON_PRIMITIVE_VALUE_TYPES_IN_SWITCH; |
1492 | 29.6M | } |
1493 | 0 | FATAL_INVALID_ENUM_VALUE(ValueType, type_); |
1494 | 0 | } |
1495 | | |
1496 | 3.66G | int PrimitiveValue::CompareTo(const PrimitiveValue& other) const { |
1497 | 3.66G | int result = CompareUsingLessThan(type_, other.type_); |
1498 | 3.66G | if (result != 0) { |
1499 | 231M | return result; |
1500 | 231M | } |
1501 | 3.43G | switch (type_) { |
1502 | 2 | case ValueType::kNullHigh: FALLTHROUGH_INTENDED; |
1503 | 8 | case ValueType::kNullLow: FALLTHROUGH_INTENDED; |
1504 | 8 | case ValueType::kCounter: FALLTHROUGH_INTENDED; |
1505 | 8 | case ValueType::kSSForward: FALLTHROUGH_INTENDED; |
1506 | 8 | case ValueType::kSSReverse: FALLTHROUGH_INTENDED; |
1507 | 10 | case ValueType::kFalse: FALLTHROUGH_INTENDED; |
1508 | 10 | case ValueType::kTrue: FALLTHROUGH_INTENDED; |
1509 | 10 | case ValueType::kFalseDescending: FALLTHROUGH_INTENDED; |
1510 | 10 | case ValueType::kTrueDescending: FALLTHROUGH_INTENDED; |
1511 | 10 | case ValueType::kLowest: FALLTHROUGH_INTENDED; |
1512 | 10 | case ValueType::kHighest: FALLTHROUGH_INTENDED; |
1513 | 10 | case ValueType::kMaxByte: |
1514 | 10 | return 0; |
1515 | 0 | case ValueType::kCollStringDescending: FALLTHROUGH_INTENDED; |
1516 | 19.8k | case ValueType::kStringDescending: |
1517 | 19.8k | return other.str_val_.compare(str_val_); |
1518 | 0 | case ValueType::kCollString: FALLTHROUGH_INTENDED; |
1519 | 93.2k | case ValueType::kString: |
1520 | 93.2k | return str_val_.compare(other.str_val_); |
1521 | 35.7M | case ValueType::kInt64Descending: |
1522 | 35.7M | return CompareUsingLessThan(other.int64_val_, int64_val_); |
1523 | 2.49k | case ValueType::kInt32Descending: |
1524 | 2.49k | return CompareUsingLessThan(other.int32_val_, int32_val_); |
1525 | 35.5M | case ValueType::kInt32: FALLTHROUGH_INTENDED; |
1526 | 35.5M | case ValueType::kWriteId: |
1527 | 35.5M | return CompareUsingLessThan(int32_val_, other.int32_val_); |
1528 | 36 | case ValueType::kUInt32Descending: |
1529 | 36 | return CompareUsingLessThan(other.uint32_val_, uint32_val_); |
1530 | 0 | case ValueType::kPgTableOid: FALLTHROUGH_INTENDED; |
1531 | 0 | case ValueType::kSubTransactionId: FALLTHROUGH_INTENDED; |
1532 | 74.4k | case ValueType::kUInt32: |
1533 | 74.4k | return CompareUsingLessThan(uint32_val_, other.uint32_val_); |
1534 | 0 | case ValueType::kUInt64Descending: |
1535 | 0 | return CompareUsingLessThan(other.uint64_val_, uint64_val_); |
1536 | 0 | case ValueType::kUInt64: |
1537 | 0 | return CompareUsingLessThan(uint64_val_, other.uint64_val_); |
1538 | 823k | case ValueType::kInt64: FALLTHROUGH_INTENDED; |
1539 | 823k | case ValueType::kArrayIndex: |
1540 | 823k | return CompareUsingLessThan(int64_val_, other.int64_val_); |
1541 | 288 | case ValueType::kDoubleDescending: |
1542 | 288 | return CompareUsingLessThan(other.double_val_, double_val_); |
1543 | 645 | case ValueType::kDouble: |
1544 | 645 | return CompareUsingLessThan(double_val_, other.double_val_); |
1545 | 288 | case ValueType::kFloatDescending: |
1546 | 288 | return CompareUsingLessThan(other.float_val_, float_val_); |
1547 | 105 | case ValueType::kFloat: |
1548 | 105 | return CompareUsingLessThan(float_val_, other.float_val_); |
1549 | 0 | case ValueType::kDecimalDescending: |
1550 | 0 | return other.decimal_val_.compare(decimal_val_); |
1551 | 10.1k | case ValueType::kDecimal: |
1552 | 10.1k | return decimal_val_.compare(other.decimal_val_); |
1553 | 0 | case ValueType::kVarIntDescending: |
1554 | 0 | return other.varint_val_.compare(varint_val_); |
1555 | 10.1k | case ValueType::kVarInt: |
1556 | 10.1k | return varint_val_.compare(other.varint_val_); |
1557 | 0 | case ValueType::kIntentTypeSet: FALLTHROUGH_INTENDED; |
1558 | 0 | case ValueType::kObsoleteIntentTypeSet: FALLTHROUGH_INTENDED; |
1559 | 0 | case ValueType::kObsoleteIntentType: FALLTHROUGH_INTENDED; |
1560 | 0 | case ValueType::kUInt16Hash: |
1561 | 0 | return CompareUsingLessThan(uint16_val_, other.uint16_val_); |
1562 | 288 | case ValueType::kTimestampDescending: |
1563 | 288 | return CompareUsingLessThan(other.timestamp_val_, timestamp_val_); |
1564 | 106 | case ValueType::kTimestamp: |
1565 | 106 | return CompareUsingLessThan(timestamp_val_, other.timestamp_val_); |
1566 | 48 | case ValueType::kInetaddress: |
1567 | 48 | return CompareUsingLessThan(*inetaddress_val_, *(other.inetaddress_val_)); |
1568 | 168 | case ValueType::kInetaddressDescending: |
1569 | 168 | return CompareUsingLessThan(*(other.inetaddress_val_), *inetaddress_val_); |
1570 | 20 | case ValueType::kFrozenDescending: FALLTHROUGH_INTENDED; |
1571 | 201 | case ValueType::kFrozen: { |
1572 | | // Compare elements one by one. |
1573 | 201 | size_t min_size = std::min(frozen_val_->size(), other.frozen_val_->size()); |
1574 | 274 | for (size_t i = 0; i < min_size; i++) { |
1575 | 222 | result = frozen_val_->at(i).CompareTo(other.frozen_val_->at(i)); |
1576 | 222 | if (result != 0) { |
1577 | 149 | return result; |
1578 | 149 | } |
1579 | 222 | } |
1580 | | |
1581 | | // If elements are equal, compare lengths. |
1582 | 52 | if (type_ == ValueType::kFrozenDescending) { |
1583 | 3 | return CompareUsingLessThan(other.frozen_val_->size(), frozen_val_->size()); |
1584 | 49 | } else { |
1585 | 49 | return CompareUsingLessThan(frozen_val_->size(), other.frozen_val_->size()); |
1586 | 49 | } |
1587 | 0 | } |
1588 | 0 | case ValueType::kTransactionApplyState: FALLTHROUGH_INTENDED; |
1589 | 0 | case ValueType::kExternalTransactionId: FALLTHROUGH_INTENDED; |
1590 | 0 | case ValueType::kTransactionId: FALLTHROUGH_INTENDED; |
1591 | 0 | case ValueType::kTableId: FALLTHROUGH_INTENDED; |
1592 | 984 | case ValueType::kUuidDescending: |
1593 | 984 | return CompareUsingLessThan(other.uuid_val_, uuid_val_); |
1594 | 288 | case ValueType::kUuid: |
1595 | 288 | return CompareUsingLessThan(uuid_val_, other.uuid_val_); |
1596 | 3.36G | case ValueType::kColumnId: FALLTHROUGH_INTENDED; |
1597 | 3.36G | case ValueType::kSystemColumnId: |
1598 | 3.36G | return CompareUsingLessThan(column_id_val_, other.column_id_val_); |
1599 | 0 | case ValueType::kHybridTime: |
1600 | | // HybridTimes are sorted in reverse order when wrapped in a PrimitiveValue. |
1601 | 0 | return -hybrid_time_val_.CompareTo(other.hybrid_time_val_); |
1602 | 0 | case ValueType::kGinNull: |
1603 | 0 | return CompareUsingLessThan(gin_null_val_, other.gin_null_val_); |
1604 | 0 | IGNORE_NON_PRIMITIVE_VALUE_TYPES_IN_SWITCH; |
1605 | 3.43G | } |
1606 | 0 | LOG(FATAL) << "Comparing invalid PrimitiveValues: " << *this << " and " << other; |
1607 | 0 | } |
1608 | | |
1609 | 932M | PrimitiveValue::PrimitiveValue() : type_(ValueType::kNullLow) { |
1610 | 932M | } |
1611 | | |
1612 | | // This is used to initialize kNullLow, kNullHigh, kTrue, kFalse constants. |
1613 | | PrimitiveValue::PrimitiveValue(ValueType value_type) |
1614 | 360M | : type_(value_type) { |
1615 | 360M | complex_data_structure_ = nullptr; |
1616 | 361M | if (value_type == ValueType::kString || value_type == ValueType::kStringDescending) { |
1617 | 15 | new(&str_val_) std::string(); |
1618 | 360M | } else if (value_type == ValueType::kInetaddress |
1619 | 361M | || value_type == ValueType::kInetaddressDescending) { |
1620 | 0 | inetaddress_val_ = new InetAddress(); |
1621 | 361M | } else if (value_type == ValueType::kDecimal || value_type == ValueType::kDecimalDescending) { |
1622 | 0 | new(&decimal_val_) std::string(); |
1623 | 360M | } else if (value_type == ValueType::kUuid || value_type == ValueType::kUuidDescending) { |
1624 | 0 | new(&uuid_val_) Uuid(); |
1625 | 360M | } else if (value_type == ValueType::kFrozen || value_type == ValueType::kFrozenDescending) { |
1626 | 646 | frozen_val_ = new FrozenContainer(); |
1627 | 360M | } else if (value_type == ValueType::kJsonb) { |
1628 | 0 | new(&json_val_) std::string(); |
1629 | 0 | } |
1630 | 360M | } |
1631 | | |
1632 | 691M | PrimitiveValue::PrimitiveValue(const PrimitiveValue& other) { |
1633 | 691M | if (other.IsString()) { |
1634 | 50.4M | type_ = other.type_; |
1635 | 50.4M | new(&str_val_) std::string(other.str_val_); |
1636 | 641M | } else if (other.type_ == ValueType::kJsonb) { |
1637 | 28.7k | type_ = other.type_; |
1638 | 28.7k | new(&json_val_) std::string(other.json_val_); |
1639 | 641M | } else if (other.type_ == ValueType::kInetaddress |
1640 | 640M | || other.type_ == ValueType::kInetaddressDescending) { |
1641 | 2.62k | type_ = other.type_; |
1642 | 2.62k | inetaddress_val_ = new InetAddress(*(other.inetaddress_val_)); |
1643 | 641M | } else if (other.type_ == ValueType::kDecimal || other.type_ == ValueType::kDecimalDescending) { |
1644 | 29.9k | type_ = other.type_; |
1645 | 29.9k | new(&decimal_val_) std::string(other.decimal_val_); |
1646 | 642M | } else if (other.type_ == ValueType::kVarInt || other.type_ == ValueType::kVarIntDescending) { |
1647 | 18.2k | type_ = other.type_; |
1648 | 18.2k | new(&varint_val_) std::string(other.varint_val_); |
1649 | 641M | } else if (other.type_ == ValueType::kUuid || other.type_ == ValueType::kUuidDescending) { |
1650 | 10.3k | type_ = other.type_; |
1651 | 10.3k | new(&uuid_val_) Uuid(std::move((other.uuid_val_))); |
1652 | 641M | } else if (other.type_ == ValueType::kFrozen || other.type_ == ValueType::kFrozenDescending ) { |
1653 | 4.03k | type_ = other.type_; |
1654 | 4.03k | frozen_val_ = new FrozenContainer(*(other.frozen_val_)); |
1655 | 641M | } else { |
1656 | 641M | memmove(static_cast<void*>(this), &other, sizeof(PrimitiveValue)); |
1657 | 641M | } |
1658 | 691M | ttl_seconds_ = other.ttl_seconds_; |
1659 | 691M | write_time_ = other.write_time_; |
1660 | 691M | } |
1661 | | |
1662 | 0 | PrimitiveValue::PrimitiveValue(const Slice& s, SortOrder sort_order, bool is_collate) { |
1663 | 0 | if (sort_order == SortOrder::kDescending) { |
1664 | 0 | type_ = is_collate ? ValueType::kCollStringDescending : ValueType::kStringDescending; |
1665 | 0 | } else { |
1666 | 0 | type_ = is_collate ? ValueType::kCollString : ValueType::kString; |
1667 | 0 | } |
1668 | 0 | new(&str_val_) std::string(s.cdata(), s.cend()); |
1669 | 0 | } |
1670 | | |
1671 | 13.9M | PrimitiveValue::PrimitiveValue(const std::string& s, SortOrder sort_order, bool is_collate) { |
1672 | 13.9M | if (sort_order == SortOrder::kDescending) { |
1673 | 21.7k | type_ = is_collate ? ValueType::kCollStringDescending : ValueType::kStringDescending; |
1674 | 13.8M | } else { |
1675 | 13.8M | type_ = is_collate ? ValueType::kCollString : ValueType::kString; |
1676 | 13.8M | } |
1677 | 13.9M | new(&str_val_) std::string(s); |
1678 | 13.9M | } |
1679 | | |
1680 | 0 | PrimitiveValue::PrimitiveValue(const char* s, SortOrder sort_order, bool is_collate) { |
1681 | 0 | if (sort_order == SortOrder::kDescending) { |
1682 | 0 | type_ = is_collate ? ValueType::kCollStringDescending : ValueType::kStringDescending; |
1683 | 0 | } else { |
1684 | 0 | type_ = is_collate ? ValueType::kCollString : ValueType::kString; |
1685 | 0 | } |
1686 | 0 | new(&str_val_) std::string(s); |
1687 | 0 | } |
1688 | | |
1689 | 977k | PrimitiveValue::PrimitiveValue(int64_t v, SortOrder sort_order) { |
1690 | 977k | if (sort_order == SortOrder::kDescending) { |
1691 | 26.9k | type_ = ValueType::kInt64Descending; |
1692 | 950k | } else { |
1693 | 950k | type_ = ValueType::kInt64; |
1694 | 950k | } |
1695 | | // Avoid using an initializer for a union field (got surprising and unexpected results with |
1696 | | // that approach). Use a direct assignment instead. |
1697 | 977k | int64_val_ = v; |
1698 | 977k | } |
1699 | | |
1700 | 672k | PrimitiveValue::PrimitiveValue(const Timestamp& timestamp, SortOrder sort_order) { |
1701 | 672k | if (sort_order == SortOrder::kDescending) { |
1702 | 671k | type_ = ValueType::kTimestampDescending; |
1703 | 1.61k | } else { |
1704 | 1.61k | type_ = ValueType::kTimestamp; |
1705 | 1.61k | } |
1706 | 672k | timestamp_val_ = timestamp; |
1707 | 672k | } |
1708 | | |
1709 | 320 | PrimitiveValue::PrimitiveValue(const InetAddress& inetaddress, SortOrder sort_order) { |
1710 | 320 | if (sort_order == SortOrder::kDescending) { |
1711 | 234 | type_ = ValueType::kInetaddressDescending; |
1712 | 86 | } else { |
1713 | 86 | type_ = ValueType::kInetaddress; |
1714 | 86 | } |
1715 | 320 | inetaddress_val_ = new InetAddress(inetaddress); |
1716 | 320 | } |
1717 | | |
1718 | 1.15k | PrimitiveValue::PrimitiveValue(const Uuid& uuid, SortOrder sort_order) { |
1719 | 1.15k | if (sort_order == SortOrder::kDescending) { |
1720 | 822 | type_ = ValueType::kUuidDescending; |
1721 | 330 | } else { |
1722 | 330 | type_ = ValueType::kUuid; |
1723 | 330 | } |
1724 | 1.15k | uuid_val_ = uuid; |
1725 | 1.15k | } |
1726 | | |
1727 | 0 | PrimitiveValue::PrimitiveValue(const HybridTime& hybrid_time) : type_(ValueType::kHybridTime) { |
1728 | 0 | hybrid_time_val_ = DocHybridTime(hybrid_time); |
1729 | 0 | } |
1730 | | |
1731 | | PrimitiveValue::PrimitiveValue(const DocHybridTime& hybrid_time) |
1732 | | : type_(ValueType::kHybridTime), |
1733 | 0 | hybrid_time_val_(hybrid_time) { |
1734 | 0 | } |
1735 | | |
1736 | 242M | PrimitiveValue::PrimitiveValue(const ColumnId column_id) : type_(ValueType::kColumnId) { |
1737 | 242M | column_id_val_ = column_id; |
1738 | 242M | } |
1739 | | |
1740 | 3.50G | PrimitiveValue::~PrimitiveValue() { |
1741 | 3.50G | if (IsString()) { |
1742 | 263M | str_val_.~basic_string(); |
1743 | 3.24G | } else if (type_ == ValueType::kJsonb) { |
1744 | 99.7k | json_val_.~basic_string(); |
1745 | 3.24G | } else if (type_ == ValueType::kInetaddress || type_ == ValueType::kInetaddressDescending) { |
1746 | 5.98k | delete inetaddress_val_; |
1747 | 3.24G | } else if (type_ == ValueType::kDecimal || type_ == ValueType::kDecimalDescending) { |
1748 | 172k | decimal_val_.~basic_string(); |
1749 | 3.24G | } else if (type_ == ValueType::kVarInt || type_ == ValueType::kVarIntDescending) { |
1750 | 116k | varint_val_.~basic_string(); |
1751 | 3.24G | } else if (type_ == ValueType::kFrozen) { |
1752 | 7.10k | delete frozen_val_; |
1753 | 7.10k | } |
1754 | | // HybridTime does not need its destructor to be called, because it is a simple wrapper over an |
1755 | | // unsigned 64-bit integer. |
1756 | 3.50G | } |
1757 | | |
1758 | 298k | PrimitiveValue PrimitiveValue::NullValue(SortingType sorting) { |
1759 | 298k | using SortingType = SortingType; |
1760 | | |
1761 | 298k | return PrimitiveValue( |
1762 | 298k | sorting == SortingType::kAscendingNullsLast || sorting == SortingType::kDescendingNullsLast |
1763 | 37 | ? ValueType::kNullHigh |
1764 | 298k | : ValueType::kNullLow); |
1765 | 298k | } |
1766 | | |
1767 | 0 | DocHybridTime PrimitiveValue::hybrid_time() const { |
1768 | 0 | DCHECK(type_ == ValueType::kHybridTime); |
1769 | 0 | return hybrid_time_val_; |
1770 | 0 | } |
1771 | | |
1772 | 34.7k | bool PrimitiveValue::IsPrimitive() const { |
1773 | 34.7k | return IsPrimitiveValueType(type_); |
1774 | 34.7k | } |
1775 | | |
1776 | 30.5M | bool PrimitiveValue::IsTombstoneOrPrimitive() const { |
1777 | 30.5M | return IsPrimitiveValueType(type_) || type_ == ValueType::kTombstone; |
1778 | 30.5M | } |
1779 | | |
1780 | 0 | bool PrimitiveValue::IsInfinity() const { |
1781 | 0 | return type_ == ValueType::kHighest || type_ == ValueType::kLowest; |
1782 | 0 | } |
1783 | | |
1784 | 0 | bool PrimitiveValue::IsInt64() const { |
1785 | 0 | return ValueType::kInt64 == type_ || ValueType::kInt64Descending == type_; |
1786 | 0 | } |
1787 | | |
1788 | 4.95G | bool PrimitiveValue::IsString() const { |
1789 | 4.95G | return ValueType::kString == type_ || ValueType::kStringDescending == type_ || |
1790 | 4.52G | ValueType::kCollString == type_ || ValueType::kCollStringDescending == type_; |
1791 | 4.95G | } |
1792 | | |
1793 | 1.47M | bool PrimitiveValue::IsDouble() const { |
1794 | 1.47M | return ValueType::kDouble == type_ || ValueType::kDoubleDescending == type_; |
1795 | 1.47M | } |
1796 | | |
1797 | 101M | int32_t PrimitiveValue::GetInt32() const { |
1798 | 101M | DCHECK(ValueType::kInt32 == type_ || ValueType::kInt32Descending == type_); |
1799 | 101M | return int32_val_; |
1800 | 101M | } |
1801 | | |
1802 | 53.7M | uint32_t PrimitiveValue::GetUInt32() const { |
1803 | 53.7M | DCHECK(ValueType::kUInt32 == type_ || ValueType::kUInt32Descending == type_); |
1804 | 53.7M | return uint32_val_; |
1805 | 53.7M | } |
1806 | | |
1807 | 4.75M | int64_t PrimitiveValue::GetInt64() const { |
1808 | 4.75M | DCHECK(ValueType::kInt64 == type_ || ValueType::kInt64Descending == type_); |
1809 | 4.75M | return int64_val_; |
1810 | 4.75M | } |
1811 | | |
1812 | 0 | uint64_t PrimitiveValue::GetUInt64() const { |
1813 | 0 | DCHECK(ValueType::kUInt64 == type_ || ValueType::kUInt64Descending == type_); |
1814 | 0 | return uint64_val_; |
1815 | 0 | } |
1816 | | |
1817 | 0 | uint16_t PrimitiveValue::GetUInt16() const { |
1818 | 0 | DCHECK(ValueType::kUInt16Hash == type_ || |
1819 | 0 | ValueType::kObsoleteIntentTypeSet == type_ || |
1820 | 0 | ValueType::kObsoleteIntentType == type_ || |
1821 | 0 | ValueType::kIntentTypeSet == type_); |
1822 | 0 | return uint16_val_; |
1823 | 0 | } |
1824 | | |
1825 | 825k | float PrimitiveValue::GetFloat() const { |
1826 | 825k | DCHECK(ValueType::kFloat == type_ || ValueType::kFloatDescending == type_); |
1827 | 825k | return float_val_; |
1828 | 825k | } |
1829 | | |
1830 | 30.1k | const std::string& PrimitiveValue::GetDecimal() const { |
1831 | 30.1k | DCHECK(ValueType::kDecimal == type_ || ValueType::kDecimalDescending == type_); |
1832 | 30.1k | return decimal_val_; |
1833 | 30.1k | } |
1834 | | |
1835 | 21.4k | const std::string& PrimitiveValue::GetVarInt() const { |
1836 | 21.4k | DCHECK(ValueType::kVarInt == type_ || ValueType::kVarIntDescending == type_); |
1837 | 21.4k | return varint_val_; |
1838 | 21.4k | } |
1839 | | |
1840 | 3.60M | Timestamp PrimitiveValue::GetTimestamp() const { |
1841 | 3.60M | DCHECK(ValueType::kTimestamp == type_ || ValueType::kTimestampDescending == type_); |
1842 | 3.60M | return timestamp_val_; |
1843 | 3.60M | } |
1844 | | |
1845 | 146 | const InetAddress* PrimitiveValue::GetInetaddress() const { |
1846 | 146 | DCHECK(type_ == ValueType::kInetaddress || type_ == ValueType::kInetaddressDescending); |
1847 | 146 | return inetaddress_val_; |
1848 | 146 | } |
1849 | | |
1850 | 13.8k | const std::string& PrimitiveValue::GetJson() const { |
1851 | 13.8k | DCHECK(type_ == ValueType::kJsonb); |
1852 | 13.8k | return json_val_; |
1853 | 13.8k | } |
1854 | | |
1855 | 850 | const Uuid& PrimitiveValue::GetUuid() const { |
1856 | 850 | DCHECK(type_ == ValueType::kUuid || type_ == ValueType::kUuidDescending || |
1857 | 850 | type_ == ValueType::kTransactionId || type_ == ValueType::kTableId); |
1858 | 850 | return uuid_val_; |
1859 | 850 | } |
1860 | | |
1861 | 670 | ColumnId PrimitiveValue::GetColumnId() const { |
1862 | 670 | DCHECK(type_ == ValueType::kColumnId || type_ == ValueType::kSystemColumnId); |
1863 | 670 | return column_id_val_; |
1864 | 670 | } |
1865 | | |
1866 | 0 | uint8_t PrimitiveValue::GetGinNull() const { |
1867 | 0 | DCHECK(ValueType::kGinNull == type_); |
1868 | 0 | return gin_null_val_; |
1869 | 0 | } |
1870 | | |
1871 | 746M | void PrimitiveValue::MoveFrom(PrimitiveValue* other) { |
1872 | 746M | if (this == other) { |
1873 | 0 | return; |
1874 | 0 | } |
1875 | | |
1876 | 746M | ttl_seconds_ = other->ttl_seconds_; |
1877 | 746M | write_time_ = other->write_time_; |
1878 | 746M | if (other->IsString()) { |
1879 | 85.4M | type_ = other->type_; |
1880 | 85.4M | new(&str_val_) std::string(std::move(other->str_val_)); |
1881 | | // The moved-from object should now be in a "valid but unspecified" state as per the standard. |
1882 | 660M | } else if (other->type_ == ValueType::kInetaddress |
1883 | 662M | || other->type_ == ValueType::kInetaddressDescending) { |
1884 | 324 | type_ = other->type_; |
1885 | 324 | inetaddress_val_ = new InetAddress(std::move(*(other->inetaddress_val_))); |
1886 | 660M | } else if (other->type_ == ValueType::kJsonb) { |
1887 | 49.3k | type_ = other->type_; |
1888 | 49.3k | new(&json_val_) std::string(std::move(other->json_val_)); |
1889 | 660M | } else if (other->type_ == ValueType::kDecimal || |
1890 | 662M | other->type_ == ValueType::kDecimalDescending) { |
1891 | 29.7k | type_ = other->type_; |
1892 | 29.7k | new(&decimal_val_) std::string(std::move(other->decimal_val_)); |
1893 | 660M | } else if (other->type_ == ValueType::kVarInt || |
1894 | 661M | other->type_ == ValueType::kVarIntDescending) { |
1895 | 4.24k | type_ = other->type_; |
1896 | 4.24k | new(&varint_val_) std::string(std::move(other->varint_val_)); |
1897 | 661M | } else if (other->type_ == ValueType::kUuid || other->type_ == ValueType::kUuidDescending) { |
1898 | 1.30k | type_ = other->type_; |
1899 | 1.30k | new(&uuid_val_) Uuid(std::move((other->uuid_val_))); |
1900 | 660M | } else if (other->type_ == ValueType::kFrozen) { |
1901 | 786 | type_ = other->type_; |
1902 | 786 | frozen_val_ = new FrozenContainer(std::move(*(other->frozen_val_))); |
1903 | 660M | } else { |
1904 | | // Non-string primitive values only have plain old data. We are assuming there is no overlap |
1905 | | // between the two objects, so we're using memcpy instead of memmove. |
1906 | 660M | memcpy(static_cast<void*>(this), other, sizeof(PrimitiveValue)); |
1907 | 660M | #ifndef NDEBUG |
1908 | | // We could just leave the old object as is for it to be in a "valid but unspecified" state. |
1909 | | // However, in debug mode we clear the old object's state to make sure we don't attempt to use |
1910 | | // it. |
1911 | 660M | memset(static_cast<void*>(other), 0xab, sizeof(PrimitiveValue)); |
1912 | | // Restore the type. There should be no deallocation for non-string types anyway. |
1913 | 660M | other->type_ = ValueType::kNullLow; |
1914 | 660M | #endif |
1915 | 660M | } |
1916 | 746M | } |
1917 | | |
1918 | | SortOrder PrimitiveValue::SortOrderFromColumnSchemaSortingType( |
1919 | 35.6M | SortingType sorting_type) { |
1920 | 35.6M | if (sorting_type == SortingType::kDescending || |
1921 | 34.9M | sorting_type == SortingType::kDescendingNullsLast) { |
1922 | 701k | return SortOrder::kDescending; |
1923 | 701k | } |
1924 | 34.9M | return SortOrder::kAscending; |
1925 | 34.9M | } |
1926 | | |
1927 | | PrimitiveValue PrimitiveValue::FromQLValuePB(const QLValuePB& value, |
1928 | 35.2M | SortingType sorting_type) { |
1929 | 35.2M | const auto sort_order = SortOrderFromColumnSchemaSortingType(sorting_type); |
1930 | | |
1931 | 35.2M | switch (value.value_case()) { |
1932 | 1.25M | case QLValuePB::kInt8Value: |
1933 | 1.25M | return PrimitiveValue::Int32(value.int8_value(), sort_order); |
1934 | 456k | case QLValuePB::kInt16Value: |
1935 | 456k | return PrimitiveValue::Int32(value.int16_value(), sort_order); |
1936 | 12.2M | case QLValuePB::kInt32Value: |
1937 | 12.2M | return PrimitiveValue::Int32(value.int32_value(), sort_order); |
1938 | 940k | case QLValuePB::kInt64Value: |
1939 | 940k | return PrimitiveValue(value.int64_value(), sort_order); |
1940 | 4.70M | case QLValuePB::kUint32Value: |
1941 | 4.70M | return PrimitiveValue::UInt32(value.uint32_value(), sort_order); |
1942 | 0 | case QLValuePB::kUint64Value: |
1943 | 0 | return PrimitiveValue::UInt64(value.uint64_value(), sort_order); |
1944 | 136k | case QLValuePB::kFloatValue: { |
1945 | 136k | float f = value.float_value(); |
1946 | 136k | return PrimitiveValue::Float(util::CanonicalizeFloat(f), sort_order); |
1947 | 0 | } |
1948 | 172k | case QLValuePB::kDoubleValue: { |
1949 | 172k | double d = value.double_value(); |
1950 | 172k | return PrimitiveValue::Double(util::CanonicalizeDouble(d), sort_order); |
1951 | 0 | } |
1952 | 4.60k | case QLValuePB::kDecimalValue: |
1953 | 4.60k | return PrimitiveValue::Decimal(value.decimal_value(), sort_order); |
1954 | 3.63k | case QLValuePB::kVarintValue: |
1955 | 3.63k | return PrimitiveValue::VarInt(value.varint_value(), sort_order); |
1956 | 9.76M | case QLValuePB::kStringValue: { |
1957 | 9.76M | const string& val = value.string_value(); |
1958 | | // In both Postgres and YCQL, character value cannot have embedded \0 byte. |
1959 | | // Redis allows embedded \0 byte but it does not use QLValuePB so will not |
1960 | | // come here to pick up 'is_collate'. Therefore, if the value is not empty |
1961 | | // and the first byte is \0, it indicates this is a collation encoded string. |
1962 | 9.76M | if (!val.empty() && val[0] == '\0') { |
1963 | | // An empty collation encoded string is at least 3 bytes. |
1964 | 0 | CHECK_GE(val.size(), 3); |
1965 | 0 | return PrimitiveValue(val, sort_order, true /* is_collate */); |
1966 | 0 | } |
1967 | 9.76M | return PrimitiveValue(val, sort_order); |
1968 | 9.76M | } |
1969 | 2.66M | case QLValuePB::kBinaryValue: |
1970 | | // TODO consider using dedicated encoding for binary (not string) to avoid overhead of |
1971 | | // zero-encoding for keys (since zero-bytes could be common for binary) |
1972 | 2.66M | return PrimitiveValue(value.binary_value(), sort_order); |
1973 | 973k | case QLValuePB::kBoolValue: |
1974 | 973k | return PrimitiveValue(sort_order == SortOrder::kDescending |
1975 | 12 | ? (value.bool_value() ? ValueType::kTrueDescending |
1976 | 6 | : ValueType::kFalseDescending) |
1977 | 973k | : (value.bool_value() ? ValueType::kTrue |
1978 | 628k | : ValueType::kFalse)); |
1979 | 673k | case QLValuePB::kTimestampValue: |
1980 | 673k | return PrimitiveValue(QLValue::timestamp_value(value), sort_order); |
1981 | 376 | case QLValuePB::kDateValue: |
1982 | 376 | return PrimitiveValue::UInt32(value.date_value(), sort_order); |
1983 | 394 | case QLValuePB::kTimeValue: |
1984 | 394 | return PrimitiveValue(value.time_value(), sort_order); |
1985 | 320 | case QLValuePB::kInetaddressValue: |
1986 | 320 | return PrimitiveValue(QLValue::inetaddress_value(value), sort_order); |
1987 | 7.41k | case QLValuePB::kJsonbValue: |
1988 | 7.41k | return PrimitiveValue::Jsonb(QLValue::jsonb_value(value)); |
1989 | 858 | case QLValuePB::kUuidValue: |
1990 | 858 | return PrimitiveValue(QLValue::uuid_value(value), sort_order); |
1991 | 294 | case QLValuePB::kTimeuuidValue: |
1992 | 294 | return PrimitiveValue(QLValue::timeuuid_value(value), sort_order); |
1993 | 646 | case QLValuePB::kFrozenValue: { |
1994 | 646 | QLSeqValuePB frozen = value.frozen_value(); |
1995 | 646 | PrimitiveValue pv(ValueType::kFrozen); |
1996 | 646 | auto null_value_type = ValueType::kNullLow; |
1997 | 646 | if (sort_order == SortOrder::kDescending) { |
1998 | 108 | null_value_type = ValueType::kNullHigh; |
1999 | 108 | pv.type_ = ValueType::kFrozenDescending; |
2000 | 108 | } |
2001 | | |
2002 | 2.00k | for (int i = 0; i < frozen.elems_size(); i++) { |
2003 | 1.36k | if (IsNull(frozen.elems(i))) { |
2004 | 111 | pv.frozen_val_->emplace_back(null_value_type); |
2005 | 1.25k | } else { |
2006 | 1.25k | pv.frozen_val_->push_back(PrimitiveValue::FromQLValuePB(frozen.elems(i), sorting_type)); |
2007 | 1.25k | } |
2008 | 1.36k | } |
2009 | 646 | return pv; |
2010 | 9.76M | } |
2011 | 1.28M | case QLValuePB::VALUE_NOT_SET: |
2012 | 1.28M | return PrimitiveValue::kTombstone; |
2013 | | |
2014 | 0 | case QLValuePB::kMapValue: FALLTHROUGH_INTENDED; |
2015 | 0 | case QLValuePB::kSetValue: FALLTHROUGH_INTENDED; |
2016 | 0 | case QLValuePB::kListValue: |
2017 | 0 | break; |
2018 | |
|
2019 | 8 | case QLValuePB::kVirtualValue: |
2020 | 8 | return PrimitiveValue(value.virtual_value() == QLVirtualValuePB::LIMIT_MAX ? |
2021 | 0 | docdb::ValueType::kHighest : |
2022 | 8 | docdb::ValueType::kLowest); |
2023 | 351 | case QLValuePB::kGinNullValue: |
2024 | 351 | return PrimitiveValue::GinNull(value.gin_null_value()); |
2025 | | |
2026 | | // default: fall through |
2027 | 0 | } |
2028 | | |
2029 | 0 | LOG(FATAL) << "Unsupported datatype in PrimitiveValue: " << value.value_case(); |
2030 | 0 | } |
2031 | | |
2032 | | void PrimitiveValue::ToQLValuePB(const PrimitiveValue& primitive_value, |
2033 | | const std::shared_ptr<QLType>& ql_type, |
2034 | 265M | QLValuePB* ql_value) { |
2035 | | // DocDB sets type to kInvalidValueType for SubDocuments that don't exist. That's why they need |
2036 | | // to be set to Null in QLValue. |
2037 | 265M | if (primitive_value.value_type() == ValueType::kNullLow || |
2038 | 265M | primitive_value.value_type() == ValueType::kNullHigh || |
2039 | 265M | primitive_value.value_type() == ValueType::kInvalid || |
2040 | 265M | primitive_value.value_type() == ValueType::kTombstone) { |
2041 | 22.1M | SetNull(ql_value); |
2042 | 22.1M | return; |
2043 | 22.1M | } |
2044 | | |
2045 | | // For ybgin indexes, null category can be set on any index key column, regardless of the column's |
2046 | | // actual type. The column's actual type cannot be kGinNull, so it throws error in the below |
2047 | | // switch. |
2048 | 243M | if (primitive_value.value_type() == ValueType::kGinNull) { |
2049 | 0 | ql_value->set_gin_null_value(primitive_value.GetGinNull()); |
2050 | 0 | return; |
2051 | 0 | } |
2052 | | |
2053 | 243M | switch (ql_type->main()) { |
2054 | 22.5M | case INT8: |
2055 | 22.5M | ql_value->set_int8_value(static_cast<int8_t>(primitive_value.GetInt32())); |
2056 | 22.5M | return; |
2057 | 12.9M | case INT16: |
2058 | 12.9M | ql_value->set_int16_value(static_cast<int16_t>(primitive_value.GetInt32())); |
2059 | 12.9M | return; |
2060 | 64.9M | case INT32: |
2061 | 64.9M | ql_value->set_int32_value(primitive_value.GetInt32()); |
2062 | 64.9M | return; |
2063 | 3.81M | case INT64: |
2064 | 3.81M | ql_value->set_int64_value(primitive_value.GetInt64()); |
2065 | 3.81M | return; |
2066 | 53.7M | case UINT32: |
2067 | 53.7M | ql_value->set_uint32_value(primitive_value.GetUInt32()); |
2068 | 53.7M | return; |
2069 | 0 | case UINT64: |
2070 | 0 | ql_value->set_uint64_value(primitive_value.GetUInt64()); |
2071 | 0 | return; |
2072 | 825k | case FLOAT: |
2073 | 825k | ql_value->set_float_value(primitive_value.GetFloat()); |
2074 | 825k | return; |
2075 | 1.47M | case DOUBLE: |
2076 | 1.47M | ql_value->set_double_value(primitive_value.GetDouble()); |
2077 | 1.47M | return; |
2078 | 30.1k | case DECIMAL: |
2079 | 30.1k | ql_value->set_decimal_value(primitive_value.GetDecimal()); |
2080 | 30.1k | return; |
2081 | 21.4k | case VARINT: |
2082 | 21.4k | ql_value->set_varint_value(primitive_value.GetVarInt()); |
2083 | 21.4k | return; |
2084 | 37.7M | case BOOL: |
2085 | 37.7M | ql_value->set_bool_value(primitive_value.value_type() == ValueType::kTrue || |
2086 | 25.3M | primitive_value.value_type() == ValueType::kTrueDescending); |
2087 | 37.7M | return; |
2088 | 3.60M | case TIMESTAMP: |
2089 | 3.60M | ql_value->set_timestamp_value(primitive_value.GetTimestamp().ToInt64()); |
2090 | 3.60M | return; |
2091 | 458 | case DATE: |
2092 | 458 | ql_value->set_date_value(primitive_value.GetUInt32()); |
2093 | 458 | return; |
2094 | 442 | case TIME: |
2095 | 442 | ql_value->set_time_value(primitive_value.GetInt64()); |
2096 | 442 | return; |
2097 | 146 | case INET: { |
2098 | 146 | QLValue temp_value; |
2099 | 146 | temp_value.set_inetaddress_value(*primitive_value.GetInetaddress()); |
2100 | 146 | *ql_value = std::move(*temp_value.mutable_value()); |
2101 | 146 | return; |
2102 | 0 | } |
2103 | 13.8k | case JSONB: { |
2104 | 13.8k | QLValue temp_value; |
2105 | 13.8k | temp_value.set_jsonb_value(primitive_value.GetJson()); |
2106 | 13.8k | *ql_value = std::move(*temp_value.mutable_value()); |
2107 | 13.8k | return; |
2108 | 0 | } |
2109 | 666 | case UUID: { |
2110 | 666 | QLValue temp_value; |
2111 | 666 | temp_value.set_uuid_value(primitive_value.GetUuid()); |
2112 | 666 | *ql_value = std::move(*temp_value.mutable_value()); |
2113 | 666 | return; |
2114 | 0 | } |
2115 | 184 | case TIMEUUID: { |
2116 | 184 | QLValue temp_value; |
2117 | 184 | temp_value.set_timeuuid_value(primitive_value.GetUuid()); |
2118 | 184 | *ql_value = std::move(*temp_value.mutable_value()); |
2119 | 184 | return; |
2120 | 0 | } |
2121 | 30.1M | case STRING: |
2122 | 30.1M | ql_value->set_string_value(primitive_value.GetString()); |
2123 | 30.1M | return; |
2124 | 11.8M | case BINARY: |
2125 | 11.8M | ql_value->set_binary_value(primitive_value.GetString()); |
2126 | 11.8M | return; |
2127 | 499 | case FROZEN: { |
2128 | 499 | const auto& type = ql_type->param_type(0); |
2129 | 499 | QLSeqValuePB *frozen_value = ql_value->mutable_frozen_value(); |
2130 | 499 | frozen_value->clear_elems(); |
2131 | 499 | switch (type->main()) { |
2132 | 67 | case MAP: { |
2133 | 67 | const std::shared_ptr<QLType>& keys_type = type->param_type(0); |
2134 | 67 | const std::shared_ptr<QLType>& values_type = type->param_type(1); |
2135 | 277 | for (size_t i = 0; i < primitive_value.frozen_val_->size(); i++) { |
2136 | 210 | if (i % 2 == 0) { |
2137 | 105 | QLValuePB *key = frozen_value->add_elems(); |
2138 | 105 | PrimitiveValue::ToQLValuePB((*primitive_value.frozen_val_)[i], keys_type, key); |
2139 | 105 | } else { |
2140 | 105 | QLValuePB *value = frozen_value->add_elems(); |
2141 | 105 | PrimitiveValue::ToQLValuePB((*primitive_value.frozen_val_)[i], values_type, value); |
2142 | 105 | } |
2143 | 210 | } |
2144 | 67 | return; |
2145 | 0 | } |
2146 | 90 | case SET: FALLTHROUGH_INTENDED; |
2147 | 163 | case LIST: { |
2148 | 163 | const std::shared_ptr<QLType>& elems_type = type->param_type(0); |
2149 | 293 | for (const auto &pv : *primitive_value.frozen_val_) { |
2150 | 293 | QLValuePB *elem = frozen_value->add_elems(); |
2151 | 293 | PrimitiveValue::ToQLValuePB(pv, elems_type, elem); |
2152 | 293 | } |
2153 | 163 | return; |
2154 | 90 | } |
2155 | 269 | case USER_DEFINED_TYPE: { |
2156 | 823 | for (size_t i = 0; i < primitive_value.frozen_val_->size(); i++) { |
2157 | 554 | QLValuePB *value = frozen_value->add_elems(); |
2158 | 554 | PrimitiveValue::ToQLValuePB( |
2159 | 554 | (*primitive_value.frozen_val_)[i], type->param_type(i), value); |
2160 | 554 | } |
2161 | 269 | return; |
2162 | 90 | } |
2163 | | |
2164 | 0 | default: |
2165 | 0 | break; |
2166 | 0 | } |
2167 | 0 | FATAL_INVALID_ENUM_VALUE(DataType, type->main()); |
2168 | 0 | } |
2169 | |
|
2170 | 0 | case NULL_VALUE_TYPE: FALLTHROUGH_INTENDED; |
2171 | 0 | case MAP: FALLTHROUGH_INTENDED; |
2172 | 0 | case SET: FALLTHROUGH_INTENDED; |
2173 | 0 | case LIST: FALLTHROUGH_INTENDED; |
2174 | 0 | case TUPLE: FALLTHROUGH_INTENDED; |
2175 | 0 | case TYPEARGS: FALLTHROUGH_INTENDED; |
2176 | 0 | case USER_DEFINED_TYPE: FALLTHROUGH_INTENDED; |
2177 | |
|
2178 | 0 | case UINT8: FALLTHROUGH_INTENDED; |
2179 | 0 | case UINT16: FALLTHROUGH_INTENDED; |
2180 | 0 | case UNKNOWN_DATA: FALLTHROUGH_INTENDED; |
2181 | 0 | case GIN_NULL: |
2182 | 0 | break; |
2183 | | |
2184 | | // default: fall through |
2185 | 0 | } |
2186 | | |
2187 | 0 | LOG(FATAL) << "Unsupported datatype " << ql_type->ToString(); |
2188 | 0 | } |
2189 | | |
2190 | | } // namespace docdb |
2191 | | } // namespace yb |