/Users/deen/code/yugabyte-db/src/yb/common/ql_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 | | // This file contains the QLValue class that represents QL values. |
15 | | |
16 | | #include "yb/common/ql_value.h" |
17 | | |
18 | | #include <glog/logging.h> |
19 | | |
20 | | #include "yb/common/jsonb.h" |
21 | | #include "yb/common/ql_protocol_util.h" |
22 | | #include "yb/common/ql_type.h" |
23 | | |
24 | | #include "yb/gutil/casts.h" |
25 | | #include "yb/gutil/strings/escaping.h" |
26 | | |
27 | | #include "yb/util/bytes_formatter.h" |
28 | | #include "yb/util/date_time.h" |
29 | | #include "yb/util/decimal.h" |
30 | | #include "yb/util/enums.h" |
31 | | #include "yb/util/size_literals.h" |
32 | | #include "yb/util/status_format.h" |
33 | | #include "yb/util/status_log.h" |
34 | | #include "yb/util/varint.h" |
35 | | |
36 | | using yb::operator"" _MB; |
37 | | |
38 | | // Maximumum value size is 64MB |
39 | | DEFINE_int32(yql_max_value_size, 64_MB, |
40 | | "Maximum size of a value in the Yugabyte Query Layer"); |
41 | | |
42 | | namespace yb { |
43 | | |
44 | | using std::string; |
45 | | using std::shared_ptr; |
46 | | using std::to_string; |
47 | | using util::Decimal; |
48 | | using common::Jsonb; |
49 | | |
50 | | template<typename T> |
51 | 1.74M | static int GenericCompare(const T& lhs, const T& rhs) { |
52 | 1.74M | if (lhs < rhs) return -1; |
53 | 1.06M | if (lhs > rhs) return 1; |
54 | 398k | return 0; |
55 | 398k | } ql_value.cc:_ZN2ybL14GenericCompareIaEEiRKT_S3_ Line | Count | Source | 51 | 923 | static int GenericCompare(const T& lhs, const T& rhs) { | 52 | 923 | if (lhs < rhs) return -1; | 53 | 474 | if (lhs > rhs) return 1; | 54 | 39 | return 0; | 55 | 39 | } |
ql_value.cc:_ZN2ybL14GenericCompareIsEEiRKT_S3_ Line | Count | Source | 51 | 10.3k | static int GenericCompare(const T& lhs, const T& rhs) { | 52 | 10.3k | if (lhs < rhs) return -1; | 53 | 4.82k | if (lhs > rhs) return 1; | 54 | 285 | return 0; | 55 | 285 | } |
ql_value.cc:_ZN2ybL14GenericCompareIiEEiRKT_S3_ Line | Count | Source | 51 | 731k | static int GenericCompare(const T& lhs, const T& rhs) { | 52 | 731k | if (lhs < rhs) return -1; | 53 | 639k | if (lhs > rhs) return 1; | 54 | 392k | return 0; | 55 | 392k | } |
ql_value.cc:_ZN2ybL14GenericCompareIxEEiRKT_S3_ Line | Count | Source | 51 | 1.00M | static int GenericCompare(const T& lhs, const T& rhs) { | 52 | 1.00M | if (lhs < rhs) return -1; | 53 | 417k | if (lhs > rhs) return 1; | 54 | 4.49k | return 0; | 55 | 4.49k | } |
ql_value.cc:_ZN2ybL14GenericCompareIjEEiRKT_S3_ Line | Count | Source | 51 | 354 | static int GenericCompare(const T& lhs, const T& rhs) { | 52 | 354 | if (lhs < rhs) return -1; | 53 | 235 | if (lhs > rhs) return 1; | 54 | 213 | return 0; | 55 | 213 | } |
Unexecuted instantiation: ql_value.cc:_ZN2ybL14GenericCompareIyEEiRKT_S3_ ql_value.cc:_ZN2ybL14GenericCompareIfEEiRKT_S3_ Line | Count | Source | 51 | 582 | static int GenericCompare(const T& lhs, const T& rhs) { | 52 | 582 | if (lhs < rhs) return -1; | 53 | 428 | if (lhs > rhs) return 1; | 54 | 264 | return 0; | 55 | 264 | } |
ql_value.cc:_ZN2ybL14GenericCompareIdEEiRKT_S3_ Line | Count | Source | 51 | 596 | static int GenericCompare(const T& lhs, const T& rhs) { | 52 | 596 | if (lhs < rhs) return -1; | 53 | 440 | if (lhs > rhs) return 1; | 54 | 273 | return 0; | 55 | 273 | } |
Unexecuted instantiation: ql_value.cc:_ZN2ybL14GenericCompareINS_9TimestampEEEiRKT_S4_ ql_value.cc:_ZN2ybL14GenericCompareINS_11InetAddressEEEiRKT_S4_ Line | Count | Source | 51 | 303 | static int GenericCompare(const T& lhs, const T& rhs) { | 52 | 303 | if (lhs < rhs) return -1; | 53 | 190 | if (lhs > rhs) return 1; | 54 | 66 | return 0; | 55 | 66 | } |
ql_value.cc:_ZN2ybL14GenericCompareINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEEiRKT_SA_ Line | Count | Source | 51 | 292 | static int GenericCompare(const T& lhs, const T& rhs) { | 52 | 292 | if (lhs < rhs) return -1; | 53 | 238 | if (lhs > rhs) return 1; | 54 | 167 | return 0; | 55 | 167 | } |
ql_value.cc:_ZN2ybL14GenericCompareINS_4UuidEEEiRKT_S4_ Line | Count | Source | 51 | 1.26k | static int GenericCompare(const T& lhs, const T& rhs) { | 52 | 1.26k | if (lhs < rhs) return -1; | 53 | 752 | if (lhs > rhs) return 1; | 54 | 209 | return 0; | 55 | 209 | } |
Unexecuted instantiation: ql_value.cc:_ZN2ybL14GenericCompareIhEEiRKT_S3_ |
56 | | |
57 | 198M | QLValue::~QLValue() {} |
58 | | |
59 | | //------------------------- instance methods for abstract QLValue class ----------------------- |
60 | | |
61 | 53.8k | int QLValue::CompareTo(const QLValue& other) const { |
62 | 53.8k | if (!IsVirtual() && other.IsVirtual()) { |
63 | 0 | return -other.CompareTo(*this); |
64 | 0 | } |
65 | | |
66 | 53.8k | CHECK(type() == other.type() || EitherIsVirtual(other)); |
67 | 53.8k | CHECK(!IsNull()); |
68 | 53.8k | CHECK(!other.IsNull()); |
69 | 53.8k | switch (type()) { |
70 | 923 | case InternalType::kInt8Value: return GenericCompare(int8_value(), other.int8_value()); |
71 | 10.3k | case InternalType::kInt16Value: return GenericCompare(int16_value(), other.int16_value()); |
72 | 20.7k | case InternalType::kInt32Value: return GenericCompare(int32_value(), other.int32_value()); |
73 | 11.1k | case InternalType::kInt64Value: return GenericCompare(int64_value(), other.int64_value()); |
74 | 0 | case InternalType::kUint32Value: return GenericCompare(uint32_value(), other.uint32_value()); |
75 | 0 | case InternalType::kUint64Value: return GenericCompare(uint64_value(), other.uint64_value()); |
76 | 16 | case InternalType::kFloatValue: { |
77 | 16 | bool is_nan_0 = util::IsNanFloat(float_value()); |
78 | 16 | bool is_nan_1 = util::IsNanFloat(other.float_value()); |
79 | 16 | if (is_nan_0 && is_nan_1) return 0; |
80 | 16 | if (is_nan_0 && !is_nan_1) return 1; |
81 | 16 | if (!is_nan_0 && is_nan_1) return -1; |
82 | 16 | return GenericCompare(float_value(), other.float_value()); |
83 | 16 | } |
84 | 16 | case InternalType::kDoubleValue: { |
85 | 16 | bool is_nan_0 = util::IsNanDouble(double_value()); |
86 | 16 | bool is_nan_1 = util::IsNanDouble(other.double_value()); |
87 | 16 | if (is_nan_0 && is_nan_1) return 0; |
88 | 16 | if (is_nan_0 && !is_nan_1) return 1; |
89 | 16 | if (!is_nan_0 && is_nan_1) return -1; |
90 | 16 | return GenericCompare(double_value(), other.double_value()); |
91 | 16 | } |
92 | | // Encoded decimal is byte-comparable. |
93 | 0 | case InternalType::kDecimalValue: return decimal_value().compare(other.decimal_value()); |
94 | 0 | case InternalType::kVarintValue: return varint_value().CompareTo(other.varint_value()); |
95 | 10.6k | case InternalType::kStringValue: return string_value().compare(other.string_value()); |
96 | 2 | case InternalType::kBoolValue: return Compare(bool_value(), other.bool_value()); |
97 | 0 | case InternalType::kTimestampValue: |
98 | 0 | return GenericCompare(timestamp_value(), other.timestamp_value()); |
99 | 0 | case InternalType::kBinaryValue: return binary_value().compare(other.binary_value()); |
100 | 0 | case InternalType::kInetaddressValue: |
101 | 0 | return GenericCompare(inetaddress_value(), other.inetaddress_value()); |
102 | 0 | case InternalType::kJsonbValue: |
103 | 0 | return GenericCompare(jsonb_value(), other.jsonb_value()); |
104 | 0 | case InternalType::kUuidValue: |
105 | 0 | return GenericCompare(uuid_value(), other.uuid_value()); |
106 | 0 | case InternalType::kTimeuuidValue: |
107 | 0 | return GenericCompare(timeuuid_value(), other.timeuuid_value()); |
108 | 0 | case InternalType::kDateValue: return GenericCompare(date_value(), other.date_value()); |
109 | 0 | case InternalType::kTimeValue: return GenericCompare(time_value(), other.time_value()); |
110 | 15 | case InternalType::kFrozenValue: { |
111 | 15 | return Compare(frozen_value(), other.frozen_value()); |
112 | 16 | } |
113 | 0 | case InternalType::kMapValue: FALLTHROUGH_INTENDED; |
114 | 0 | case InternalType::kSetValue: FALLTHROUGH_INTENDED; |
115 | 0 | case InternalType::kListValue: |
116 | 0 | LOG(FATAL) << "Internal error: collection types are not comparable"; |
117 | 0 | return 0; |
118 | |
|
119 | 0 | case InternalType::VALUE_NOT_SET: |
120 | 0 | LOG(FATAL) << "Internal error: value should not be null"; |
121 | 0 | break; |
122 | |
|
123 | 0 | case InternalType::kVirtualValue: |
124 | 0 | if (IsMax()) { |
125 | 0 | return other.IsMax() ? 0 : 1; |
126 | 0 | } else { |
127 | 0 | return other.IsMin() ? 0 : -1; |
128 | 0 | } |
129 | | |
130 | 0 | case InternalType::kGinNullValue: { |
131 | 0 | return GenericCompare(gin_null_value(), other.gin_null_value()); |
132 | 0 | } |
133 | 0 | } |
134 | | |
135 | 0 | LOG(FATAL) << "Internal error: unsupported type " << type(); |
136 | 0 | return 0; |
137 | 0 | } |
138 | | |
139 | | // TODO(mihnea) After the hash changes, this method does not do the key encoding anymore |
140 | | // (not needed for hash computation), so AppendToBytes() is better describes what this method does. |
141 | | // The internal methods such as AppendIntToKey should be renamed accordingly. |
142 | 12.9M | void AppendToKey(const QLValuePB &value_pb, string *bytes) { |
143 | 12.9M | switch (value_pb.value_case()) { |
144 | 296 | case InternalType::kBoolValue: { |
145 | 274 | YBPartition::AppendIntToKey<bool, uint8>(value_pb.bool_value() ? 1 : 0, bytes); |
146 | 296 | break; |
147 | 0 | } |
148 | 135k | case InternalType::kInt8Value: { |
149 | 135k | YBPartition::AppendIntToKey<int8, uint8>(value_pb.int8_value(), bytes); |
150 | 135k | break; |
151 | 0 | } |
152 | 71.7k | case InternalType::kInt16Value: { |
153 | 71.7k | YBPartition::AppendIntToKey<int16, uint16>(value_pb.int16_value(), bytes); |
154 | 71.7k | break; |
155 | 0 | } |
156 | 4.74M | case InternalType::kInt32Value: { |
157 | 4.74M | YBPartition::AppendIntToKey<int32, uint32>(value_pb.int32_value(), bytes); |
158 | 4.74M | break; |
159 | 0 | } |
160 | 732k | case InternalType::kInt64Value: { |
161 | 732k | YBPartition::AppendIntToKey<int64, uint64>(value_pb.int64_value(), bytes); |
162 | 732k | break; |
163 | 0 | } |
164 | 0 | case InternalType::kUint32Value: { |
165 | 0 | YBPartition::AppendIntToKey<uint32, uint32>(value_pb.uint32_value(), bytes); |
166 | 0 | break; |
167 | 0 | } |
168 | 0 | case InternalType::kUint64Value: { |
169 | 0 | YBPartition::AppendIntToKey<uint64, uint64>(value_pb.uint64_value(), bytes); |
170 | 0 | break; |
171 | 0 | } |
172 | 672k | case InternalType::kTimestampValue: { |
173 | 672k | YBPartition::AppendIntToKey<int64, uint64>(value_pb.timestamp_value(), bytes); |
174 | 672k | break; |
175 | 0 | } |
176 | 345 | case InternalType::kDateValue: { |
177 | 345 | YBPartition::AppendIntToKey<uint32, uint32>(value_pb.date_value(), bytes); |
178 | 345 | break; |
179 | 0 | } |
180 | 335 | case InternalType::kTimeValue: { |
181 | 335 | YBPartition::AppendIntToKey<int64, uint64>(value_pb.time_value(), bytes); |
182 | 335 | break; |
183 | 0 | } |
184 | 6.12M | case InternalType::kStringValue: { |
185 | 6.12M | const string& str = value_pb.string_value(); |
186 | 6.12M | YBPartition::AppendBytesToKey(str.c_str(), str.length(), bytes); |
187 | 6.12M | break; |
188 | 0 | } |
189 | 792 | case InternalType::kUuidValue: { |
190 | 792 | const string& str = value_pb.uuid_value(); |
191 | 792 | YBPartition::AppendBytesToKey(str.c_str(), str.length(), bytes); |
192 | 792 | break; |
193 | 0 | } |
194 | 229 | case InternalType::kTimeuuidValue: { |
195 | 229 | const string& str = value_pb.timeuuid_value(); |
196 | 229 | YBPartition::AppendBytesToKey(str.c_str(), str.length(), bytes); |
197 | 229 | break; |
198 | 0 | } |
199 | 327 | case InternalType::kInetaddressValue: { |
200 | 327 | const string& str = value_pb.inetaddress_value(); |
201 | 327 | YBPartition::AppendBytesToKey(str.c_str(), str.length(), bytes); |
202 | 327 | break; |
203 | 0 | } |
204 | 2.80k | case InternalType::kDecimalValue: { |
205 | 2.80k | const string& str = value_pb.decimal_value(); |
206 | 2.80k | YBPartition::AppendBytesToKey(str.c_str(), str.length(), bytes); |
207 | 2.80k | break; |
208 | 0 | } |
209 | 1.71k | case InternalType::kVarintValue: { |
210 | 1.71k | const string& str = value_pb.varint_value(); |
211 | 1.71k | YBPartition::AppendBytesToKey(str.c_str(), str.length(), bytes); |
212 | 1.71k | break; |
213 | 0 | } |
214 | 465k | case InternalType::kBinaryValue: { |
215 | 465k | const string& str = value_pb.binary_value(); |
216 | 465k | YBPartition::AppendBytesToKey(str.c_str(), str.length(), bytes); |
217 | 465k | break; |
218 | 0 | } |
219 | 398 | case InternalType::kFloatValue: { |
220 | 398 | YBPartition::AppendIntToKey<float, uint32>(util::CanonicalizeFloat(value_pb.float_value()), |
221 | 398 | bytes); |
222 | 398 | break; |
223 | 0 | } |
224 | 906 | case InternalType::kDoubleValue: { |
225 | 906 | YBPartition::AppendIntToKey<double, uint64>(util::CanonicalizeDouble(value_pb.double_value()), |
226 | 906 | bytes); |
227 | 906 | break; |
228 | 0 | } |
229 | 317 | case InternalType::kFrozenValue: { |
230 | 651 | for (const auto& elem_pb : value_pb.frozen_value().elems()) { |
231 | 651 | AppendToKey(elem_pb, bytes); |
232 | 651 | } |
233 | 317 | break; |
234 | 0 | } |
235 | 4.13k | case InternalType::VALUE_NOT_SET: |
236 | 4.13k | break; |
237 | 0 | case InternalType::kMapValue: FALLTHROUGH_INTENDED; |
238 | 0 | case InternalType::kSetValue: FALLTHROUGH_INTENDED; |
239 | 0 | case InternalType::kListValue: FALLTHROUGH_INTENDED; |
240 | 0 | case InternalType::kJsonbValue: |
241 | 0 | LOG(FATAL) << "Runtime error: This datatype(" |
242 | 0 | << int(value_pb.value_case()) |
243 | 0 | << ") is not supported in hash key"; |
244 | 0 | case InternalType::kVirtualValue: |
245 | 0 | LOG(FATAL) << "Runtime error: virtual value should not be used to construct hash key"; |
246 | 0 | case InternalType::kGinNullValue: { |
247 | 0 | LOG(ERROR) << "Runtime error: gin null value should not be used to construct hash key"; |
248 | 0 | YBPartition::AppendIntToKey<uint8, uint8>(value_pb.gin_null_value(), bytes); |
249 | 0 | break; |
250 | 0 | } |
251 | 12.9M | } |
252 | 12.9M | } |
253 | | |
254 | | void QLValue::Serialize( |
255 | | const std::shared_ptr<QLType>& ql_type, const QLClient& client, const QLValuePB& pb, |
256 | 37.6M | faststring* buffer) { |
257 | 37.6M | CHECK_EQ(client, YQL_CLIENT_CQL); |
258 | 37.6M | if (IsNull(pb)) { |
259 | 4.57M | CQLEncodeLength(-1, buffer); |
260 | 4.57M | return; |
261 | 4.57M | } |
262 | | |
263 | 33.0M | switch (ql_type->main()) { |
264 | 40.8k | case INT8: |
265 | 40.8k | CQLEncodeNum(Store8, int8_value(pb), buffer); |
266 | 40.8k | return; |
267 | 21.6k | case INT16: |
268 | 21.6k | CQLEncodeNum(NetworkByteOrder::Store16, int16_value(pb), buffer); |
269 | 21.6k | return; |
270 | 4.36M | case INT32: |
271 | 4.36M | CQLEncodeNum(NetworkByteOrder::Store32, int32_value(pb), buffer); |
272 | 4.36M | return; |
273 | 657k | case INT64: |
274 | 657k | CQLEncodeNum(NetworkByteOrder::Store64, int64_value(pb), buffer); |
275 | 657k | return; |
276 | 453 | case FLOAT: |
277 | 453 | CQLEncodeFloat(NetworkByteOrder::Store32, float_value(pb), buffer); |
278 | 453 | return; |
279 | 537 | case DOUBLE: |
280 | 537 | CQLEncodeFloat(NetworkByteOrder::Store64, double_value(pb), buffer); |
281 | 537 | return; |
282 | 11.3k | case DECIMAL: { |
283 | 11.3k | auto decimal = util::DecimalFromComparable(decimal_value(pb)); |
284 | 11.3k | bool is_out_of_range = false; |
285 | 11.3k | CQLEncodeBytes(decimal.EncodeToSerializedBigDecimal(&is_out_of_range), buffer); |
286 | 11.3k | if(is_out_of_range) { |
287 | 0 | LOG(ERROR) << "Out of range: Unable to encode decimal " << decimal.ToString() |
288 | 0 | << " into a BigDecimal serialized representation"; |
289 | 0 | } |
290 | 11.3k | return; |
291 | 0 | } |
292 | 10.8k | case VARINT: { |
293 | 10.8k | CQLEncodeBytes(varint_value(pb).EncodeToTwosComplement(), buffer); |
294 | 10.8k | return; |
295 | 0 | } |
296 | 21.0M | case STRING: |
297 | 21.0M | CQLEncodeBytes(string_value(pb), buffer); |
298 | 21.0M | return; |
299 | 185k | case BOOL: |
300 | 176k | CQLEncodeNum(Store8, static_cast<uint8>(bool_value(pb) ? 1 : 0), buffer); |
301 | 185k | return; |
302 | 659k | case BINARY: |
303 | 659k | CQLEncodeBytes(binary_value(pb), buffer); |
304 | 659k | return; |
305 | 3.61M | case TIMESTAMP: { |
306 | 3.61M | int64_t val = DateTime::AdjustPrecision(timestamp_value_pb(pb), |
307 | 3.61M | DateTime::kInternalPrecision, |
308 | 3.61M | DateTime::CqlInputFormat.input_precision); |
309 | 3.61M | CQLEncodeNum(NetworkByteOrder::Store64, val, buffer); |
310 | 3.61M | return; |
311 | 0 | } |
312 | 75 | case DATE: { |
313 | 75 | CQLEncodeNum(NetworkByteOrder::Store32, date_value(pb), buffer); |
314 | 75 | return; |
315 | 0 | } |
316 | 66 | case TIME: { |
317 | 66 | CQLEncodeNum(NetworkByteOrder::Store64, time_value(pb), buffer); |
318 | 66 | return; |
319 | 0 | } |
320 | 1.25M | case INET: { |
321 | 1.25M | std::string bytes; |
322 | 1.25M | CHECK_OK(inetaddress_value(pb).ToBytes(&bytes)); |
323 | 1.25M | CQLEncodeBytes(bytes, buffer); |
324 | 1.25M | return; |
325 | 0 | } |
326 | 211 | case JSONB: { |
327 | 211 | std::string json; |
328 | 211 | Jsonb jsonb(jsonb_value(pb)); |
329 | 211 | CHECK_OK(jsonb.ToJsonString(&json)); |
330 | 211 | CQLEncodeBytes(json, buffer); |
331 | 211 | return; |
332 | 0 | } |
333 | 366k | case UUID: { |
334 | 366k | std::string bytes; |
335 | 366k | uuid_value(pb).ToBytes(&bytes); |
336 | 366k | CQLEncodeBytes(bytes, buffer); |
337 | 366k | return; |
338 | 0 | } |
339 | 125 | case TIMEUUID: { |
340 | 125 | std::string bytes; |
341 | 125 | Uuid uuid = timeuuid_value(pb); |
342 | 125 | CHECK_OK(uuid.IsTimeUuid()); |
343 | 125 | uuid.ToBytes(&bytes); |
344 | 125 | CQLEncodeBytes(bytes, buffer); |
345 | 125 | return; |
346 | 0 | } |
347 | 573k | case MAP: { |
348 | 573k | const QLMapValuePB& map = map_value(pb); |
349 | 573k | DCHECK_EQ(map.keys_size(), map.values_size()); |
350 | 573k | int32_t start_pos = CQLStartCollection(buffer); |
351 | 573k | int32_t length = static_cast<int32_t>(map.keys_size()); |
352 | 573k | CQLEncodeLength(length, buffer); |
353 | 573k | const shared_ptr<QLType>& keys_type = ql_type->params()[0]; |
354 | 573k | const shared_ptr<QLType>& values_type = ql_type->params()[1]; |
355 | 1.84M | for (int i = 0; i < length; i++) { |
356 | 1.27M | QLValue::Serialize(keys_type, client, map.keys(i), buffer); |
357 | 1.27M | QLValue::Serialize(values_type, client, map.values(i), buffer); |
358 | 1.27M | } |
359 | 573k | CQLFinishCollection(start_pos, buffer); |
360 | 573k | return; |
361 | 0 | } |
362 | 260k | case SET: { |
363 | 260k | const QLSeqValuePB& set = set_value(pb); |
364 | 260k | int32_t start_pos = CQLStartCollection(buffer); |
365 | 260k | int32_t length = static_cast<int32_t>(set.elems_size()); |
366 | 260k | CQLEncodeLength(length, buffer); // number of elements in collection |
367 | 260k | const shared_ptr<QLType>& elems_type = ql_type->param_type(0); |
368 | 260k | for (auto& elem : set.elems()) { |
369 | 260k | QLValue::Serialize(elems_type, client, elem, buffer); |
370 | 260k | } |
371 | 260k | CQLFinishCollection(start_pos, buffer); |
372 | 260k | return; |
373 | 0 | } |
374 | 2.95k | case LIST: { |
375 | 2.95k | const QLSeqValuePB& list = list_value(pb); |
376 | 2.95k | int32_t start_pos = CQLStartCollection(buffer); |
377 | 2.95k | int32_t length = static_cast<int32_t>(list.elems_size()); |
378 | 2.95k | CQLEncodeLength(length, buffer); |
379 | 2.95k | const shared_ptr<QLType>& elems_type = ql_type->param_type(0); |
380 | 1.26k | for (auto& elem : list.elems()) { |
381 | 1.26k | QLValue::Serialize(elems_type, client, elem, buffer); |
382 | 1.26k | } |
383 | 2.95k | CQLFinishCollection(start_pos, buffer); |
384 | 2.95k | return; |
385 | 0 | } |
386 | | |
387 | 45 | case USER_DEFINED_TYPE: { |
388 | 45 | const QLMapValuePB& map = map_value(pb); |
389 | 45 | DCHECK_EQ(map.keys_size(), map.values_size()); |
390 | 45 | int32_t start_pos = CQLStartCollection(buffer); |
391 | | |
392 | | // For every field the UDT has, we try to find a corresponding map entry. If found we |
393 | | // serialize the value, else null. Map keys should always be in ascending order. |
394 | 45 | int key_idx = 0; |
395 | 143 | for (size_t i = 0; i < ql_type->udtype_field_names().size(); i++) { |
396 | 98 | if (key_idx < map.keys_size() && |
397 | 93 | implicit_cast<size_t>(map.keys(key_idx).int16_value()) == i) { |
398 | 88 | QLValue::Serialize(ql_type->param_type(i), client, map.values(key_idx), buffer); |
399 | 88 | key_idx++; |
400 | 10 | } else { // entry not found -> writing null |
401 | 10 | CQLEncodeLength(-1, buffer); |
402 | 10 | } |
403 | 98 | } |
404 | | |
405 | 45 | CQLFinishCollection(start_pos, buffer); |
406 | 45 | return; |
407 | 0 | } |
408 | 418 | case FROZEN: { |
409 | 418 | const QLSeqValuePB& frozen = frozen_value(pb); |
410 | 418 | const auto& type = ql_type->param_type(0); |
411 | 418 | switch (type->main()) { |
412 | 54 | case MAP: { |
413 | 54 | DCHECK_EQ(frozen.elems_size() % 2, 0); |
414 | 54 | int32_t start_pos = CQLStartCollection(buffer); |
415 | 54 | int32_t length = static_cast<int32_t>(frozen.elems_size() / 2); |
416 | 54 | CQLEncodeLength(length, buffer); |
417 | 54 | const shared_ptr<QLType> &keys_type = type->params()[0]; |
418 | 54 | const shared_ptr<QLType> &values_type = type->params()[1]; |
419 | 142 | for (int i = 0; i < length; i++) { |
420 | 88 | QLValue::Serialize(keys_type, client, frozen.elems(2 * i), buffer); |
421 | 88 | QLValue::Serialize(values_type, client, frozen.elems(2 * i + 1), buffer); |
422 | 88 | } |
423 | 54 | CQLFinishCollection(start_pos, buffer); |
424 | 54 | return; |
425 | 0 | } |
426 | 71 | case SET: FALLTHROUGH_INTENDED; |
427 | 133 | case LIST: { |
428 | 133 | int32_t start_pos = CQLStartCollection(buffer); |
429 | 133 | int32_t length = static_cast<int32_t>(frozen.elems_size()); |
430 | 133 | CQLEncodeLength(length, buffer); // number of elements in collection |
431 | 133 | const shared_ptr<QLType> &elems_type = type->param_type(0); |
432 | 240 | for (auto &elem : frozen.elems()) { |
433 | 240 | QLValue::Serialize(elems_type, client, elem, buffer); |
434 | 240 | } |
435 | 133 | CQLFinishCollection(start_pos, buffer); |
436 | 133 | return; |
437 | 71 | } |
438 | 231 | case USER_DEFINED_TYPE: { |
439 | 231 | int32_t start_pos = CQLStartCollection(buffer); |
440 | 707 | for (int i = 0; i < frozen.elems_size(); i++) { |
441 | 476 | QLValue::Serialize(type->param_type(i), client, frozen.elems(i), buffer); |
442 | 476 | } |
443 | 231 | CQLFinishCollection(start_pos, buffer); |
444 | 231 | return; |
445 | 71 | } |
446 | | |
447 | 0 | default: |
448 | 0 | break; |
449 | 0 | } |
450 | 0 | break; |
451 | 0 | } |
452 | |
|
453 | 0 | QL_UNSUPPORTED_TYPES_IN_SWITCH: |
454 | 0 | break; |
455 | |
|
456 | 0 | QL_INVALID_TYPES_IN_SWITCH: |
457 | 0 | break; |
458 | | // default: fall through |
459 | 0 | } |
460 | | |
461 | 0 | LOG(FATAL) << "Internal error: unsupported type " << ql_type->ToString(); |
462 | 0 | } |
463 | | |
464 | | void QLValue::Serialize( |
465 | 1.85k | const std::shared_ptr<QLType>& ql_type, const QLClient& client, faststring* buffer) const { |
466 | 1.85k | return Serialize(ql_type, client, pb_, buffer); |
467 | 1.85k | } |
468 | | |
469 | 2.01M | Status CheckForNull(const QLValue& val) { |
470 | 0 | return val.IsNull() ? STATUS(InvalidArgument, "null is not supported inside collections") |
471 | 2.01M | : Status::OK(); |
472 | 2.01M | } |
473 | | |
474 | | Status QLValue::Deserialize( |
475 | 25.5M | const std::shared_ptr<QLType>& ql_type, const QLClient& client, Slice* data) { |
476 | 25.5M | CHECK_EQ(client, YQL_CLIENT_CQL); |
477 | 25.5M | int32_t len = 0; |
478 | 25.5M | RETURN_NOT_OK(CQLDecodeNum(sizeof(len), NetworkByteOrder::Load32, data, &len)); |
479 | 25.5M | if (len == -1) { |
480 | 3.73M | SetNull(); |
481 | 3.73M | return Status::OK(); |
482 | 3.73M | } |
483 | 21.7M | if (len > FLAGS_yql_max_value_size) { |
484 | 2 | return STATUS_SUBSTITUTE(NotSupported, |
485 | 2 | "Value size ($0) is longer than max value size supported ($1)", |
486 | 2 | len, FLAGS_yql_max_value_size); |
487 | 2 | } |
488 | | |
489 | 21.7M | switch (ql_type->main()) { |
490 | 40.5k | case INT8: |
491 | 40.5k | return CQLDeserializeNum( |
492 | 40.5k | len, Load8, static_cast<void (QLValue::*)(int8_t)>(&QLValue::set_int8_value), data); |
493 | 21.3k | case INT16: |
494 | 21.3k | return CQLDeserializeNum( |
495 | 21.3k | len, NetworkByteOrder::Load16, |
496 | 21.3k | static_cast<void (QLValue::*)(int16_t)>(&QLValue::set_int16_value), data); |
497 | 1.80M | case INT32: |
498 | 1.80M | return CQLDeserializeNum( |
499 | 1.80M | len, NetworkByteOrder::Load32, |
500 | 1.80M | static_cast<void (QLValue::*)(int32_t)>(&QLValue::set_int32_value), data); |
501 | 639k | case INT64: |
502 | 639k | return CQLDeserializeNum( |
503 | 639k | len, NetworkByteOrder::Load64, |
504 | 639k | static_cast<void (QLValue::*)(int64_t)>(&QLValue::set_int64_value), data); |
505 | 87 | case FLOAT: |
506 | 87 | return CQLDeserializeFloat( |
507 | 87 | len, NetworkByteOrder::Load32, |
508 | 87 | static_cast<void (QLValue::*)(float)>(&QLValue::set_float_value), data); |
509 | 117 | case DOUBLE: |
510 | 117 | return CQLDeserializeFloat( |
511 | 117 | len, NetworkByteOrder::Load64, |
512 | 117 | static_cast<void (QLValue::*)(double)>(&QLValue::set_double_value), data); |
513 | 205 | case DECIMAL: { |
514 | 205 | string value; |
515 | 205 | RETURN_NOT_OK(CQLDecodeBytes(len, data, &value)); |
516 | 205 | Decimal decimal; |
517 | 205 | RETURN_NOT_OK(decimal.DecodeFromSerializedBigDecimal(value)); |
518 | 205 | set_decimal_value(decimal.EncodeToComparable()); |
519 | 205 | return Status::OK(); |
520 | 205 | } |
521 | 4 | case VARINT: { |
522 | 4 | string value; |
523 | 4 | RETURN_NOT_OK(CQLDecodeBytes(len, data, &value)); |
524 | 4 | util::VarInt varint; |
525 | 4 | RETURN_NOT_OK(varint.DecodeFromTwosComplement(value)); |
526 | 4 | set_varint_value(varint); |
527 | 4 | return Status::OK(); |
528 | 4 | } |
529 | 16.2M | case STRING: |
530 | 16.2M | return CQLDecodeBytes(len, data, mutable_string_value()); |
531 | 171k | case BOOL: { |
532 | 171k | uint8_t value = 0; |
533 | 171k | RETURN_NOT_OK(CQLDecodeNum(len, Load8, data, &value)); |
534 | 171k | set_bool_value(value != 0); |
535 | 171k | return Status::OK(); |
536 | 171k | } |
537 | 439k | case BINARY: |
538 | 439k | return CQLDecodeBytes(len, data, mutable_binary_value()); |
539 | 670k | case TIMESTAMP: { |
540 | 670k | int64_t value = 0; |
541 | 670k | RETURN_NOT_OK(CQLDecodeNum(len, NetworkByteOrder::Load64, data, &value)); |
542 | 670k | value = DateTime::AdjustPrecision(value, |
543 | 670k | DateTime::CqlInputFormat.input_precision, |
544 | 670k | DateTime::kInternalPrecision); |
545 | 670k | set_timestamp_value(value); |
546 | 670k | return Status::OK(); |
547 | 670k | } |
548 | 339 | case DATE: { |
549 | 339 | uint32_t value = 0; |
550 | 339 | RETURN_NOT_OK(CQLDecodeNum(len, NetworkByteOrder::Load32, data, &value)); |
551 | 339 | set_date_value(value); |
552 | 339 | return Status::OK(); |
553 | 339 | } |
554 | 339 | case TIME: { |
555 | 339 | int64_t value = 0; |
556 | 339 | RETURN_NOT_OK(CQLDecodeNum(len, NetworkByteOrder::Load64, data, &value)); |
557 | 339 | set_time_value(value); |
558 | 339 | return Status::OK(); |
559 | 339 | } |
560 | 873k | case INET: { |
561 | 873k | string bytes; |
562 | 873k | RETURN_NOT_OK(CQLDecodeBytes(len, data, &bytes)); |
563 | 873k | InetAddress addr; |
564 | 873k | RETURN_NOT_OK(addr.FromBytes(bytes)); |
565 | 873k | set_inetaddress_value(addr); |
566 | 873k | return Status::OK(); |
567 | 873k | } |
568 | 220 | case JSONB: { |
569 | 220 | string json; |
570 | 220 | RETURN_NOT_OK(CQLDecodeBytes(len, data, &json)); |
571 | 220 | Jsonb jsonb; |
572 | 220 | RETURN_NOT_OK(jsonb.FromString(json)); |
573 | 220 | set_jsonb_value(jsonb.MoveSerializedJsonb()); |
574 | 220 | return Status::OK(); |
575 | 220 | } |
576 | 270k | case UUID: { |
577 | 270k | string bytes; |
578 | 270k | RETURN_NOT_OK(CQLDecodeBytes(len, data, &bytes)); |
579 | 270k | Uuid uuid; |
580 | 270k | RETURN_NOT_OK(uuid.FromBytes(bytes)); |
581 | 270k | set_uuid_value(uuid); |
582 | 270k | return Status::OK(); |
583 | 270k | } |
584 | 4 | case TIMEUUID: { |
585 | 4 | string bytes; |
586 | 4 | RETURN_NOT_OK(CQLDecodeBytes(len, data, &bytes)); |
587 | 4 | Uuid uuid; |
588 | 4 | RETURN_NOT_OK(uuid.FromBytes(bytes)); |
589 | 4 | RETURN_NOT_OK(uuid.IsTimeUuid()); |
590 | 4 | set_timeuuid_value(uuid); |
591 | 4 | return Status::OK(); |
592 | 4 | } |
593 | 418k | case MAP: { |
594 | 418k | const shared_ptr<QLType>& keys_type = ql_type->param_type(0); |
595 | 418k | const shared_ptr<QLType>& values_type = ql_type->param_type(1); |
596 | 418k | set_map_value(); |
597 | 418k | int32_t nr_elems = 0; |
598 | 418k | RETURN_NOT_OK(CQLDecodeNum(sizeof(nr_elems), NetworkByteOrder::Load32, data, &nr_elems)); |
599 | 1.31M | for (int i = 0; i < nr_elems; i++) { |
600 | 898k | QLValue key; |
601 | 898k | RETURN_NOT_OK(key.Deserialize(keys_type, client, data)); |
602 | 898k | RETURN_NOT_OK(CheckForNull(key)); |
603 | 898k | *add_map_key() = std::move(*key.mutable_value()); |
604 | 898k | QLValue value; |
605 | 898k | RETURN_NOT_OK(value.Deserialize(values_type, client, data)); |
606 | 898k | RETURN_NOT_OK(CheckForNull(value)); |
607 | 898k | *add_map_value() = std::move(*value.mutable_value()); |
608 | 898k | } |
609 | 418k | return Status::OK(); |
610 | 418k | } |
611 | 214k | case SET: { |
612 | 214k | const shared_ptr<QLType>& elems_type = ql_type->param_type(0); |
613 | 214k | set_set_value(); |
614 | 214k | int32_t nr_elems = 0; |
615 | 214k | RETURN_NOT_OK(CQLDecodeNum(sizeof(nr_elems), NetworkByteOrder::Load32, data, &nr_elems)); |
616 | 429k | for (int i = 0; i < nr_elems; i++) { |
617 | 214k | QLValue elem; |
618 | 214k | RETURN_NOT_OK(elem.Deserialize(elems_type, client, data)); |
619 | 214k | RETURN_NOT_OK(CheckForNull(elem)); |
620 | 214k | *add_set_elem() = std::move(*elem.mutable_value()); |
621 | 214k | } |
622 | 214k | return Status::OK(); |
623 | 214k | } |
624 | 761 | case LIST: { |
625 | 761 | const shared_ptr<QLType>& elems_type = ql_type->param_type(0); |
626 | 761 | set_list_value(); |
627 | 761 | int32_t nr_elems = 0; |
628 | 761 | RETURN_NOT_OK(CQLDecodeNum(sizeof(nr_elems), NetworkByteOrder::Load32, data, &nr_elems)); |
629 | 6.26k | for (int i = 0; i < nr_elems; i++) { |
630 | 5.50k | QLValue elem; |
631 | 5.50k | RETURN_NOT_OK(elem.Deserialize(elems_type, client, data)); |
632 | 5.50k | RETURN_NOT_OK(CheckForNull(elem)); |
633 | 5.50k | *add_list_elem() = std::move(*elem.mutable_value()); |
634 | 5.50k | } |
635 | 761 | return Status::OK(); |
636 | 761 | } |
637 | | |
638 | 11 | case USER_DEFINED_TYPE: { |
639 | 11 | set_map_value(); |
640 | 11 | int fields_size = narrow_cast<int>(ql_type->udtype_field_names().size()); |
641 | 33 | for (int i = 0; i < fields_size; i++) { |
642 | | // TODO (mihnea) default to null if value missing (CQL behavior) |
643 | 22 | QLValue value; |
644 | 22 | RETURN_NOT_OK(value.Deserialize(ql_type->param_type(i), client, data)); |
645 | 22 | if (!value.IsNull()) { |
646 | 19 | add_map_key()->set_int16_value(i); |
647 | 19 | *add_map_value() = std::move(*value.mutable_value()); |
648 | 19 | } |
649 | 22 | } |
650 | 11 | return Status::OK(); |
651 | 11 | } |
652 | | |
653 | 53 | case FROZEN: { |
654 | 53 | set_frozen_value(); |
655 | 53 | const auto& type = ql_type->param_type(0); |
656 | 53 | switch (type->main()) { |
657 | 3 | case MAP: { |
658 | 3 | std::map<QLValue, QLValue> map_values; |
659 | 3 | const shared_ptr<QLType> &keys_type = type->param_type(0); |
660 | 3 | const shared_ptr<QLType> &values_type = type->param_type(1); |
661 | 3 | int32_t nr_elems = 0; |
662 | 3 | RETURN_NOT_OK(CQLDecodeNum(sizeof(nr_elems), NetworkByteOrder::Load32, data, &nr_elems)); |
663 | 9 | for (int i = 0; i < nr_elems; i++) { |
664 | 6 | QLValue key; |
665 | 6 | RETURN_NOT_OK(key.Deserialize(keys_type, client, data)); |
666 | 6 | RETURN_NOT_OK(CheckForNull(key)); |
667 | 6 | QLValue value; |
668 | 6 | RETURN_NOT_OK(value.Deserialize(values_type, client, data)); |
669 | 6 | RETURN_NOT_OK(CheckForNull(key)); |
670 | 6 | map_values[key] = value; |
671 | 6 | } |
672 | | |
673 | 6 | for (auto &pair : map_values) { |
674 | 6 | *add_frozen_elem() = std::move(pair.first.value()); |
675 | 6 | *add_frozen_elem() = std::move(pair.second.value()); |
676 | 6 | } |
677 | | |
678 | 3 | return Status::OK(); |
679 | 3 | } |
680 | 8 | case SET: { |
681 | 8 | const shared_ptr<QLType> &elems_type = type->param_type(0); |
682 | 8 | int32_t nr_elems = 0; |
683 | | |
684 | 8 | std::set<QLValue> set_values; |
685 | 8 | RETURN_NOT_OK(CQLDecodeNum(sizeof(nr_elems), NetworkByteOrder::Load32, data, &nr_elems)); |
686 | 24 | for (int i = 0; i < nr_elems; i++) { |
687 | 16 | QLValue elem; |
688 | 16 | RETURN_NOT_OK(elem.Deserialize(elems_type, client, data)); |
689 | 16 | RETURN_NOT_OK(CheckForNull(elem)); |
690 | 16 | set_values.insert(std::move(elem)); |
691 | 16 | } |
692 | 16 | for (auto &elem : set_values) { |
693 | 16 | *add_frozen_elem() = std::move(elem.value()); |
694 | 16 | } |
695 | 8 | return Status::OK(); |
696 | 8 | } |
697 | 3 | case LIST: { |
698 | 3 | const shared_ptr<QLType> &elems_type = type->param_type(0); |
699 | 3 | int32_t nr_elems = 0; |
700 | 3 | RETURN_NOT_OK(CQLDecodeNum(sizeof(nr_elems), NetworkByteOrder::Load32, data, &nr_elems)); |
701 | 7 | for (int i = 0; i < nr_elems; i++) { |
702 | 4 | QLValue elem; |
703 | 4 | RETURN_NOT_OK(elem.Deserialize(elems_type, client, data)); |
704 | 4 | RETURN_NOT_OK(CheckForNull(elem)); |
705 | 4 | *add_frozen_elem() = std::move(*elem.mutable_value()); |
706 | 4 | } |
707 | 3 | return Status::OK(); |
708 | 3 | } |
709 | | |
710 | 39 | case USER_DEFINED_TYPE: { |
711 | 39 | const int fields_size = narrow_cast<int>(type->udtype_field_names().size()); |
712 | 112 | for (int i = 0; i < fields_size; i++) { |
713 | | // TODO (mihnea) default to null if value missing (CQL behavior) |
714 | 73 | QLValue value; |
715 | 73 | RETURN_NOT_OK(value.Deserialize(type->param_type(i), client, data)); |
716 | 73 | *add_frozen_elem() = std::move(*value.mutable_value()); |
717 | 73 | } |
718 | 39 | return Status::OK(); |
719 | 39 | } |
720 | 0 | default: |
721 | 0 | break; |
722 | | |
723 | 0 | } |
724 | 0 | break; |
725 | 0 | } |
726 | |
|
727 | 0 | QL_UNSUPPORTED_TYPES_IN_SWITCH: |
728 | 0 | break; |
729 | |
|
730 | 0 | QL_INVALID_TYPES_IN_SWITCH: |
731 | 0 | break; |
732 | | |
733 | | // default: fall through |
734 | 0 | } |
735 | | |
736 | 0 | LOG(FATAL) << "Internal error: unsupported type " << ql_type->ToString(); |
737 | 0 | return STATUS(InternalError, "unsupported type"); |
738 | 0 | } |
739 | | |
740 | 160k | string QLValue::ToValueString(const QuotesType quotes_type) const { |
741 | 160k | if (IsNull()) { |
742 | 373 | return "null"; |
743 | 373 | } |
744 | | |
745 | 160k | switch (type()) { |
746 | 38.8k | case InternalType::kInt8Value: return to_string(int8_value()); |
747 | 19.4k | case InternalType::kInt16Value: return to_string(int16_value()); |
748 | 32.9k | case InternalType::kInt32Value: return to_string(int32_value()); |
749 | 9 | case InternalType::kInt64Value: return to_string(int64_value()); |
750 | 0 | case InternalType::kUint32Value: return to_string(uint32_value()); |
751 | 0 | case InternalType::kUint64Value: return to_string(uint64_value()); |
752 | 5 | case InternalType::kFloatValue: return to_string(float_value()); |
753 | 1 | case InternalType::kDoubleValue: return to_string(double_value()); |
754 | 2 | case InternalType::kDecimalValue: |
755 | 2 | return util::DecimalFromComparable(decimal_value()).ToString(); |
756 | 9 | case InternalType::kVarintValue: return varint_value().ToString(); |
757 | 68.9k | case InternalType::kStringValue: return FormatBytesAsStr(string_value(), quotes_type); |
758 | 1 | case InternalType::kTimestampValue: return timestamp_value().ToFormattedString(); |
759 | 1 | case InternalType::kDateValue: return to_string(date_value()); |
760 | 1 | case InternalType::kTimeValue: return to_string(time_value()); |
761 | 1 | case InternalType::kInetaddressValue: return inetaddress_value().ToString(); |
762 | 1 | case InternalType::kJsonbValue: return FormatBytesAsStr(jsonb_value(), quotes_type); |
763 | 1 | case InternalType::kUuidValue: return uuid_value().ToString(); |
764 | 1 | case InternalType::kTimeuuidValue: return timeuuid_value().ToString(); |
765 | 205 | case InternalType::kBoolValue: return (bool_value() ? "true" : "false"); |
766 | 1 | case InternalType::kBinaryValue: return "0x" + b2a_hex(binary_value()); |
767 | | |
768 | 4 | case InternalType::kMapValue: { |
769 | 4 | std::stringstream ss; |
770 | 4 | QLMapValuePB map = map_value(); |
771 | 4 | DCHECK_EQ(map.keys_size(), map.values_size()); |
772 | 4 | ss << "{"; |
773 | 18 | for (int i = 0; i < map.keys_size(); i++) { |
774 | 14 | if (i > 0) { |
775 | 10 | ss << ", "; |
776 | 10 | } |
777 | 14 | ss << QLValue(map.keys(i)).ToString() << " -> " |
778 | 14 | << QLValue(map.values(i)).ToString(); |
779 | 14 | } |
780 | 4 | ss << "}"; |
781 | 4 | return ss.str(); |
782 | 0 | } |
783 | 1 | case InternalType::kSetValue: { |
784 | 1 | std::stringstream ss; |
785 | 1 | QLSeqValuePB set = set_value(); |
786 | 1 | ss << "{"; |
787 | 3 | for (int i = 0; i < set.elems_size(); i++) { |
788 | 2 | if (i > 0) { |
789 | 1 | ss << ", "; |
790 | 1 | } |
791 | 2 | ss << QLValue(set.elems(i)).ToString(); |
792 | 2 | } |
793 | 1 | ss << "}"; |
794 | 1 | return ss.str(); |
795 | 0 | } |
796 | 1 | case InternalType::kListValue: { |
797 | 1 | std::stringstream ss; |
798 | 1 | QLSeqValuePB list = list_value(); |
799 | 1 | ss << "["; |
800 | 3 | for (int i = 0; i < list.elems_size(); i++) { |
801 | 2 | if (i > 0) { |
802 | 1 | ss << ", "; |
803 | 1 | } |
804 | 2 | ss << QLValue(list.elems(i)).ToString(); |
805 | 2 | } |
806 | 1 | ss << "]"; |
807 | 1 | return ss.str(); |
808 | 0 | } |
809 | | |
810 | 1 | case InternalType::kFrozenValue: { |
811 | 1 | std::stringstream ss; |
812 | 1 | QLSeqValuePB frozen = frozen_value(); |
813 | 1 | ss << "frozen:<"; |
814 | 3 | for (int i = 0; i < frozen.elems_size(); i++) { |
815 | 2 | if (i > 0) { |
816 | 1 | ss << ", "; |
817 | 1 | } |
818 | 2 | ss << QLValue(frozen.elems(i)).ToString(); |
819 | 2 | } |
820 | 1 | ss << ">"; |
821 | 1 | return ss.str(); |
822 | 0 | } |
823 | 0 | case InternalType::kVirtualValue: |
824 | 0 | if (IsMax()) { |
825 | 0 | return "<MAX_LIMIT>"; |
826 | 0 | } |
827 | 0 | return "<MIN_LIMIT>"; |
828 | 0 | case InternalType::kGinNullValue: { |
829 | 0 | switch (gin_null_value()) { |
830 | | // case 0, gin:norm-key, should not exist since the actual data would be used instead. |
831 | 0 | case 1: |
832 | 0 | return "gin:null-key"; |
833 | 0 | case 2: |
834 | 0 | return "gin:empty-item"; |
835 | 0 | case 3: |
836 | 0 | return "gin:null-item"; |
837 | | // case -1, gin:empty-query, should not exist since that's internal to postgres. |
838 | 0 | default: |
839 | 0 | LOG(FATAL) << "Unexpected gin null category: " << gin_null_value(); |
840 | 0 | } |
841 | 0 | } |
842 | |
|
843 | 0 | case InternalType::VALUE_NOT_SET: |
844 | 0 | LOG(FATAL) << "Internal error: value should not be null"; |
845 | 0 | return "null"; |
846 | | // default: fall through |
847 | 0 | } |
848 | | |
849 | 0 | LOG(FATAL) << "Internal error: unknown or unsupported type " << type(); |
850 | 0 | return "unknown"; |
851 | 0 | } |
852 | | |
853 | 159k | string QLValue::ToString() const { |
854 | 159k | if (IsNull()) { |
855 | 634 | return "null"; |
856 | 634 | } |
857 | | |
858 | 159k | std::string res; |
859 | 159k | switch (type()) { |
860 | 38.8k | case InternalType::kInt8Value: res = "int8:"; break; |
861 | 19.4k | case InternalType::kInt16Value: res = "int16:"; break; |
862 | 31.9k | case InternalType::kInt32Value: res = "int32:"; break; |
863 | 1 | case InternalType::kInt64Value: res = "int64:"; break; |
864 | 0 | case InternalType::kUint32Value: res = "uint32:"; break; |
865 | 0 | case InternalType::kUint64Value: res = "uint64:"; break; |
866 | 5 | case InternalType::kFloatValue: res = "float:"; break; |
867 | 1 | case InternalType::kDoubleValue: res = "double:"; break; |
868 | 2 | case InternalType::kDecimalValue: res = "decimal: "; break; |
869 | 1 | case InternalType::kVarintValue: res = "varint: "; break; |
870 | 68.8k | case InternalType::kStringValue: res = "string:"; break; |
871 | 1 | case InternalType::kTimestampValue: res = "timestamp:"; break; |
872 | 1 | case InternalType::kDateValue: res = "date:"; break; |
873 | 1 | case InternalType::kTimeValue: res = "time:"; break; |
874 | 1 | case InternalType::kInetaddressValue: res = "inetaddress:"; break; |
875 | 1 | case InternalType::kJsonbValue: res = "jsonb:"; break; |
876 | 1 | case InternalType::kUuidValue: res = "uuid:"; break; |
877 | 1 | case InternalType::kTimeuuidValue: res = "timeuuid:"; break; |
878 | 1 | case InternalType::kBoolValue: res = "bool:"; break; |
879 | 1 | case InternalType::kBinaryValue: res = "binary:0x"; break; |
880 | 4 | case InternalType::kMapValue: res = "map:"; break; |
881 | 1 | case InternalType::kSetValue: res = "set:"; break; |
882 | 1 | case InternalType::kListValue: res = "list:"; break; |
883 | 1 | case InternalType::kFrozenValue: res = "frozen:"; break; |
884 | 0 | case InternalType::kVirtualValue: res = ""; break; |
885 | | |
886 | 0 | case InternalType::VALUE_NOT_SET: |
887 | 0 | LOG(FATAL) << "Internal error: value should not be null"; |
888 | 0 | return "null"; |
889 | 0 | default: |
890 | 0 | LOG(FATAL) << "Internal error: unknown or unsupported type " << type(); |
891 | 0 | return "unknown"; |
892 | 159k | } |
893 | 159k | return res + ToValueString(); |
894 | 159k | } |
895 | | |
896 | 1.25M | InetAddress QLValue::inetaddress_value(const QLValuePB& pb) { |
897 | 1.25M | InetAddress addr; |
898 | 1.25M | CHECK_OK(addr.FromBytes(inetaddress_value_pb(pb))); |
899 | 1.25M | return addr; |
900 | 1.25M | } |
901 | | |
902 | 885 | Uuid QLValue::timeuuid_value(const QLValuePB& pb) { |
903 | 885 | Uuid timeuuid; |
904 | 885 | CHECK_OK(timeuuid.FromBytes(timeuuid_value_pb(pb))); |
905 | 885 | CHECK_OK(timeuuid.IsTimeUuid()); |
906 | 885 | return timeuuid; |
907 | 885 | } |
908 | | |
909 | 369k | Uuid QLValue::uuid_value(const QLValuePB& pb) { |
910 | 369k | Uuid uuid; |
911 | 369k | CHECK_OK(uuid.FromBytes(uuid_value_pb(pb))); |
912 | 369k | return uuid; |
913 | 369k | } |
914 | | |
915 | 11.1k | util::VarInt QLValue::varint_value(const QLValuePB& pb) { |
916 | 0 | CHECK(pb.has_varint_value()) << "Value: " << pb.ShortDebugString(); |
917 | 11.1k | util::VarInt varint; |
918 | 11.1k | size_t num_decoded_bytes; |
919 | 11.1k | CHECK_OK(varint.DecodeFromComparable(pb.varint_value(), &num_decoded_bytes)); |
920 | 11.1k | return varint; |
921 | 11.1k | } |
922 | | |
923 | 1.50M | void QLValue::set_inetaddress_value(const InetAddress& val, QLValuePB* pb) { |
924 | 1.50M | CHECK_OK(val.ToBytes(pb->mutable_inetaddress_value())); |
925 | 1.50M | } |
926 | | |
927 | 527 | void QLValue::set_timeuuid_value(const Uuid& val) { |
928 | 527 | CHECK_OK(val.IsTimeUuid()); |
929 | 527 | val.ToBytes(pb_.mutable_timeuuid_value()); |
930 | 527 | } |
931 | | |
932 | | template<typename num_type, typename data_type> |
933 | | CHECKED_STATUS QLValue::CQLDeserializeNum( |
934 | | size_t len, data_type (*converter)(const void*), void (QLValue::*setter)(num_type), |
935 | 2.50M | Slice* data) { |
936 | 2.50M | num_type value = 0; |
937 | 2.50M | RETURN_NOT_OK(CQLDecodeNum(len, converter, data, &value)); |
938 | 2.50M | (this->*setter)(value); |
939 | 2.50M | return Status::OK(); |
940 | 2.50M | } _ZN2yb7QLValue17CQLDeserializeNumIahEENS_6StatusEmPFT0_PKvEMS0_FvT_EPNS_5SliceE Line | Count | Source | 935 | 40.5k | Slice* data) { | 936 | 40.5k | num_type value = 0; | 937 | 40.5k | RETURN_NOT_OK(CQLDecodeNum(len, converter, data, &value)); | 938 | 40.5k | (this->*setter)(value); | 939 | 40.5k | return Status::OK(); | 940 | 40.5k | } |
_ZN2yb7QLValue17CQLDeserializeNumIstEENS_6StatusEmPFT0_PKvEMS0_FvT_EPNS_5SliceE Line | Count | Source | 935 | 21.3k | Slice* data) { | 936 | 21.3k | num_type value = 0; | 937 | 21.3k | RETURN_NOT_OK(CQLDecodeNum(len, converter, data, &value)); | 938 | 21.3k | (this->*setter)(value); | 939 | 21.3k | return Status::OK(); | 940 | 21.3k | } |
_ZN2yb7QLValue17CQLDeserializeNumIijEENS_6StatusEmPFT0_PKvEMS0_FvT_EPNS_5SliceE Line | Count | Source | 935 | 1.80M | Slice* data) { | 936 | 1.80M | num_type value = 0; | 937 | 1.80M | RETURN_NOT_OK(CQLDecodeNum(len, converter, data, &value)); | 938 | 1.80M | (this->*setter)(value); | 939 | 1.80M | return Status::OK(); | 940 | 1.80M | } |
_ZN2yb7QLValue17CQLDeserializeNumIxyEENS_6StatusEmPFT0_PKvEMS0_FvT_EPNS_5SliceE Line | Count | Source | 935 | 639k | Slice* data) { | 936 | 639k | num_type value = 0; | 937 | 639k | RETURN_NOT_OK(CQLDecodeNum(len, converter, data, &value)); | 938 | 639k | (this->*setter)(value); | 939 | 639k | return Status::OK(); | 940 | 639k | } |
|
941 | | |
942 | | template<typename float_type, typename data_type> |
943 | | CHECKED_STATUS QLValue::CQLDeserializeFloat( |
944 | | size_t len, data_type (*converter)(const void*), void (QLValue::*setter)(float_type), |
945 | 204 | Slice* data) { |
946 | 204 | float_type value = 0.0; |
947 | 204 | RETURN_NOT_OK(CQLDecodeFloat(len, converter, data, &value)); |
948 | 204 | (this->*setter)(value); |
949 | 204 | return Status::OK(); |
950 | 204 | } _ZN2yb7QLValue19CQLDeserializeFloatIfjEENS_6StatusEmPFT0_PKvEMS0_FvT_EPNS_5SliceE Line | Count | Source | 945 | 87 | Slice* data) { | 946 | 87 | float_type value = 0.0; | 947 | 87 | RETURN_NOT_OK(CQLDecodeFloat(len, converter, data, &value)); | 948 | 87 | (this->*setter)(value); | 949 | 87 | return Status::OK(); | 950 | 87 | } |
_ZN2yb7QLValue19CQLDeserializeFloatIdyEENS_6StatusEmPFT0_PKvEMS0_FvT_EPNS_5SliceE Line | Count | Source | 945 | 117 | Slice* data) { | 946 | 117 | float_type value = 0.0; | 947 | 117 | RETURN_NOT_OK(CQLDecodeFloat(len, converter, data, &value)); | 948 | 117 | (this->*setter)(value); | 949 | 117 | return Status::OK(); | 950 | 117 | } |
|
951 | | |
952 | | //----------------------------------- QLValuePB operators -------------------------------- |
953 | | |
954 | 600k | InternalType type(const QLValuePB& v) { |
955 | 600k | return v.value_case(); |
956 | 600k | } |
957 | 36.8M | bool IsNull(const QLValuePB& v) { |
958 | 36.8M | return v.value_case() == QLValuePB::VALUE_NOT_SET; |
959 | 36.8M | } |
960 | 22.1M | void SetNull(QLValuePB* v) { |
961 | 22.1M | v->Clear(); |
962 | 22.1M | } |
963 | 3.41k | bool EitherIsNull(const QLValuePB& lhs, const QLValuePB& rhs) { |
964 | 3.41k | return IsNull(lhs) || IsNull(rhs); |
965 | 3.41k | } |
966 | 3.86M | bool BothNotNull(const QLValuePB& lhs, const QLValuePB& rhs) { |
967 | 3.86M | return !IsNull(lhs) && !IsNull(rhs); |
968 | 3.86M | } |
969 | 379k | bool BothNull(const QLValuePB& lhs, const QLValuePB& rhs) { |
970 | 379k | return IsNull(lhs) && IsNull(rhs); |
971 | 379k | } |
972 | 0 | bool EitherIsVirtual(const QLValuePB& lhs, const QLValuePB& rhs) { |
973 | 0 | return lhs.value_case() == QLValuePB::kVirtualValue || |
974 | 0 | rhs.value_case() == QLValuePB::kVirtualValue; |
975 | 0 | } |
976 | 3.03M | bool Comparable(const QLValuePB& lhs, const QLValuePB& rhs) { |
977 | 3.03M | return (lhs.value_case() == rhs.value_case() || |
978 | 3.41k | EitherIsNull(lhs, rhs) || |
979 | 0 | EitherIsVirtual(lhs, rhs)); |
980 | 3.03M | } |
981 | 0 | bool EitherIsNull(const QLValuePB& lhs, const QLValue& rhs) { |
982 | 0 | return IsNull(lhs) || rhs.IsNull(); |
983 | 0 | } |
984 | 0 | bool EitherIsVirtual(const QLValuePB& lhs, const QLValue& rhs) { |
985 | 0 | return lhs.value_case() == QLValuePB::kVirtualValue || rhs.IsVirtual(); |
986 | 0 | } |
987 | 598k | bool Comparable(const QLValuePB& lhs, const QLValue& rhs) { |
988 | 598k | return (lhs.value_case() == rhs.type() || |
989 | 0 | EitherIsNull(lhs, rhs) || |
990 | 0 | EitherIsVirtual(lhs, rhs)); |
991 | 598k | } |
992 | 1.19M | bool BothNotNull(const QLValuePB& lhs, const QLValue& rhs) { |
993 | 1.19M | return !IsNull(lhs) && !rhs.IsNull(); |
994 | 1.19M | } |
995 | 507k | bool BothNull(const QLValuePB& lhs, const QLValue& rhs) { |
996 | 507k | return IsNull(lhs) && rhs.IsNull(); |
997 | 507k | } |
998 | 1.93M | int Compare(const QLValuePB& lhs, const QLValuePB& rhs) { |
999 | 1.93M | if (rhs.value_case() == QLValuePB::kVirtualValue && |
1000 | 0 | lhs.value_case() != QLValuePB::kVirtualValue) { |
1001 | 0 | return -Compare(rhs, lhs); |
1002 | 0 | } |
1003 | 1.93M | CHECK(Comparable(lhs, rhs)); |
1004 | 1.93M | CHECK(BothNotNull(lhs, rhs)); |
1005 | 1.93M | switch (lhs.value_case()) { |
1006 | 10.3k | case QLValuePB::kInt8Value: return GenericCompare(lhs.int8_value(), rhs.int8_value()); |
1007 | 154k | case QLValuePB::kInt16Value: return GenericCompare(lhs.int16_value(), rhs.int16_value()); |
1008 | 545k | case QLValuePB::kInt32Value: return GenericCompare(lhs.int32_value(), rhs.int32_value()); |
1009 | 991k | case QLValuePB::kInt64Value: return GenericCompare(lhs.int64_value(), rhs.int64_value()); |
1010 | 0 | case QLValuePB::kUint32Value: return GenericCompare(lhs.uint32_value(), rhs.uint32_value()); |
1011 | 0 | case QLValuePB::kUint64Value: return GenericCompare(lhs.uint64_value(), rhs.uint64_value()); |
1012 | 598 | case QLValuePB::kFloatValue: { |
1013 | 598 | bool is_nan_0 = util::IsNanFloat(lhs.float_value()); |
1014 | 598 | bool is_nan_1 = util::IsNanFloat(rhs.float_value()); |
1015 | 598 | if (is_nan_0 && is_nan_1) return 0; |
1016 | 594 | if (is_nan_0 && !is_nan_1) return 1; |
1017 | 569 | if (!is_nan_0 && is_nan_1) return -1; |
1018 | 567 | return GenericCompare(lhs.float_value(), rhs.float_value()); |
1019 | 567 | } |
1020 | 611 | case QLValuePB::kDoubleValue: { |
1021 | 611 | bool is_nan_0 = util::IsNanDouble(lhs.double_value()); |
1022 | 611 | bool is_nan_1 = util::IsNanDouble(rhs.double_value()); |
1023 | 611 | if (is_nan_0 && is_nan_1) return 0; |
1024 | 607 | if (is_nan_0 && !is_nan_1) return 1; |
1025 | 582 | if (!is_nan_0 && is_nan_1) return -1; |
1026 | 580 | return GenericCompare(lhs.double_value(), rhs.double_value()); |
1027 | 580 | } |
1028 | | // Encoded decimal is byte-comparable. |
1029 | 10.3k | case QLValuePB::kDecimalValue: return lhs.decimal_value().compare(rhs.decimal_value()); |
1030 | 10.2k | case QLValuePB::kVarintValue: return lhs.varint_value().compare(rhs.varint_value()); |
1031 | 205k | case QLValuePB::kStringValue: return lhs.string_value().compare(rhs.string_value()); |
1032 | 708 | case QLValuePB::kBoolValue: return Compare(lhs.bool_value(), rhs.bool_value()); |
1033 | 381 | case QLValuePB::kTimestampValue: |
1034 | 381 | return GenericCompare(lhs.timestamp_value(), rhs.timestamp_value()); |
1035 | 354 | case QLValuePB::kDateValue: return GenericCompare(lhs.date_value(), rhs.date_value()); |
1036 | 311 | case QLValuePB::kTimeValue: return GenericCompare(lhs.time_value(), rhs.time_value()); |
1037 | 8 | case QLValuePB::kBinaryValue: return lhs.binary_value().compare(rhs.binary_value()); |
1038 | 187 | case QLValuePB::kInetaddressValue: |
1039 | 187 | return GenericCompare(lhs.inetaddress_value(), rhs.inetaddress_value()); |
1040 | 105 | case QLValuePB::kJsonbValue: |
1041 | 105 | return GenericCompare(lhs.jsonb_value(), rhs.jsonb_value()); |
1042 | 1.05k | case QLValuePB::kUuidValue: |
1043 | 1.05k | return GenericCompare(QLValue::uuid_value(lhs), QLValue::uuid_value(rhs)); |
1044 | 208 | case QLValuePB::kTimeuuidValue: |
1045 | 208 | return GenericCompare(QLValue::timeuuid_value(lhs), QLValue::timeuuid_value(rhs)); |
1046 | 111 | case QLValuePB::kFrozenValue: |
1047 | 111 | return Compare(lhs.frozen_value(), rhs.frozen_value()); |
1048 | 0 | case QLValuePB::kMapValue: FALLTHROUGH_INTENDED; |
1049 | 0 | case QLValuePB::kSetValue: FALLTHROUGH_INTENDED; |
1050 | 0 | case QLValuePB::kListValue: |
1051 | 0 | LOG(FATAL) << "Internal error: collection types are not comparable"; |
1052 | 0 | return 0; |
1053 | 0 | case QLValuePB::VALUE_NOT_SET: |
1054 | 0 | LOG(FATAL) << "Internal error: value should not be null"; |
1055 | 0 | case QLValuePB::kVirtualValue: |
1056 | 0 | if (lhs.virtual_value() == QLVirtualValuePB::LIMIT_MAX) { |
1057 | 0 | return (rhs.value_case() == QLValuePB::kVirtualValue && |
1058 | 0 | rhs.virtual_value() == QLVirtualValuePB::LIMIT_MAX) ? 0 : 1; |
1059 | 0 | } else { |
1060 | 0 | return (rhs.value_case() == QLValuePB::kVirtualValue && |
1061 | 0 | rhs.virtual_value() == QLVirtualValuePB::LIMIT_MIN) ? 0 : -1; |
1062 | 0 | } |
1063 | 0 | break; |
1064 | 0 | case QLValuePB::kGinNullValue: |
1065 | 0 | return GenericCompare(lhs.gin_null_value(), rhs.gin_null_value()); |
1066 | | |
1067 | | // default: fall through |
1068 | 0 | } |
1069 | | |
1070 | 0 | LOG(FATAL) << "Internal error: unknown or unsupported type " << lhs.value_case(); |
1071 | 0 | return 0; |
1072 | 0 | } |
1073 | | |
1074 | 600k | int Compare(const QLValuePB& lhs, const QLValue& rhs) { |
1075 | 600k | if (rhs.IsVirtual() && lhs.value_case() != QLValuePB::kVirtualValue) { |
1076 | 0 | return -Compare(rhs.value(), lhs); |
1077 | 0 | } |
1078 | 600k | CHECK(Comparable(lhs, rhs)); |
1079 | 600k | CHECK(BothNotNull(lhs, rhs)); |
1080 | 600k | switch (type(lhs)) { |
1081 | 0 | case QLValuePB::kInt8Value: |
1082 | 0 | return GenericCompare(static_cast<int8_t>(lhs.int8_value()), rhs.int8_value()); |
1083 | 0 | case QLValuePB::kInt16Value: |
1084 | 0 | return GenericCompare(static_cast<int16_t>(lhs.int16_value()), rhs.int16_value()); |
1085 | 0 | case QLValuePB::kInt32Value: return GenericCompare(lhs.int32_value(), rhs.int32_value()); |
1086 | 0 | case QLValuePB::kInt64Value: return GenericCompare(lhs.int64_value(), rhs.int64_value()); |
1087 | 0 | case QLValuePB::kUint32Value: return GenericCompare(lhs.uint32_value(), rhs.uint32_value()); |
1088 | 0 | case QLValuePB::kUint64Value: return GenericCompare(lhs.uint64_value(), rhs.uint64_value()); |
1089 | 0 | case QLValuePB::kFloatValue: { |
1090 | 0 | bool is_nan_0 = util::IsNanFloat(lhs.float_value()); |
1091 | 0 | bool is_nan_1 = util::IsNanFloat(rhs.float_value()); |
1092 | 0 | if (is_nan_0 && is_nan_1) return 0; |
1093 | 0 | if (is_nan_0 && !is_nan_1) return 1; |
1094 | 0 | if (!is_nan_0 && is_nan_1) return -1; |
1095 | 0 | return GenericCompare(lhs.float_value(), rhs.float_value()); |
1096 | 0 | } |
1097 | 0 | case QLValuePB::kDoubleValue: { |
1098 | 0 | bool is_nan_0 = util::IsNanDouble(lhs.double_value()); |
1099 | 0 | bool is_nan_1 = util::IsNanDouble(rhs.double_value()); |
1100 | 0 | if (is_nan_0 && is_nan_1) return 0; |
1101 | 0 | if (is_nan_0 && !is_nan_1) return 1; |
1102 | 0 | if (!is_nan_0 && is_nan_1) return -1; |
1103 | 0 | return GenericCompare(lhs.double_value(), rhs.double_value()); |
1104 | 0 | } |
1105 | | // Encoded decimal is byte-comparable. |
1106 | 0 | case QLValuePB::kDecimalValue: return lhs.decimal_value().compare(rhs.decimal_value()); |
1107 | 0 | case QLValuePB::kVarintValue: return lhs.varint_value().compare(rhs.value().varint_value()); |
1108 | 599k | case QLValuePB::kStringValue: return lhs.string_value().compare(rhs.string_value()); |
1109 | 0 | case QLValuePB::kBoolValue: return Compare(lhs.bool_value(), rhs.bool_value()); |
1110 | 0 | case QLValuePB::kTimestampValue: |
1111 | 0 | return GenericCompare(lhs.timestamp_value(), rhs.timestamp_value_pb()); |
1112 | 0 | case QLValuePB::kDateValue: return GenericCompare(lhs.date_value(), rhs.date_value()); |
1113 | 0 | case QLValuePB::kTimeValue: return GenericCompare(lhs.time_value(), rhs.time_value()); |
1114 | 0 | case QLValuePB::kBinaryValue: return lhs.binary_value().compare(rhs.binary_value()); |
1115 | 301 | case QLValuePB::kInetaddressValue: |
1116 | 301 | return GenericCompare(QLValue::inetaddress_value(lhs), rhs.inetaddress_value()); |
1117 | 0 | case QLValuePB::kJsonbValue: |
1118 | 0 | return GenericCompare(QLValue::jsonb_value(lhs), rhs.jsonb_value()); |
1119 | 0 | case QLValuePB::kUuidValue: |
1120 | 0 | return GenericCompare(QLValue::uuid_value(lhs), rhs.uuid_value()); |
1121 | 0 | case QLValuePB::kTimeuuidValue: |
1122 | 0 | return GenericCompare(QLValue::timeuuid_value(lhs), rhs.timeuuid_value()); |
1123 | 0 | case QLValuePB::kFrozenValue: |
1124 | 0 | return Compare(lhs.frozen_value(), rhs.frozen_value()); |
1125 | 0 | case QLValuePB::kMapValue: FALLTHROUGH_INTENDED; |
1126 | 0 | case QLValuePB::kSetValue: FALLTHROUGH_INTENDED; |
1127 | 0 | case QLValuePB::kListValue: |
1128 | 0 | LOG(FATAL) << "Internal error: collection types are not comparable"; |
1129 | 0 | return 0; |
1130 | 0 | case QLValuePB::VALUE_NOT_SET: |
1131 | 0 | LOG(FATAL) << "Internal error: value should not be null"; |
1132 | 0 | break; |
1133 | 0 | case QLValuePB::kVirtualValue: |
1134 | 0 | if (lhs.virtual_value() == QLVirtualValuePB::LIMIT_MAX) { |
1135 | 0 | return rhs.IsMax() ? 0 : 1; |
1136 | 0 | } else { |
1137 | 0 | return rhs.IsMin() ? 0 : -1; |
1138 | 0 | } |
1139 | 0 | break; |
1140 | 0 | case QLValuePB::kGinNullValue: |
1141 | 0 | return GenericCompare(static_cast<uint8_t>(lhs.gin_null_value()), rhs.gin_null_value()); |
1142 | | |
1143 | | // default: fall through |
1144 | 0 | } |
1145 | | |
1146 | 0 | FATAL_INVALID_ENUM_VALUE(QLValuePB::ValueCase, type(lhs)); |
1147 | 0 | } |
1148 | | |
1149 | 126 | int Compare(const QLSeqValuePB& lhs, const QLSeqValuePB& rhs) { |
1150 | | // Compare elements one by one. |
1151 | 126 | int result = 0; |
1152 | 126 | int min_size = std::min(lhs.elems_size(), rhs.elems_size()); |
1153 | 248 | for (int i = 0; i < min_size; i++) { |
1154 | 193 | bool lhs_is_null = IsNull(lhs.elems(i)); |
1155 | 193 | bool rhs_is_null = IsNull(rhs.elems(i)); |
1156 | | |
1157 | 193 | if (lhs_is_null && rhs_is_null) result = 0; |
1158 | 185 | else if (lhs_is_null) result = -1; |
1159 | 181 | else if (rhs_is_null) result = 1; |
1160 | 181 | else |
1161 | 181 | result = Compare(lhs.elems(i), rhs.elems(i)); |
1162 | | |
1163 | 193 | if (result != 0) { |
1164 | 71 | return result; |
1165 | 71 | } |
1166 | 193 | } |
1167 | | |
1168 | | // If elements are equal, compare lengths. |
1169 | 55 | return GenericCompare(lhs.elems_size(), rhs.elems_size()); |
1170 | 126 | } |
1171 | | |
1172 | 710 | int Compare(const bool lhs, const bool rhs) { |
1173 | | // Using Cassandra semantics: true > false. |
1174 | 710 | if (lhs) { |
1175 | 357 | return rhs ? 0 : 1; |
1176 | 320 | } else { |
1177 | 286 | return rhs ? -1 : 0; |
1178 | 320 | } |
1179 | 710 | } |
1180 | | |
1181 | | // In YCQL null is not comparable with regular values (w.r.t. ordering). |
1182 | 514k | bool operator <(const QLValuePB& lhs, const QLValuePB& rhs) { |
1183 | 514k | return BothNotNull(lhs, rhs) && Compare(lhs, rhs) < 0; |
1184 | 514k | } |
1185 | 439k | bool operator >(const QLValuePB& lhs, const QLValuePB& rhs) { |
1186 | 439k | return BothNotNull(lhs, rhs) && Compare(lhs, rhs) > 0; |
1187 | 439k | } |
1188 | | |
1189 | | // In YCQL equality holds for null values. |
1190 | 28.0k | bool operator <=(const QLValuePB& lhs, const QLValuePB& rhs) { |
1191 | 28.0k | return (BothNotNull(lhs, rhs) && Compare(lhs, rhs) <= 0) || BothNull(lhs, rhs); |
1192 | 28.0k | } |
1193 | 29.2k | bool operator >=(const QLValuePB& lhs, const QLValuePB& rhs) { |
1194 | 29.2k | return (BothNotNull(lhs, rhs) && Compare(lhs, rhs) >= 0) || BothNull(lhs, rhs); |
1195 | 29.2k | } |
1196 | 926k | bool operator ==(const QLValuePB& lhs, const QLValuePB& rhs) { |
1197 | 926k | return (BothNotNull(lhs, rhs) && Compare(lhs, rhs) == 0) || BothNull(lhs, rhs); |
1198 | 926k | } |
1199 | 354k | bool operator !=(const QLValuePB& lhs, const QLValuePB& rhs) { |
1200 | 354k | return !(lhs == rhs); |
1201 | 354k | } |
1202 | | |
1203 | | // In YCQL null is not comparable with regular values (w.r.t. ordering). |
1204 | 0 | bool operator <(const QLValuePB& lhs, const QLValue& rhs) { |
1205 | 0 | return BothNotNull(lhs, rhs) && Compare(lhs, rhs) < 0; |
1206 | 0 | } |
1207 | 0 | bool operator >(const QLValuePB& lhs, const QLValue& rhs) { |
1208 | 0 | return BothNotNull(lhs, rhs) && Compare(lhs, rhs) > 0; |
1209 | 0 | } |
1210 | | |
1211 | | // In YCQL equality holds for null values. |
1212 | 0 | bool operator <=(const QLValuePB& lhs, const QLValue& rhs) { |
1213 | 0 | return (BothNotNull(lhs, rhs) && Compare(lhs, rhs) <= 0) || BothNull(lhs, rhs); |
1214 | 0 | } |
1215 | 0 | bool operator >=(const QLValuePB& lhs, const QLValue& rhs) { |
1216 | 0 | return (BothNotNull(lhs, rhs) && Compare(lhs, rhs) >= 0) || BothNull(lhs, rhs); |
1217 | 0 | } |
1218 | 599k | bool operator ==(const QLValuePB& lhs, const QLValue& rhs) { |
1219 | 599k | return (BothNotNull(lhs, rhs) && Compare(lhs, rhs) == 0) || BothNull(lhs, rhs); |
1220 | 599k | } |
1221 | 599k | bool operator !=(const QLValuePB& lhs, const QLValue& rhs) { |
1222 | 599k | return !(lhs == rhs); |
1223 | 599k | } |
1224 | | |
1225 | | } // namespace yb |