/Users/deen/code/yugabyte-db/src/yb/yql/cql/ql/exec/eval_const.cc
Line | Count | Source (jump to first uncovered line) |
1 | | //-------------------------------------------------------------------------------------------------- |
2 | | // Copyright (c) YugaByte, Inc. |
3 | | // |
4 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
5 | | // in compliance with the License. You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
10 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
11 | | // or implied. See the License for the specific language governing permissions and limitations |
12 | | // under the License. |
13 | | // |
14 | | //-------------------------------------------------------------------------------------------------- |
15 | | |
16 | | #include <string> |
17 | | |
18 | | #include "yb/common/jsonb.h" |
19 | | #include "yb/common/ql_datatype.h" |
20 | | #include "yb/common/ql_type.h" |
21 | | #include "yb/common/ql_value.h" |
22 | | |
23 | | #include "yb/gutil/casts.h" |
24 | | #include "yb/gutil/endian.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/enums.h" |
30 | | #include "yb/util/net/inetaddress.h" |
31 | | #include "yb/util/result.h" |
32 | | #include "yb/util/status_format.h" |
33 | | #include "yb/util/uuid.h" |
34 | | |
35 | | #include "yb/yql/cql/ql/exec/exec_context.h" |
36 | | #include "yb/yql/cql/ql/exec/executor.h" |
37 | | #include "yb/yql/cql/ql/ptree/pt_expr.h" |
38 | | |
39 | | namespace yb { |
40 | | namespace ql { |
41 | | |
42 | | using strings::Substitute; |
43 | | |
44 | | CHECKED_STATUS Executor::PTConstToPB(const PTExpr::SharedPtr& expr, |
45 | | QLValuePB *const_pb, |
46 | 7.67M | bool negate) { |
47 | 7.67M | if (expr->internal_type() == InternalType::VALUE_NOT_SET) { |
48 | 1.57k | SetNull(const_pb); |
49 | 1.57k | } |
50 | | |
51 | 7.67M | switch (expr->expr_op()) { |
52 | 63 | case ExprOperator::kUMinus: |
53 | 63 | return PTUMinusToPB(static_cast<const PTOperator1*>(expr.get()), const_pb); |
54 | | |
55 | 78 | case ExprOperator::kBindVar: { |
56 | 78 | QLExpressionPB expr_pb; |
57 | 78 | RETURN_NOT_OK(PTExprToPB(static_cast<const PTBindVar*>(expr.get()), &expr_pb)); |
58 | 78 | *const_pb = std::move(*expr_pb.mutable_value()); |
59 | 78 | return Status::OK(); |
60 | 78 | } |
61 | | |
62 | 7.67M | case ExprOperator::kConst: |
63 | 7.67M | case ExprOperator::kCollection: |
64 | 7.67M | break; |
65 | | |
66 | 13 | default: |
67 | 13 | return STATUS_SUBSTITUTE(RuntimeError, |
68 | 7.67M | "Invalid constant expression ($0)", expr->QLName()); |
69 | 7.67M | } |
70 | | |
71 | 7.65M | const PTExpr *const_pt = expr.get(); |
72 | 7.65M | switch (const_pt->ql_type_id()) { |
73 | 1.57k | case DataType::NULL_VALUE_TYPE: { |
74 | 1.57k | SetNull(const_pb); |
75 | 1.57k | break; |
76 | 0 | } |
77 | 7.45M | case DataType::VARINT: { |
78 | 7.45M | return PTExprToPB(static_cast<const PTConstVarInt*>(const_pt), const_pb, negate); |
79 | 0 | } |
80 | 4.00k | case DataType::DECIMAL: { |
81 | 4.00k | return PTExprToPB(static_cast<const PTConstDecimal*>(const_pt), const_pb, negate); |
82 | 0 | } |
83 | 0 | case DataType::INT64: { // Might be an obsolete case. |
84 | 0 | return PTExprToPB(static_cast<const PTConstInt*>(const_pt), const_pb, negate); |
85 | 0 | } |
86 | 0 | case DataType::DOUBLE: { // Might be an obsolete case. |
87 | 0 | return PTExprToPB(static_cast<const PTConstDouble*>(const_pt), const_pb, negate); |
88 | 0 | } |
89 | 183k | case DataType::STRING: { |
90 | 18.4E | DCHECK(!negate) << "Invalid datatype for negation"; |
91 | 183k | return PTExprToPB(static_cast<const PTConstText*>(const_pt), const_pb); |
92 | 0 | } |
93 | 456 | case DataType::BOOL: { |
94 | 456 | DCHECK(!negate) << "Invalid datatype for negation"0 ; |
95 | 456 | return PTExprToPB(static_cast<const PTConstBool*>(const_pt), const_pb); |
96 | 0 | } |
97 | 986 | case DataType::UUID: { |
98 | 986 | DCHECK(!negate) << "Invalid datatype for negation"0 ; |
99 | 986 | return PTExprToPB(static_cast<const PTConstUuid*>(const_pt), const_pb); |
100 | 0 | } |
101 | 3.13k | case DataType::BINARY: { |
102 | 3.13k | DCHECK(!negate) << "Invalid datatype for negation"0 ; |
103 | 3.13k | return PTExprToPB(static_cast<const PTConstBinary*>(const_pt), const_pb); |
104 | 0 | } |
105 | 84 | case DataType::MAP: FALLTHROUGH_INTENDED; |
106 | 151 | case DataType::SET: FALLTHROUGH_INTENDED; |
107 | 743 | case DataType::LIST: FALLTHROUGH_INTENDED; |
108 | 1.06k | case DataType::FROZEN: FALLTHROUGH_INTENDED; |
109 | 1.09k | case DataType::USER_DEFINED_TYPE: { |
110 | 1.09k | DCHECK(!negate) << "Invalid datatype for negation"0 ; |
111 | 1.09k | return PTExprToPB(static_cast<const PTCollectionExpr *>(const_pt), const_pb); |
112 | 1.06k | } |
113 | | |
114 | 0 | default: |
115 | 0 | return STATUS_SUBSTITUTE(RuntimeError, |
116 | 7.65M | "Unknown datatype ($0) for QL constant value", |
117 | 7.65M | const_pt->ql_type_id()); |
118 | 7.65M | } |
119 | 1.57k | return Status::OK(); |
120 | 7.65M | } |
121 | | |
122 | | CHECKED_STATUS Executor::PTExprToPB(const PTConstVarInt *const_pt, QLValuePB *const_pb, |
123 | 7.48M | bool negate) { |
124 | 7.48M | switch (const_pt->expected_internal_type()) { |
125 | 525 | case InternalType::kInt8Value: { |
126 | 525 | int64_t value; |
127 | 525 | if (!const_pt->ToInt64(&value, negate).ok() || |
128 | 525 | !(value <= INT8_MAX && value >= INT8_MIN524 )) { |
129 | 2 | return exec_context_->Error(const_pt->loc(), "Invalid tiny integer/int8", |
130 | 2 | ErrorCode::INVALID_ARGUMENTS); |
131 | 2 | } |
132 | 523 | const_pb->set_int8_value(narrow_cast<int32>(value)); |
133 | 523 | break; |
134 | 525 | } |
135 | 466 | case InternalType::kInt16Value: { |
136 | 466 | int64_t value; |
137 | 466 | if (!const_pt->ToInt64(&value, negate).ok() || |
138 | 466 | !(value <= INT16_MAX && value >= INT16_MIN465 )) { |
139 | 2 | return exec_context_->Error(const_pt->loc(), "Invalid small integer/int16", |
140 | 2 | ErrorCode::INVALID_ARGUMENTS); |
141 | 2 | } |
142 | 464 | const_pb->set_int16_value(narrow_cast<int32>(value)); |
143 | 464 | break; |
144 | 466 | } |
145 | 7.47M | case InternalType::kInt32Value: { |
146 | 7.47M | int64_t value; |
147 | 7.47M | if (!const_pt->ToInt64(&value, negate).ok() || |
148 | 7.47M | !(7.45M value <= INT32_MAX7.45M && value >= INT32_MIN7.45M )) { |
149 | 6 | return exec_context_->Error(const_pt->loc(), "Invalid integer/int32", |
150 | 6 | ErrorCode::INVALID_ARGUMENTS); |
151 | 6 | } |
152 | 7.47M | const_pb->set_int32_value(narrow_cast<int32>(value)); |
153 | 7.47M | break; |
154 | 7.47M | } |
155 | 954 | case InternalType::kInt64Value: { |
156 | 954 | int64_t value; |
157 | 954 | if (!const_pt->ToInt64(&value, negate).ok() || |
158 | 954 | !(944 value <= INT64_MAX944 && value >= INT64_MIN944 )) { |
159 | 10 | return exec_context_->Error(const_pt->loc(), "Invalid big integer/int64", |
160 | 10 | ErrorCode::INVALID_ARGUMENTS); |
161 | 10 | } |
162 | 944 | const_pb->set_int64_value(value); |
163 | 944 | break; |
164 | 954 | } |
165 | 101 | case InternalType::kFloatValue: { |
166 | 101 | long double value; |
167 | 101 | if (!const_pt->ToDouble(&value, negate).ok()) { |
168 | 0 | return exec_context_->Error(const_pt->loc(), "Invalid float", |
169 | 0 | ErrorCode::INVALID_ARGUMENTS); |
170 | 0 | } |
171 | 101 | const_pb->set_float_value(value); |
172 | 101 | break; |
173 | 101 | } |
174 | 111 | case InternalType::kDoubleValue: { |
175 | 111 | long double value; |
176 | 111 | if (!const_pt->ToDouble(&value, negate).ok()) { |
177 | 0 | return exec_context_->Error(const_pt->loc(), "Invalid double", |
178 | 0 | ErrorCode::INVALID_ARGUMENTS); |
179 | 0 | } |
180 | 111 | const_pb->set_double_value(value); |
181 | 111 | break; |
182 | 111 | } |
183 | 126 | case InternalType::kDecimalValue: { |
184 | 126 | return const_pt->ToDecimal(const_pb->mutable_decimal_value(), negate); |
185 | 111 | } |
186 | 567 | case InternalType::kTimestampValue: { |
187 | 567 | int64_t value; |
188 | 567 | if (!const_pt->ToInt64(&value, negate).ok()) { |
189 | 0 | return exec_context_->Error(const_pt->loc(), "Invalid integer", |
190 | 0 | ErrorCode::INVALID_ARGUMENTS); |
191 | 0 | } |
192 | 567 | const_pb->set_timestamp_value(DateTime::TimestampFromInt(value).ToInt64()); |
193 | 567 | break; |
194 | 567 | } |
195 | 0 | case InternalType::kDateValue: { |
196 | 0 | int64_t value; |
197 | 0 | if (!const_pt->ToInt64(&value, negate).ok() || |
198 | 0 | value < std::numeric_limits<uint32_t>::min() || |
199 | 0 | value > std::numeric_limits<uint32_t>::max()) { |
200 | 0 | return exec_context_->Error(const_pt->loc(), "Invalid date", |
201 | 0 | ErrorCode::INVALID_ARGUMENTS); |
202 | 0 | } |
203 | 0 | const_pb->set_date_value(static_cast<uint32_t>(value)); |
204 | 0 | break; |
205 | 0 | } |
206 | 9 | case InternalType::kTimeValue: { |
207 | 9 | int64_t value; |
208 | 9 | if (!const_pt->ToInt64(&value, negate).ok() || |
209 | 9 | value < DateTime::kMinTime || value > DateTime::kMaxTime) { |
210 | 0 | return exec_context_->Error(const_pt->loc(), "Invalid time", |
211 | 0 | ErrorCode::INVALID_ARGUMENTS); |
212 | 0 | } |
213 | 9 | const_pb->set_time_value(value); |
214 | 9 | break; |
215 | 9 | } |
216 | 2.14k | case InternalType::kVarintValue: { |
217 | 2.14k | return const_pt->ToVarInt(const_pb->mutable_varint_value(), negate); |
218 | 9 | } |
219 | | |
220 | 8 | default: |
221 | 8 | return STATUS_SUBSTITUTE(RuntimeError, |
222 | 7.48M | "Illegal datatype conversion: $0 to $1", "varint", |
223 | 7.48M | InternalTypeToCQLString(const_pt->expected_internal_type())); |
224 | 7.48M | } |
225 | 7.45M | return Status::OK(); |
226 | 7.48M | } |
227 | | |
228 | | CHECKED_STATUS Executor::PTExprToPB(const PTConstDecimal *const_pt, QLValuePB *const_pb, |
229 | 4.00k | bool negate) { |
230 | 4.00k | switch (const_pt->expected_internal_type()) { |
231 | 2.62k | case InternalType::kDecimalValue: { |
232 | 2.62k | return const_pt->ToDecimal(const_pb->mutable_decimal_value(), negate); |
233 | 0 | } |
234 | 663 | case InternalType::kFloatValue: { |
235 | 663 | long double value; |
236 | 663 | RETURN_NOT_OK(const_pt->ToDouble(&value, negate)); |
237 | 663 | const_pb->set_float_value(value); |
238 | 663 | break; |
239 | 663 | } |
240 | 717 | case InternalType::kDoubleValue: { |
241 | 717 | long double value; |
242 | 717 | RETURN_NOT_OK(const_pt->ToDouble(&value, negate)); |
243 | 713 | const_pb->set_double_value(value); |
244 | 713 | break; |
245 | 717 | } |
246 | 0 | default: |
247 | 0 | return STATUS_SUBSTITUTE(RuntimeError, |
248 | 4.00k | "Illegal datatype conversion: $0 to $1", "decimal", |
249 | 4.00k | InternalTypeToCQLString(const_pt->expected_internal_type())); |
250 | 4.00k | } |
251 | 1.37k | return Status::OK(); |
252 | 4.00k | } |
253 | | |
254 | | // The following numeric functions might be needed if we fold constant at compile time. |
255 | | // Leave them here for now. |
256 | | CHECKED_STATUS Executor::PTExprToPB(const PTConstInt *const_pt, QLValuePB *const_pb, |
257 | 0 | bool negate) { |
258 | 0 | int64_t value = const_pt->value(); |
259 | 0 | if (negate) { |
260 | 0 | value = -value; |
261 | 0 | } |
262 | |
|
263 | 0 | switch (const_pt->expected_internal_type()) { |
264 | 0 | case InternalType::kInt8Value: |
265 | 0 | const_pb->set_int8_value(narrow_cast<int32>(value)); |
266 | 0 | break; |
267 | 0 | case InternalType::kInt16Value: |
268 | 0 | const_pb->set_int16_value(narrow_cast<int32>(value)); |
269 | 0 | break; |
270 | 0 | case InternalType::kInt32Value: |
271 | 0 | const_pb->set_int32_value(narrow_cast<int32>(value)); |
272 | 0 | break; |
273 | 0 | case InternalType::kInt64Value: |
274 | 0 | const_pb->set_int64_value(value); |
275 | 0 | break; |
276 | 0 | case InternalType::kFloatValue: |
277 | 0 | const_pb->set_float_value(value); |
278 | 0 | break; |
279 | 0 | case InternalType::kDoubleValue: |
280 | 0 | const_pb->set_double_value(value); |
281 | 0 | break; |
282 | 0 | case InternalType::kTimestampValue: |
283 | 0 | const_pb->set_timestamp_value(DateTime::TimestampFromInt(value).ToInt64()); |
284 | 0 | break; |
285 | 0 | default: |
286 | 0 | return STATUS_SUBSTITUTE(RuntimeError, |
287 | 0 | "Illegal datatype conversion: $0 to $1", "int", |
288 | 0 | InternalTypeToCQLString(const_pt->expected_internal_type())); |
289 | 0 | } |
290 | 0 | return Status::OK(); |
291 | 0 | } |
292 | | |
293 | | CHECKED_STATUS Executor::PTExprToPB(const PTConstDouble *const_pt, QLValuePB *const_pb, |
294 | 0 | bool negate) { |
295 | 0 | long double value = const_pt->value(); |
296 | 0 | if (negate) { |
297 | 0 | value = -value; |
298 | 0 | } |
299 | |
|
300 | 0 | switch (const_pt->expected_internal_type()) { |
301 | 0 | case InternalType::kFloatValue: |
302 | 0 | const_pb->set_float_value(value); |
303 | 0 | break; |
304 | 0 | case InternalType::kDoubleValue: |
305 | 0 | const_pb->set_double_value(value); |
306 | 0 | break; |
307 | 0 | default: |
308 | 0 | return STATUS_SUBSTITUTE(RuntimeError, |
309 | 0 | "Illegal datatype conversion: $0 to $1", "double", |
310 | 0 | InternalTypeToCQLString(const_pt->expected_internal_type())); |
311 | 0 | } |
312 | 0 | return Status::OK(); |
313 | 0 | } |
314 | | |
315 | 185k | CHECKED_STATUS Executor::PTExprToPB(const PTConstText *const_pt, QLValuePB *const_pb) { |
316 | 185k | switch (const_pt->expected_internal_type()) { |
317 | 172k | case InternalType::kStringValue: |
318 | 172k | return const_pt->ToString(const_pb->mutable_string_value()); |
319 | 1.36k | case InternalType::kTimestampValue: { |
320 | 1.36k | int64_t value = 0; |
321 | 1.36k | RETURN_NOT_OK(const_pt->ToTimestamp(&value)); |
322 | 1.32k | const_pb->set_timestamp_value(value); |
323 | 1.32k | break; |
324 | 1.36k | } |
325 | 30 | case InternalType::kDateValue: { |
326 | 30 | uint32_t value = 0; |
327 | 30 | RETURN_NOT_OK(const_pt->ToDate(&value)); |
328 | 26 | const_pb->set_date_value(value); |
329 | 26 | break; |
330 | 30 | } |
331 | 10 | case InternalType::kTimeValue: { |
332 | 10 | int64_t value = 0; |
333 | 10 | RETURN_NOT_OK(const_pt->ToTime(&value)); |
334 | 5 | const_pb->set_time_value(value); |
335 | 5 | break; |
336 | 10 | } |
337 | 392 | case InternalType::kInetaddressValue: { |
338 | 392 | InetAddress value; |
339 | 392 | RETURN_NOT_OK(const_pt->ToInetaddress(&value)); |
340 | | |
341 | 390 | QLValue ql_const; |
342 | 390 | ql_const.set_inetaddress_value(value); |
343 | 390 | *const_pb = std::move(*ql_const.mutable_value()); |
344 | 390 | break; |
345 | 392 | } |
346 | 9.38k | case InternalType::kJsonbValue: { |
347 | 9.38k | std::string value; |
348 | 9.38k | RETURN_NOT_OK(const_pt->ToString(&value)); |
349 | 9.38k | common::Jsonb jsonb; |
350 | 9.38k | RETURN_NOT_OK(jsonb.FromString(value)); |
351 | | |
352 | 9.38k | QLValue ql_const; |
353 | 9.38k | ql_const.set_jsonb_value(jsonb.MoveSerializedJsonb()); |
354 | 9.38k | *const_pb = std::move(*ql_const.mutable_value()); |
355 | 9.38k | break; |
356 | 9.38k | } |
357 | | |
358 | 0 | default: |
359 | 0 | return STATUS_SUBSTITUTE(RuntimeError, |
360 | 185k | "Illegal datatype conversion: $0 to $1", "text", |
361 | 185k | InternalTypeToCQLString(const_pt->expected_internal_type())); |
362 | 185k | } |
363 | 11.1k | return Status::OK(); |
364 | 185k | } |
365 | | |
366 | 456 | CHECKED_STATUS Executor::PTExprToPB(const PTConstBool *const_pt, QLValuePB *const_pb) { |
367 | 456 | switch (const_pt->expected_internal_type()) { |
368 | 456 | case InternalType::kBoolValue: |
369 | 456 | const_pb->set_bool_value(const_pt->value()); |
370 | 456 | break; |
371 | 0 | default: |
372 | 0 | return STATUS_SUBSTITUTE(RuntimeError, |
373 | 456 | "Illegal datatype conversion: $0 to $1", "bool", |
374 | 456 | InternalTypeToCQLString(const_pt->expected_internal_type())); |
375 | 456 | } |
376 | 456 | return Status::OK(); |
377 | 456 | } |
378 | | |
379 | 3.13k | CHECKED_STATUS Executor::PTExprToPB(const PTConstBinary *const_pt, QLValuePB *const_pb) { |
380 | 3.13k | const auto& value = const_pt->value(); |
381 | 3.13k | switch (const_pt->expected_internal_type()) { |
382 | 3.13k | case InternalType::kBinaryValue: { |
383 | 3.13k | int input_size = static_cast<int>(value->size()); |
384 | 3.13k | if (input_size % 2 != 0) { |
385 | 2 | return STATUS(RuntimeError, "Invalid binary input, expected even number of hex digits"); |
386 | 2 | } |
387 | | |
388 | 3.13k | string bytes; |
389 | 3.13k | a2b_hex(value->c_str(), &bytes, input_size / 2); |
390 | 3.13k | const_pb->set_binary_value(bytes); |
391 | 3.13k | break; |
392 | 3.13k | } |
393 | 0 | default: |
394 | 0 | return STATUS_SUBSTITUTE(RuntimeError, |
395 | 3.13k | "Illegal datatype conversion: $0 to $1", "binary", |
396 | 3.13k | InternalTypeToCQLString(const_pt->expected_internal_type())); |
397 | 3.13k | } |
398 | 3.13k | return Status::OK(); |
399 | 3.13k | } |
400 | | |
401 | 986 | CHECKED_STATUS Executor::PTExprToPB(const PTConstUuid *const_pt, QLValuePB *const_pb) { |
402 | 986 | const auto& value = const_pt->value(); |
403 | 986 | switch (const_pt->expected_internal_type()) { |
404 | 704 | case InternalType::kUuidValue: { |
405 | 704 | Uuid uuid = VERIFY_RESULT(Uuid::FromString(value->c_str())); |
406 | | |
407 | 0 | QLValue ql_const; |
408 | 704 | ql_const.set_uuid_value(uuid); |
409 | 704 | *const_pb = std::move(*ql_const.mutable_value()); |
410 | 704 | break; |
411 | 704 | } |
412 | 282 | case InternalType::kTimeuuidValue: { |
413 | 282 | Uuid uuid = VERIFY_RESULT(Uuid::FromString(value->c_str())); |
414 | 282 | RETURN_NOT_OK(uuid.IsTimeUuid()); |
415 | | |
416 | 281 | QLValue ql_const; |
417 | 281 | ql_const.set_timeuuid_value(uuid); |
418 | 281 | *const_pb = std::move(*ql_const.mutable_value()); |
419 | 281 | break; |
420 | 282 | } |
421 | 0 | default: |
422 | 0 | return STATUS_SUBSTITUTE(RuntimeError, |
423 | 986 | "Illegal datatype conversion: $0 to $1", "uuid", |
424 | 986 | InternalTypeToCQLString(const_pt->expected_internal_type())); |
425 | 986 | } |
426 | 985 | return Status::OK(); |
427 | 986 | } |
428 | | |
429 | 1.09k | CHECKED_STATUS Executor::PTExprToPB(const PTCollectionExpr *const_pt, QLValuePB *const_pb) { |
430 | 1.09k | switch (const_pt->ql_type()->main()) { |
431 | 84 | case MAP: { |
432 | 84 | QLMapValuePB *map_value = const_pb->mutable_map_value(); |
433 | 133 | for (auto &key : const_pt->keys()) { |
434 | | // Expect key to be constant because CQL only allows collection of constants. |
435 | 133 | QLValuePB *key_pb = map_value->add_keys(); |
436 | 133 | RETURN_NOT_OK(PTConstToPB(key, key_pb)); |
437 | 133 | } |
438 | | |
439 | 128 | for (auto &value : const_pt->values())81 { |
440 | | // Expect value to be constant because CQL only allows collection of constants. |
441 | 128 | QLValuePB *value_pb = map_value->add_values(); |
442 | 128 | RETURN_NOT_OK(PTConstToPB(value, value_pb)); |
443 | 128 | } |
444 | 79 | break; |
445 | 81 | } |
446 | | |
447 | 79 | case SET: { |
448 | 67 | QLSeqValuePB *set_value = const_pb->mutable_set_value(); |
449 | 101 | for (auto &elem : const_pt->values()) { |
450 | | // Expected elem to be constant because CQL only allows collection of constants. |
451 | 101 | QLValuePB *elem_pb = set_value->add_elems(); |
452 | 101 | RETURN_NOT_OK(PTConstToPB(elem, elem_pb)); |
453 | 101 | } |
454 | 64 | break; |
455 | 67 | } |
456 | | |
457 | 592 | case LIST: { |
458 | 592 | QLSeqValuePB *list_value = const_pb->mutable_list_value(); |
459 | 1.64k | for (auto &elem : const_pt->values()) { |
460 | | // Expected elem to be constant because CQL only allows collection of constants. |
461 | 1.64k | QLValuePB *elem_pb = list_value->add_elems(); |
462 | 1.64k | RETURN_NOT_OK(PTConstToPB(elem, elem_pb)); |
463 | 1.64k | } |
464 | 587 | break; |
465 | 592 | } |
466 | | |
467 | 587 | case USER_DEFINED_TYPE: { |
468 | | // Internally UDTs are maps with field names as keys |
469 | 28 | QLMapValuePB *map_value = const_pb->mutable_map_value(); |
470 | 28 | auto field_values = const_pt->udtype_field_values(); |
471 | 91 | for (size_t i = 0; i < field_values.size(); i++63 ) { |
472 | | // Skipping unset fields. |
473 | 66 | if (field_values[i] != nullptr) { |
474 | 58 | QLValuePB *key_pb = map_value->add_keys(); |
475 | 58 | key_pb->set_int16_value(narrow_cast<int16_t>(i)); |
476 | | // Expect value to be constant because CQL only allows collection of constants. |
477 | 58 | QLValuePB *value_pb = map_value->add_values(); |
478 | 58 | RETURN_NOT_OK(PTConstToPB(field_values[i], value_pb)); |
479 | 58 | } |
480 | 66 | } |
481 | 25 | break; |
482 | 28 | } |
483 | | |
484 | 322 | case FROZEN: { |
485 | | // For frozen types we need to do the de-duplication and ordering at the QL level since we |
486 | | // serialize it here already. |
487 | 322 | QLSeqValuePB *frozen_value = const_pb->mutable_frozen_value(); |
488 | | |
489 | 322 | switch (const_pt->ql_type()->param_type(0)->main()) { |
490 | 41 | case MAP: { |
491 | 41 | std::map<QLValuePB, QLValuePB> map_values; |
492 | 41 | auto keys_it = const_pt->keys().begin(); |
493 | 41 | auto values_it = const_pt->values().begin(); |
494 | 112 | while (keys_it != const_pt->keys().end() && values_it != const_pt->values().end()71 ) { |
495 | 71 | QLValuePB key_pb; |
496 | 71 | RETURN_NOT_OK(PTConstToPB(*keys_it, &key_pb)); |
497 | 71 | RETURN_NOT_OK(PTConstToPB(*values_it, &map_values[key_pb])); |
498 | 71 | keys_it++; |
499 | 71 | values_it++; |
500 | 71 | } |
501 | | |
502 | 65 | for (auto &pair : map_values)41 { |
503 | 65 | *frozen_value->add_elems() = std::move(pair.first); |
504 | 65 | *frozen_value->add_elems() = std::move(pair.second); |
505 | 65 | } |
506 | 41 | break; |
507 | 41 | } |
508 | | |
509 | 63 | case SET: { |
510 | 63 | std::set<QLValuePB> set_values; |
511 | 140 | for (const auto &elem : const_pt->values()) { |
512 | 140 | QLValuePB elem_pb; |
513 | 140 | RETURN_NOT_OK(PTConstToPB(elem, &elem_pb)); |
514 | 140 | set_values.insert(std::move(elem_pb)); |
515 | 140 | } |
516 | | |
517 | 119 | for (auto &elem : set_values)63 { |
518 | 119 | *frozen_value->add_elems() = std::move(elem); |
519 | 119 | } |
520 | 63 | break; |
521 | 63 | } |
522 | | |
523 | 53 | case LIST: { |
524 | 97 | for (auto &elem : const_pt->values()) { |
525 | | // Expected elem to be constant because CQL only allows collection of constants. |
526 | 97 | QLValuePB *elem_pb = frozen_value->add_elems(); |
527 | 97 | RETURN_NOT_OK(PTConstToPB(elem, elem_pb)); |
528 | 97 | } |
529 | 53 | break; |
530 | 53 | } |
531 | | |
532 | 165 | case USER_DEFINED_TYPE: { |
533 | | // Internally UDTs are maps with field names as keys |
534 | 165 | auto field_values = const_pt->udtype_field_values(); |
535 | 504 | for (size_t i = 0; i < field_values.size(); i++339 ) { |
536 | 341 | QLValuePB *value_pb = frozen_value->add_elems(); |
537 | 341 | if (field_values[i] != nullptr) { |
538 | | // Expect value to be constant because CQL only allows collection of constants. |
539 | 300 | RETURN_NOT_OK(PTConstToPB(field_values[i], value_pb)); |
540 | 300 | } |
541 | 341 | } |
542 | 163 | break; |
543 | 165 | } |
544 | | |
545 | 163 | default: |
546 | 0 | return STATUS_SUBSTITUTE(InternalError, "unsupported type $0", |
547 | 322 | const_pt->ql_type()->param_type(0)->main()); |
548 | 322 | } |
549 | 320 | break; |
550 | 322 | } |
551 | | |
552 | 320 | default: |
553 | 0 | return STATUS_SUBSTITUTE(InternalError, "unsupported type $0", const_pt->ql_type()->main()); |
554 | 1.09k | } |
555 | | |
556 | 1.07k | return Status::OK(); |
557 | 1.09k | } |
558 | | |
559 | | |
560 | | } // namespace ql |
561 | | } // namespace yb |