YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/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