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