YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/docdb/primitive_value.h
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
#ifndef YB_DOCDB_PRIMITIVE_VALUE_H_
15
#define YB_DOCDB_PRIMITIVE_VALUE_H_
16
17
#include <ostream>
18
#include <string>
19
#include <vector>
20
21
#include <glog/logging.h>
22
23
#include "yb/common/common_fwd.h"
24
#include "yb/common/column_id.h"
25
#include "yb/common/doc_hybrid_time.h"
26
#include "yb/common/hybrid_time.h"
27
28
#include "yb/docdb/docdb_fwd.h"
29
30
#include "yb/util/algorithm_util.h"
31
#include "yb/util/net/inetaddress.h"
32
#include "yb/util/slice.h"
33
#include "yb/util/strongly_typed_bool.h"
34
#include "yb/util/timestamp.h"
35
#include "yb/util/uuid.h"
36
37
namespace yb {
38
namespace docdb {
39
40
// Used for extending a list.
41
// PREPEND prepends the arguments one by one (PREPEND a b c) will prepend [c b a] to the list,
42
// while PREPEND_BLOCK prepends the arguments together, so it will prepend [a b c] to the list.
43
YB_DEFINE_ENUM(ListExtendOrder, (APPEND)(PREPEND_BLOCK)(PREPEND))
44
45
// A necessary use of a forward declaration to avoid circular inclusion.
46
class SubDocument;
47
48
enum class SystemColumnIds : ColumnIdRep {
49
  kLivenessColumn = 0  // Stores the TTL for QL rows inserted using an INSERT statement.
50
};
51
52
class PrimitiveValue {
53
 public:
54
  static const PrimitiveValue kInvalid;
55
  static const PrimitiveValue kTombstone;
56
  static const PrimitiveValue kObject;
57
  static const PrimitiveValue kLivenessColumn;
58
59
  PrimitiveValue();
60
  explicit PrimitiveValue(ValueType value_type);
61
62
  PrimitiveValue(const PrimitiveValue& other);
63
64
2.06G
  PrimitiveValue(PrimitiveValue&& other) {
65
2.06G
    MoveFrom(&other);
66
2.06G
  }
67
68
104
  PrimitiveValue& operator =(const PrimitiveValue& other) {
69
104
    this->~PrimitiveValue();
70
104
    new(this) PrimitiveValue(other);
71
104
    return *this;
72
104
  }
73
74
58.1M
  PrimitiveValue& operator =(PrimitiveValue&& other) {
75
58.1M
    this->~PrimitiveValue();
76
58.1M
    MoveFrom(&other);
77
58.1M
    return *this;
78
58.1M
  }
79
80
  explicit PrimitiveValue(const Slice& s,
81
                          SortOrder sort_order = SortOrder::kAscending,
82
                          bool is_collate = false);
83
84
  explicit PrimitiveValue(const std::string& s,
85
                          SortOrder sort_order = SortOrder::kAscending,
86
                          bool is_collate = false);
87
88
  explicit PrimitiveValue(const char* s,
89
                          SortOrder sort_order = SortOrder::kAscending,
90
                          bool is_collate = false);
91
92
  explicit PrimitiveValue(int64_t v, SortOrder sort_order = SortOrder::kAscending);
93
94
  explicit PrimitiveValue(const Timestamp& timestamp,
95
                          SortOrder sort_order = SortOrder::kAscending);
96
97
  explicit PrimitiveValue(const InetAddress& inetaddress,
98
                          SortOrder sort_order = SortOrder::kAscending);
99
100
  explicit PrimitiveValue(const Uuid& uuid,
101
                          SortOrder sort_order = SortOrder::kAscending);
102
103
  explicit PrimitiveValue(const HybridTime& hybrid_time);
104
  explicit PrimitiveValue(const DocHybridTime& hybrid_time);
105
  explicit PrimitiveValue(const ColumnId column_id);
106
107
  static PrimitiveValue NullValue(SortingType sorting);
108
109
  // Construct a primitive value from a QLValuePB.
110
  static PrimitiveValue FromQLValuePB(const QLValuePB& value,
111
                                      SortingType sorting_type,
112
                                      bool check_is_collate = true);
113
114
  // Set a primitive value in a QLValuePB.
115
  static void ToQLValuePB(const PrimitiveValue& pv,
116
                          const std::shared_ptr<QLType>& ql_type,
117
                          QLValuePB* ql_val);
118
119
6.26G
  ValueType value_type() const { return type_; }
120
121
  void AppendToKey(KeyBytes* key_bytes) const;
122
123
  // Convert this value to a human-readable string for logging / debugging.
124
  std::string ToString(AutoDecodeKeys auto_decode_keys = AutoDecodeKeys::kFalse) const;
125
126
  ~PrimitiveValue();
127
128
  // Decodes a primitive value from the given slice representing a RocksDB key in our key encoding
129
  // format and consumes a prefix of the slice.
130
  static CHECKED_STATUS DecodeKey(rocksdb::Slice* slice, PrimitiveValue* out);
131
  CHECKED_STATUS DecodeFromKey(rocksdb::Slice* slice);
132
133
  // Decodes a primitive value from the given slice representing a RocksDB value in our value
134
  // encoding format. Expects the entire slice to be consumed and returns an error otherwise.
135
  CHECKED_STATUS DecodeFromValue(const rocksdb::Slice& rocksdb_slice);
136
137
  static PrimitiveValue Double(double d, SortOrder sort_order = SortOrder::kAscending);
138
  static PrimitiveValue Float(float f, SortOrder sort_order = SortOrder::kAscending);
139
  // decimal_str represents a human readable string representing the decimal number, e.g. "0.03".
140
  static PrimitiveValue Decimal(const std::string& decimal_str, SortOrder sort_order);
141
  static PrimitiveValue VarInt(const std::string& varint_str, SortOrder sort_order);
142
  static PrimitiveValue ArrayIndex(int64_t index);
143
  static PrimitiveValue UInt16Hash(uint16_t hash);
144
  static PrimitiveValue SystemColumnId(ColumnId column_id);
145
  static PrimitiveValue SystemColumnId(SystemColumnIds system_column_id);
146
  static PrimitiveValue Int32(int32_t v, SortOrder sort_order = SortOrder::kAscending);
147
  static PrimitiveValue UInt32(uint32_t v, SortOrder sort_order = SortOrder::kAscending);
148
  static PrimitiveValue UInt64(uint64_t v, SortOrder sort_order = SortOrder::kAscending);
149
  static PrimitiveValue TransactionId(Uuid transaction_id);
150
  static PrimitiveValue TableId(Uuid table_id);
151
  static PrimitiveValue ColocationId(const ColocationId colocation_id);
152
  static PrimitiveValue Jsonb(const std::string& json);
153
  static PrimitiveValue GinNull(uint8_t v);
154
155
  KeyBytes ToKeyBytes() const;
156
157
  DocHybridTime hybrid_time() const;
158
159
  // As strange as it may sound, an instance of this class may sometimes contain a single byte that
160
  // indicates an empty data structure of a certain type (object, array), or a tombstone. This
161
  // method can tell whether what's stored here is an actual primitive value.
162
  bool IsPrimitive() const;
163
164
  bool IsTombstoneOrPrimitive() const;
165
166
  bool IsInfinity() const;
167
168
  int CompareTo(const PrimitiveValue& other) const;
169
170
  // Assuming this PrimitiveValue represents a string, return a Slice pointing to it.
171
  // This returns a YB slice, not a RocksDB slice, based on what was needed when this function was
172
  // implemented. This distinction should go away if we merge RocksDB and YB Slice classes.
173
0
  Slice GetStringAsSlice() const {
174
0
    DCHECK(IsString());
175
0
    return Slice(str_val_);
176
0
  }
177
178
  bool IsInt64() const;
179
180
  bool IsString() const;
181
182
  bool IsDouble() const;
183
184
108M
  const std::string& GetString() const {
185
108M
    DCHECK(IsString());
186
108M
    return str_val_;
187
108M
  }
188
189
  int32_t GetInt32() const;
190
191
  uint32_t GetUInt32() const;
192
193
  int64_t GetInt64() const;
194
195
  uint64_t GetUInt64() const;
196
197
  uint16_t GetUInt16() const;
198
199
1.72M
  double GetDouble() const {
200
1.72M
    DCHECK(IsDouble());
201
1.72M
    return double_val_;
202
1.72M
  }
203
204
  float GetFloat() const;
205
206
  const std::string& GetDecimal() const;
207
208
  const std::string& GetVarInt() const;
209
210
  Timestamp GetTimestamp() const;
211
212
  const InetAddress* GetInetaddress() const;
213
214
  const std::string& GetJson() const;
215
216
  const Uuid& GetUuid() const;
217
218
  ColumnId GetColumnId() const;
219
220
  uint8_t GetGinNull() const;
221
222
10.6G
  bool operator <(const PrimitiveValue& other) const {
223
10.6G
    return CompareTo(other) < 0;
224
10.6G
  }
225
226
33.9M
  bool operator <=(const PrimitiveValue& other) const {
227
33.9M
    return CompareTo(other) <= 0;
228
33.9M
  }
229
230
5.28M
  bool operator >(const PrimitiveValue& other) const {
231
5.28M
    return CompareTo(other) > 0;
232
5.28M
  }
233
234
33.9M
  bool operator >=(const PrimitiveValue& other) const {
235
33.9M
    return CompareTo(other) >= 0;
236
33.9M
  }
237
238
  bool operator==(const PrimitiveValue& other) const;
239
240
2
  bool operator!=(const PrimitiveValue& other) const { return !(*this == other); }
241
242
0
  ListExtendOrder GetExtendOrder() const {
243
0
    return extend_order_;
244
0
  }
245
246
600M
  int64_t GetTtl() const {
247
600M
    return ttl_seconds_;
248
600M
  }
249
250
600M
  bool IsWriteTimeSet() const {
251
600M
    return write_time_ != kUninitializedWriteTime;
252
600M
  }
253
254
532M
  int64_t GetWriteTime() const {
255
532M
    DCHECK_NE(kUninitializedWriteTime, write_time_);
256
532M
    return write_time_;
257
532M
  }
258
259
65.2M
  void SetTtl(const int64_t ttl_seconds) {
260
65.2M
    ttl_seconds_ = ttl_seconds;
261
65.2M
  }
262
263
0
  void SetExtendOrder(const ListExtendOrder extend_order) const {
264
0
    extend_order_ = extend_order;
265
0
  }
266
267
615M
  void SetWriteTime(const int64_t write_time) {
268
615M
    write_time_ = write_time;
269
615M
  }
270
  typedef std::vector<PrimitiveValue> FrozenContainer;
271
272
 protected:
273
274
  static constexpr int64_t kUninitializedWriteTime = std::numeric_limits<int64_t>::min();
275
276
  // Column attributes.
277
  int64_t ttl_seconds_ = -1;
278
  int64_t write_time_ = kUninitializedWriteTime;
279
280
  // TODO: make PrimitiveValue extend SubDocument and put this field
281
  // in SubDocument.
282
  // This field gives the extension order of elements of a list and
283
  // is applicable only to SubDocuments of type kArray.
284
  mutable ListExtendOrder extend_order_ = ListExtendOrder::APPEND;
285
286
  ValueType type_;
287
288
  // TODO: do we have to worry about alignment here?
289
  union {
290
    int32_t int32_val_;
291
    uint32_t uint32_val_;
292
    int64_t int64_val_;
293
    uint64_t uint64_val_;
294
    uint16_t uint16_val_;
295
    DocHybridTime hybrid_time_val_;
296
    std::string str_val_;
297
    float float_val_;
298
    double double_val_;
299
    Timestamp timestamp_val_;
300
    InetAddress* inetaddress_val_;
301
    Uuid uuid_val_;
302
    FrozenContainer* frozen_val_;
303
    // This is used in SubDocument to hold a pointer to a map or a vector.
304
    void* complex_data_structure_;
305
    ColumnId column_id_val_;
306
    std::string decimal_val_;
307
    std::string varint_val_;
308
    std::string json_val_;
309
    uint8_t gin_null_val_;
310
  };
311
312
 private:
313
314
  // This is used in both the move constructor and the move assignment operator. Assumes this object
315
  // has not been constructed, or that the destructor has just been called.
316
  void MoveFrom(PrimitiveValue* other);
317
};
318
319
26
inline std::ostream& operator<<(std::ostream& out, const PrimitiveValue& primitive_value) {
320
26
  out << primitive_value.ToString();
321
26
  return out;
322
26
}
323
324
0
inline std::ostream& operator<<(std::ostream& out, const SortOrder sort_order) {
325
0
  string sort_order_name = sort_order == SortOrder::kAscending ? "kAscending" : "kDescending";
326
0
  out << sort_order_name;
327
0
  return out;
328
0
}
329
330
// A variadic template utility for creating vectors with PrimitiveValue elements out of arbitrary
331
// sequences of arguments of supported types.
332
70.9M
inline void AppendPrimitiveValues(std::vector<PrimitiveValue>* dest) {}
333
334
template <class T, class ...U>
335
inline void AppendPrimitiveValues(std::vector<PrimitiveValue>* dest,
336
                                  T first_arg,
337
69.8M
                                  U... more_args) {
338
69.8M
  dest->emplace_back(first_arg);
339
69.8M
  AppendPrimitiveValues(dest, more_args...);
340
69.8M
}
void yb::docdb::AppendPrimitiveValues<yb::docdb::PrimitiveValue>(std::__1::vector<yb::docdb::PrimitiveValue, std::__1::allocator<yb::docdb::PrimitiveValue> >*, yb::docdb::PrimitiveValue)
Line
Count
Source
337
69.8M
                                  U... more_args) {
338
69.8M
  dest->emplace_back(first_arg);
339
69.8M
  AppendPrimitiveValues(dest, more_args...);
340
69.8M
}
void yb::docdb::AppendPrimitiveValues<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int>(std::__1::vector<yb::docdb::PrimitiveValue, std::__1::allocator<yb::docdb::PrimitiveValue> >*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int)
Line
Count
Source
337
10
                                  U... more_args) {
338
10
  dest->emplace_back(first_arg);
339
10
  AppendPrimitiveValues(dest, more_args...);
340
10
}
void yb::docdb::AppendPrimitiveValues<int>(std::__1::vector<yb::docdb::PrimitiveValue, std::__1::allocator<yb::docdb::PrimitiveValue> >*, int)
Line
Count
Source
337
422
                                  U... more_args) {
338
422
  dest->emplace_back(first_arg);
339
422
  AppendPrimitiveValues(dest, more_args...);
340
422
}
341
342
template <class ...T>
343
10
inline std::vector<PrimitiveValue> PrimitiveValues(T... args) {
344
10
  std::vector<PrimitiveValue> v;
345
10
  AppendPrimitiveValues(&v, args...);
346
10
  return v;
347
10
}
348
349
// Converts a SortingType to its SortOrder equivalent.
350
// SortingType::kAscending and SortingType::kNotSpecified get
351
// converted to SortOrder::kAscending.
352
// SortingType::kDescending gets converted to SortOrder::kDescending.
353
SortOrder SortOrderFromColumnSchemaSortingType(SortingType sorting_type);
354
355
void AppendEncodedValue(const QLValuePB& value, SortingType sorting_type, std::string* out);
356
357
}  // namespace docdb
358
}  // namespace yb
359
360
#endif  // YB_DOCDB_PRIMITIVE_VALUE_H_