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