YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

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