1/**
2 * Copyright 2021 Alibaba, Inc. and its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * \author hongqing.hu
17 * \date Dec 2020
18 * \brief
19 */
20
21#include <gtest/gtest.h>
22
23//!!! undef VERSION must be after include my_global.h
24#include <my_global.h>
25#undef VERSION
26
27extern "C" {
28#include <decimal.h>
29}
30
31#define private public
32#include "repository/binlog/field.h"
33#undef private
34#include "proto/common.pb.h"
35#include "repository/repository_common/error_code.h"
36
37using namespace ::proxima::be;
38using namespace proxima::be::repository;
39
40class FieldTest : public testing::Test {
41 protected:
42 void SetUp() {}
43
44 void TearDown() {}
45
46 FieldAttr *CreateFieldAttr(const char *field_name,
47 enum_field_types field_type,
48 unsigned int field_length,
49 unsigned int field_decimals,
50 unsigned int field_flags, bool is_gbk = false) {
51 auto meta = std::make_shared<FieldMeta>(
52 field_name, field_type, field_length, field_decimals, field_flags);
53 std::string collation("utf8_general_ci");
54 if (is_gbk) {
55 collation = "gbk_chinese_ci";
56 }
57 FieldAttr *attr = new FieldAttr(true, true, collation, meta);
58 return attr;
59 }
60
61 protected:
62 std::string field_name_{"f1"};
63};
64
65
66#define TEST_CREATE_FIELD_TYPE(field_type, field_length, field_decimals, \
67 field_flags) \
68 { \
69 FieldAttr *attr = \
70 CreateFieldAttr(field_name_.c_str(), field_type, field_length, \
71 field_decimals, field_flags); \
72 auto field = FieldFactory::Create(field_name_, *attr); \
73 delete attr; \
74 ASSERT_TRUE(field != nullptr); \
75 }
76
77#define CREATE_FIELD(field_type, field_length, field_decimals, field_flags) \
78 { \
79 FieldAttr *attr = \
80 CreateFieldAttr(field_name_.c_str(), field_type, field_length, \
81 field_decimals, field_flags); \
82 field = FieldFactory::Create(field_name_, *attr); \
83 delete attr; \
84 ASSERT_TRUE(field != nullptr); \
85 }
86
87#define CREATE_FIELD2(field_type, field_length, field_decimals, field_flags, \
88 gbk) \
89 { \
90 FieldAttr *attr = \
91 CreateFieldAttr(field_name_.c_str(), field_type, field_length, \
92 field_decimals, field_flags, gbk); \
93 field = FieldFactory::Create(field_name_, *attr); \
94 delete attr; \
95 ASSERT_TRUE(field != nullptr); \
96 }
97
98TEST_F(FieldTest, TestCreateField) {
99 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_TINY, 1, 0, 0);
100 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_SHORT, 2, 0, 0);
101 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_LONG, 4, 0, 0);
102 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_FLOAT, 4, 0, 0);
103 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_DOUBLE, 8, 0, 0);
104 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_TIMESTAMP, 4, 0, 0);
105 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_TIMESTAMP2, 4, 0, 0);
106 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_LONGLONG, 8, 0, 0);
107 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_INT24, 3, 0, 0);
108 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_DATE, 4, 0, 0);
109 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_TIME, 3, 0, 0);
110 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_TIME2, 3, 0, 0);
111 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_DATETIME, 8, 0, 0);
112 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_DATETIME2, 8, 0, 0);
113 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_YEAR, 1, 0, 0);
114 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_BIT, 8, 0, 0);
115 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_JSON, 16, 0, 0);
116 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_NEWDECIMAL, 20, 0, 0);
117 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_BLOB, 256, 0, 0);
118 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_VARCHAR, 16, 0, 0);
119 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_VAR_STRING, 10, 0, 0);
120 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_STRING, 10, 0, 0);
121 TEST_CREATE_FIELD_TYPE(MYSQL_TYPE_GEOMETRY, 16, 0, 0);
122}
123
124TEST_F(FieldTest, TestFieldTiny) {
125 FieldPtr field;
126 // signed text
127 {
128 unsigned int flags = 0;
129 proto::GenericValue value;
130 CREATE_FIELD(MYSQL_TYPE_TINY, 1, 0, flags);
131 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
132 ASSERT_TRUE(field->unpack_text("-127", 4, &value));
133 ASSERT_EQ(value.int32_value(), -127);
134 ASSERT_TRUE(field->unpack_text("127", 3, &value));
135 ASSERT_EQ(value.int32_value(), 127);
136 }
137 // unsigned text
138 {
139 unsigned int flags = UNSIGNED_FLAG;
140 proto::GenericValue value;
141 CREATE_FIELD(MYSQL_TYPE_TINY, 1, 0, flags);
142 ASSERT_TRUE(field->unpack_text("6", 1, &value));
143 ASSERT_EQ(value.uint32_value(), 6);
144 ASSERT_TRUE(field->unpack_text("255", 3, &value));
145 ASSERT_EQ(value.uint32_value(), 255);
146 }
147 // signed binary
148 {
149 unsigned int flags = 0;
150 proto::GenericValue value;
151 ColumnInfo info;
152 uint8_t data[2] = {(uint8_t)(-10)};
153 CREATE_FIELD(MYSQL_TYPE_TINY, 1, 0, flags);
154 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
155 ASSERT_TRUE(field->unpack_binary(data, data + 1, info, &value));
156 ASSERT_EQ(value.int32_value(), -10);
157 }
158 // unsigned binary
159 {
160 unsigned int flags = UNSIGNED_FLAG;
161 proto::GenericValue value;
162 ColumnInfo info;
163 uint8_t data[2] = {255};
164 CREATE_FIELD(MYSQL_TYPE_TINY, 1, 0, flags);
165 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
166 ASSERT_TRUE(field->unpack_binary(data, data + 1, info, &value));
167 ASSERT_EQ(value.uint32_value(), 255);
168 }
169}
170
171TEST_F(FieldTest, TestFieldShort) {
172 FieldPtr field;
173 // signed text
174 {
175 unsigned int flags = 0;
176 proto::GenericValue value;
177 CREATE_FIELD(MYSQL_TYPE_SHORT, 2, 0, flags);
178 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
179 ASSERT_TRUE(field->unpack_text("-128", 4, &value));
180 ASSERT_EQ(value.int32_value(), -128);
181 ASSERT_TRUE(field->unpack_text("32765", 5, &value));
182 ASSERT_EQ(value.int32_value(), 32765);
183 }
184 // unsigned text
185 {
186 unsigned int flags = UNSIGNED_FLAG;
187 proto::GenericValue value;
188 CREATE_FIELD(MYSQL_TYPE_SHORT, 2, 0, flags);
189 ASSERT_TRUE(field->unpack_text("6", 1, &value));
190 ASSERT_EQ(value.uint32_value(), 6);
191 ASSERT_TRUE(field->unpack_text("65535", 5, &value));
192 ASSERT_EQ(value.uint32_value(), 65535);
193 }
194 // signed binary
195 {
196 unsigned int flags = 0;
197 proto::GenericValue value;
198 ColumnInfo info;
199 uint8_t data[3] = {1, 2};
200 CREATE_FIELD(MYSQL_TYPE_SHORT, 2, 0, flags);
201 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
202 ASSERT_TRUE(field->unpack_binary(data, data + 2, info, &value));
203 ASSERT_EQ(value.int32_value(), 513);
204 }
205 // unsigned binary
206 {
207 unsigned int flags = UNSIGNED_FLAG;
208 proto::GenericValue value;
209 ColumnInfo info;
210 uint8_t data[3] = {2, 1};
211 CREATE_FIELD(MYSQL_TYPE_SHORT, 2, 0, flags);
212 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
213 ASSERT_TRUE(field->unpack_binary(data, data + 2, info, &value));
214 ASSERT_EQ(value.uint32_value(), 258);
215 }
216}
217
218TEST_F(FieldTest, TestFieldInt24) {
219 FieldPtr field;
220 // signed text
221 {
222 unsigned int flags = 0;
223 proto::GenericValue value;
224 CREATE_FIELD(MYSQL_TYPE_INT24, 3, 0, flags);
225 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
226 ASSERT_TRUE(field->unpack_text("-65536", 6, &value));
227 ASSERT_EQ(value.int32_value(), -65536);
228 ASSERT_TRUE(field->unpack_text("100000", 6, &value));
229 ASSERT_EQ(value.int32_value(), 100000);
230 }
231 // unsigned text
232 {
233 unsigned int flags = UNSIGNED_FLAG;
234 proto::GenericValue value;
235 CREATE_FIELD(MYSQL_TYPE_INT24, 3, 0, flags);
236 ASSERT_TRUE(field->unpack_text("100", 3, &value));
237 ASSERT_EQ(value.uint32_value(), 100);
238 ASSERT_TRUE(field->unpack_text("1234567", 7, &value));
239 ASSERT_EQ(value.uint32_value(), 1234567);
240 }
241 // signed binary
242 {
243 unsigned int flags = 0;
244 proto::GenericValue value;
245 ColumnInfo info;
246 uint8_t data[3] = {1, 2, 0};
247 CREATE_FIELD(MYSQL_TYPE_INT24, 3, 0, flags);
248 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
249 ASSERT_TRUE(field->unpack_binary(data, data + 3, info, &value));
250 ASSERT_EQ(value.int32_value(), 513);
251 }
252 // unsigned binary
253 {
254 unsigned int flags = UNSIGNED_FLAG;
255 proto::GenericValue value;
256 ColumnInfo info;
257 uint8_t data[3] = {2, 1, 0};
258 CREATE_FIELD(MYSQL_TYPE_INT24, 3, 0, flags);
259 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
260 ASSERT_TRUE(field->unpack_binary(data, data + 3, info, &value));
261 ASSERT_EQ(value.uint32_value(), 258);
262 }
263}
264
265TEST_F(FieldTest, TestFieldLong) {
266 FieldPtr field;
267 // signed text
268 {
269 unsigned int flags = 0;
270 proto::GenericValue value;
271 CREATE_FIELD(MYSQL_TYPE_LONG, 4, 0, flags);
272 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
273 ASSERT_TRUE(field->unpack_text("-65536", 6, &value));
274 ASSERT_EQ(value.int32_value(), -65536);
275 ASSERT_TRUE(field->unpack_text("2000000000", 10, &value));
276 ASSERT_EQ(value.int32_value(), 2000000000);
277 }
278 // unsigned text
279 {
280 unsigned int flags = UNSIGNED_FLAG;
281 proto::GenericValue value;
282 CREATE_FIELD(MYSQL_TYPE_LONG, 4, 0, flags);
283 ASSERT_TRUE(field->unpack_text("100", 3, &value));
284 ASSERT_EQ(value.uint32_value(), 100);
285 ASSERT_TRUE(field->unpack_text("4000000000", 10, &value));
286 ASSERT_EQ(value.uint32_value(), 4000000000);
287 }
288 // signed binary
289 {
290 unsigned int flags = 0;
291 proto::GenericValue value;
292 ColumnInfo info;
293 uint8_t data[4] = {1, 2, 0, 1};
294 CREATE_FIELD(MYSQL_TYPE_LONG, 4, 0, flags);
295 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
296 ASSERT_TRUE(field->unpack_binary(data, data + 4, info, &value));
297 ASSERT_EQ(value.int32_value(), 16777729);
298 }
299 // unsigned binary
300 {
301 unsigned int flags = UNSIGNED_FLAG;
302 proto::GenericValue value;
303 ColumnInfo info;
304 uint8_t data[4] = {2, 1, 0, 255};
305 CREATE_FIELD(MYSQL_TYPE_LONG, 4, 0, flags);
306 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
307 ASSERT_TRUE(field->unpack_binary(data, data + 4, info, &value));
308 ASSERT_EQ(value.uint32_value(), 4278190338);
309 }
310}
311
312TEST_F(FieldTest, TestFieldLongLong) {
313 FieldPtr field;
314 // signed text
315 {
316 unsigned int flags = 0;
317 proto::GenericValue value;
318 CREATE_FIELD(MYSQL_TYPE_LONGLONG, 8, 0, flags);
319 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
320 ASSERT_TRUE(field->unpack_text("-65536", 6, &value));
321 ASSERT_EQ(value.int64_value(), -65536);
322 ASSERT_TRUE(field->unpack_text("8000000000", 10, &value));
323 ASSERT_EQ(value.int64_value(), 8000000000);
324 }
325 // unsigned text
326 {
327 unsigned int flags = UNSIGNED_FLAG;
328 proto::GenericValue value;
329 CREATE_FIELD(MYSQL_TYPE_LONGLONG, 8, 0, flags);
330 ASSERT_TRUE(field->unpack_text("100", 3, &value));
331 ASSERT_EQ(value.uint64_value(), 100);
332 ASSERT_TRUE(field->unpack_text("8000000000", 10, &value));
333 ASSERT_EQ(value.uint64_value(), 8000000000);
334 }
335 // signed binary
336 {
337 unsigned int flags = 0;
338 proto::GenericValue value;
339 ColumnInfo info;
340 uint8_t data[8] = {1, 2, 0, 1, 0, 0, 0, 0};
341 CREATE_FIELD(MYSQL_TYPE_LONGLONG, 8, 0, flags);
342 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
343 ASSERT_TRUE(field->unpack_binary(data, data + 8, info, &value));
344 ASSERT_EQ(value.int64_value(), 16777729);
345 }
346 // unsigned binary
347 {
348 unsigned int flags = UNSIGNED_FLAG;
349 proto::GenericValue value;
350 ColumnInfo info;
351 uint8_t data[8] = {2, 1, 0, 255, 0, 0, 0, 0};
352 CREATE_FIELD(MYSQL_TYPE_LONGLONG, 8, 0, flags);
353 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
354 ASSERT_TRUE(field->unpack_binary(data, data + 8, info, &value));
355 ASSERT_EQ(value.uint64_value(), 4278190338);
356 }
357}
358
359TEST_F(FieldTest, TestFieldFloat) {
360 FieldPtr field;
361 // text
362 {
363 unsigned int flags = 0;
364 proto::GenericValue value;
365 CREATE_FIELD(MYSQL_TYPE_FLOAT, 4, 0, flags);
366 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
367 ASSERT_TRUE(field->unpack_text("-123.456", 8, &value));
368 ASSERT_FLOAT_EQ(value.float_value(), -123.456);
369 ASSERT_TRUE(field->unpack_text("2000000000", 10, &value));
370 ASSERT_EQ(value.float_value(), 2000000000);
371 }
372
373 // binary
374 {
375 unsigned int flags = 0;
376 proto::GenericValue value;
377 ColumnInfo info;
378 float val = 0.123456;
379 uint8_t *data = (uint8_t *)(&val);
380 CREATE_FIELD(MYSQL_TYPE_FLOAT, 4, 0, flags);
381 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
382 ASSERT_TRUE(field->unpack_binary(data, data + 4, info, &value));
383 ASSERT_FLOAT_EQ(value.float_value(), 0.123456);
384 }
385}
386
387TEST_F(FieldTest, TestFieldDouble) {
388 FieldPtr field;
389 // text
390 {
391 unsigned int flags = 0;
392 proto::GenericValue value;
393 CREATE_FIELD(MYSQL_TYPE_DOUBLE, 8, 0, flags);
394 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
395 ASSERT_TRUE(field->unpack_text("-123.456", 8, &value));
396 ASSERT_DOUBLE_EQ(value.double_value(), -123.456);
397 ASSERT_TRUE(field->unpack_text("2000000000", 10, &value));
398 ASSERT_EQ(value.double_value(), 2000000000);
399 }
400
401 // binary
402 {
403 unsigned int flags = 0;
404 proto::GenericValue value;
405 ColumnInfo info;
406 double val = 1234.123456;
407 uint8_t *data = (uint8_t *)(&val);
408 CREATE_FIELD(MYSQL_TYPE_DOUBLE, 8, 0, flags);
409 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
410 ASSERT_TRUE(field->unpack_binary(data, data + 8, info, &value));
411 ASSERT_DOUBLE_EQ(value.double_value(), 1234.123456);
412 }
413}
414
415TEST_F(FieldTest, TestFieldDecimal) {
416 FieldPtr field;
417 // text
418 {
419 unsigned int flags = 0;
420 proto::GenericValue value;
421 CREATE_FIELD(MYSQL_TYPE_NEWDECIMAL, 8, 0, flags);
422 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
423 ASSERT_TRUE(field->unpack_text("111.11", 6, &value));
424 ASSERT_EQ(value.string_value(), "111.11");
425 }
426
427 // binary
428 {
429 unsigned int flags = 0;
430 proto::GenericValue value;
431 ColumnInfo info;
432 info.meta = (15 << 8) + 10;
433 uint8_t data[12] = {128, 48, 57, 24, 147, 229, 78, 9};
434 CREATE_FIELD(MYSQL_TYPE_NEWDECIMAL, 8, 0, flags);
435 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
436 ASSERT_TRUE(field->unpack_binary(data, data + 12, info, &value));
437 ASSERT_EQ(value.string_value(), "12345.4123456789");
438 }
439}
440
441TEST_F(FieldTest, TestFieldBit) {
442 FieldPtr field;
443 // text
444 {
445 unsigned int flags = 0;
446 proto::GenericValue value;
447 CREATE_FIELD(MYSQL_TYPE_BIT, 8, 0, flags);
448 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
449 ASSERT_TRUE(field->unpack_text("65534", 5, &value));
450 ASSERT_DOUBLE_EQ(value.uint64_value(), 65534);
451 }
452
453 // binary
454 {
455 unsigned int flags = 0;
456 proto::GenericValue value;
457 ColumnInfo info;
458 uint8_t data[8] = {1, 2, 3, 4, 5, 6, 7, 8};
459 info.meta = 4;
460 CREATE_FIELD(MYSQL_TYPE_BIT, 8, 0, flags);
461 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
462 {
463 ASSERT_TRUE(field->unpack_binary(data, data + 1, info, &value));
464 ASSERT_DOUBLE_EQ(value.uint64_value(), 1);
465 }
466 {
467 info.meta += 256;
468 ASSERT_TRUE(field->unpack_binary(data, data + 2, info, &value));
469 ASSERT_DOUBLE_EQ(value.uint64_value(), 258);
470 }
471 {
472 info.meta += 256;
473 ASSERT_TRUE(field->unpack_binary(data, data + 3, info, &value));
474 ASSERT_DOUBLE_EQ(value.uint64_value(), 66051);
475 }
476 {
477 info.meta += 256;
478 ASSERT_TRUE(field->unpack_binary(data, data + 4, info, &value));
479 ASSERT_DOUBLE_EQ(value.uint64_value(), 16909060);
480 }
481 {
482 info.meta += 256;
483 ASSERT_TRUE(field->unpack_binary(data, data + 5, info, &value));
484 ASSERT_DOUBLE_EQ(value.uint64_value(), 4328719365);
485 }
486 {
487 info.meta += 256;
488 ASSERT_TRUE(field->unpack_binary(data, data + 6, info, &value));
489 ASSERT_DOUBLE_EQ(value.uint64_value(), 1108152157446);
490 }
491 {
492 info.meta += 256;
493 ASSERT_TRUE(field->unpack_binary(data, data + 7, info, &value));
494 ASSERT_DOUBLE_EQ(value.uint64_value(), 283686952306183);
495 }
496 {
497 info.meta += 256;
498 ASSERT_TRUE(field->unpack_binary(data, data + 8, info, &value));
499 ASSERT_DOUBLE_EQ(value.uint64_value(), 72623859790382856);
500 }
501 }
502}
503
504TEST_F(FieldTest, TestFieldDatetime) {
505 FieldPtr field;
506 // text
507 {
508 unsigned int flags = 0;
509 proto::GenericValue value;
510 CREATE_FIELD(MYSQL_TYPE_DATETIME, 8, 0, flags);
511 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
512 ASSERT_TRUE(field->unpack_text("2021-01-13 12:12:30.123456", 26, &value));
513 ASSERT_EQ(value.string_value(), "2021-01-13 12:12:30.123456");
514 }
515
516 // binary
517 {
518 unsigned int flags = 0;
519 proto::GenericValue value;
520 ColumnInfo info;
521 uint8_t data[8] = {0x99, 0x81, 0x21, 0x01, 0x01, 0x02, 0x01, 0x01};
522 info.meta = 0;
523 CREATE_FIELD(MYSQL_TYPE_DATETIME, 8, 0, flags);
524 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
525 {
526 ASSERT_TRUE(field->unpack_binary(data, data + 5, info, &value));
527 ASSERT_EQ(value.string_value(), "2008-12-16 16:04:01");
528 }
529 {
530 info.meta = 1;
531 ASSERT_TRUE(field->unpack_binary(data, data + 6, info, &value));
532 ASSERT_EQ(value.string_value(), "2008-12-16 16:04:01.0");
533 }
534 {
535 info.meta = 2;
536 ASSERT_TRUE(field->unpack_binary(data, data + 6, info, &value));
537 ASSERT_EQ(value.string_value(), "2008-12-16 16:04:01.02");
538 }
539 {
540 info.meta = 3;
541 ASSERT_TRUE(field->unpack_binary(data, data + 7, info, &value));
542 ASSERT_EQ(value.string_value(), "2008-12-16 16:04:01.051");
543 }
544 {
545 info.meta = 4;
546 ASSERT_TRUE(field->unpack_binary(data, data + 7, info, &value));
547 ASSERT_EQ(value.string_value(), "2008-12-16 16:04:01.0513");
548 }
549 {
550 info.meta = 5;
551 ASSERT_TRUE(field->unpack_binary(data, data + 8, info, &value));
552 ASSERT_EQ(value.string_value(), "2008-12-16 16:04:01.13132");
553 }
554 {
555 info.meta = 6;
556 ASSERT_TRUE(field->unpack_binary(data, data + 8, info, &value));
557 ASSERT_EQ(value.string_value(), "2008-12-16 16:04:01.131329");
558 }
559
560 data[0] = 0x80;
561 for (size_t i = 1; i < 8; ++i) {
562 data[i] = 0x0;
563 }
564 {
565 info.meta = 6;
566 ASSERT_TRUE(field->unpack_binary(data, data + 8, info, &value));
567 ASSERT_EQ(value.string_value(), "0000-00-00 00:00:00");
568 }
569 }
570}
571
572TEST_F(FieldTest, TestFieldTimestamp) {
573 FieldPtr field;
574 // text
575 {
576 unsigned int flags = 0;
577 proto::GenericValue value;
578 CREATE_FIELD(MYSQL_TYPE_TIMESTAMP, 8, 0, flags);
579 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
580 ASSERT_TRUE(field->unpack_text("2021-01-13 12:12:30.123456", 26, &value));
581 ASSERT_EQ(value.string_value(), "2021-01-13 12:12:30.123456");
582 }
583
584 // binary
585 {
586 unsigned int flags = 0;
587 proto::GenericValue value;
588 ColumnInfo info;
589 uint8_t data[8] = {0x60, 0x81, 0x21, 0x01, 0x01, 0x02, 0x01, 0x0};
590 info.meta = 0;
591 CREATE_FIELD(MYSQL_TYPE_TIMESTAMP, 7, 0, flags);
592 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
593 {
594 ASSERT_TRUE(field->unpack_binary(data, data + 4, info, &value));
595 ASSERT_EQ(value.string_value(), "2021-04-22 15:08:49");
596 }
597 {
598 info.meta = 1;
599 ASSERT_TRUE(field->unpack_binary(data, data + 5, info, &value));
600 ASSERT_EQ(value.string_value(), "2021-04-22 15:08:49.0");
601 }
602 {
603 info.meta = 2;
604 ASSERT_TRUE(field->unpack_binary(data, data + 5, info, &value));
605 ASSERT_EQ(value.string_value(), "2021-04-22 15:08:49.01");
606 }
607 {
608 info.meta = 3;
609 ASSERT_TRUE(field->unpack_binary(data, data + 6, info, &value));
610 ASSERT_EQ(value.string_value(), "2021-04-22 15:08:49.025");
611 }
612 {
613 info.meta = 4;
614 ASSERT_TRUE(field->unpack_binary(data, data + 6, info, &value));
615 ASSERT_EQ(value.string_value(), "2021-04-22 15:08:49.0258");
616 }
617 {
618 info.meta = 5;
619 ASSERT_TRUE(field->unpack_binary(data, data + 7, info, &value));
620 ASSERT_EQ(value.string_value(), "2021-04-22 15:08:49.06604");
621 }
622 {
623 info.meta = 6;
624 ASSERT_TRUE(field->unpack_binary(data, data + 7, info, &value));
625 ASSERT_EQ(value.string_value(), "2021-04-22 15:08:49.066049");
626 }
627
628 data[0] = 0x0;
629 for (size_t i = 1; i < 8; ++i) {
630 data[i] = 0x0;
631 }
632 {
633 info.meta = 6;
634 ASSERT_TRUE(field->unpack_binary(data, data + 7, info, &value));
635 ASSERT_EQ(value.string_value(), "0000-00-00 00:00:00.000000");
636 }
637 }
638}
639
640TEST_F(FieldTest, TestFieldTime) {
641 FieldPtr field;
642 // text
643 {
644 unsigned int flags = 0;
645 proto::GenericValue value;
646 CREATE_FIELD(MYSQL_TYPE_TIME, 6, 0, flags);
647 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
648 ASSERT_TRUE(field->unpack_text("12:12:30.123456", 15, &value));
649 ASSERT_EQ(value.string_value(), "12:12:30.123456");
650 }
651
652 // binary
653 {
654 unsigned int flags = 0;
655 proto::GenericValue value;
656 ColumnInfo info;
657 uint8_t data[8] = {0x80, 0xe1, 0x21, 0x01, 0x01, 0x02, 0x0, 0x0};
658 info.meta = 0;
659 CREATE_FIELD(MYSQL_TYPE_TIME, 6, 0, flags);
660 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
661 {
662 ASSERT_TRUE(field->unpack_binary(data, data + 3, info, &value));
663 ASSERT_EQ(value.string_value(), "14:04:33");
664 }
665 {
666 info.meta = 1;
667 ASSERT_TRUE(field->unpack_binary(data, data + 4, info, &value));
668 ASSERT_EQ(value.string_value(), "14:04:33.0");
669 }
670 {
671 info.meta = 2;
672 ASSERT_TRUE(field->unpack_binary(data, data + 4, info, &value));
673 ASSERT_EQ(value.string_value(), "14:04:33.01");
674 }
675 {
676 info.meta = 3;
677 ASSERT_TRUE(field->unpack_binary(data, data + 5, info, &value));
678 ASSERT_EQ(value.string_value(), "14:04:33.025");
679 }
680 {
681 info.meta = 4;
682 ASSERT_TRUE(field->unpack_binary(data, data + 5, info, &value));
683 ASSERT_EQ(value.string_value(), "14:04:33.0257");
684 }
685 {
686 info.meta = 5;
687 ASSERT_TRUE(field->unpack_binary(data, data + 6, info, &value));
688 ASSERT_EQ(value.string_value(), "14:04:33.06579");
689 }
690 {
691 info.meta = 6;
692 ASSERT_TRUE(field->unpack_binary(data, data + 6, info, &value));
693 ASSERT_EQ(value.string_value(), "14:04:33.065794");
694 }
695
696 data[0] = 0x80;
697 for (size_t i = 1; i < 8; ++i) {
698 data[i] = 0x0;
699 }
700 {
701 info.meta = 6;
702 ASSERT_TRUE(field->unpack_binary(data, data + 6, info, &value));
703 ASSERT_EQ(value.string_value(), "00:00:00.000000");
704 }
705
706 data[0] = 0x70;
707 {
708 info.meta = 6;
709 ASSERT_TRUE(field->unpack_binary(data, data + 6, info, &value));
710 ASSERT_EQ(value.string_value(), "-256:00:00.000000");
711 }
712 }
713}
714
715TEST_F(FieldTest, TestFieldDate) {
716 FieldPtr field;
717 // text
718 {
719 unsigned int flags = 0;
720 proto::GenericValue value;
721 CREATE_FIELD(MYSQL_TYPE_DATE, 3, 0, flags);
722 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
723 ASSERT_TRUE(field->unpack_text("2021-01-13", 10, &value));
724 ASSERT_EQ(value.string_value(), "2021-01-13");
725 }
726
727 // binary
728 {
729 unsigned int flags = 0;
730 proto::GenericValue value;
731 ColumnInfo info;
732 uint8_t data[3] = {0x99, 0x81, 0x10};
733 info.meta = 0;
734 CREATE_FIELD(MYSQL_TYPE_DATE, 3, 0, flags);
735 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
736 {
737 ASSERT_TRUE(field->unpack_binary(data, data + 3, info, &value));
738 ASSERT_EQ(value.string_value(), "2112-12-25");
739 }
740
741 for (size_t i = 0; i < 3; ++i) {
742 data[i] = 0x0;
743 }
744 {
745 ASSERT_TRUE(field->unpack_binary(data, data + 3, info, &value));
746 ASSERT_EQ(value.string_value(), "0000-00-00");
747 }
748 }
749}
750
751TEST_F(FieldTest, TestFieldYear) {
752 FieldPtr field;
753 // text
754 {
755 unsigned int flags = 0;
756 proto::GenericValue value;
757 CREATE_FIELD(MYSQL_TYPE_YEAR, 1, 0, flags);
758 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
759 ASSERT_TRUE(field->unpack_text("2021", 4, &value));
760 ASSERT_EQ(value.string_value(), "2021");
761 }
762
763 // binary
764 {
765 unsigned int flags = 0;
766 proto::GenericValue value;
767 ColumnInfo info;
768 uint8_t data[1] = {111};
769 CREATE_FIELD(MYSQL_TYPE_YEAR, 1, 0, flags);
770 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
771 {
772 ASSERT_TRUE(field->unpack_binary(data, data + 1, info, &value));
773 ASSERT_EQ(value.string_value(), "2011");
774 }
775
776 for (size_t i = 0; i < 1; ++i) {
777 data[i] = 0x0;
778 }
779 {
780 ASSERT_TRUE(field->unpack_binary(data, data + 1, info, &value));
781 ASSERT_EQ(value.string_value(), "0000");
782 }
783 }
784}
785
786TEST_F(FieldTest, TestFieldBlob) {
787 FieldPtr field;
788 // unpack_text
789 {
790 // blob
791 unsigned int flags = BINARY_FLAG;
792 proto::GenericValue value;
793 CREATE_FIELD(MYSQL_TYPE_BLOB, 8, 0, flags);
794 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
795 ASSERT_TRUE(field->unpack_text("313233343536373839", 18, &value));
796 ASSERT_EQ(value.bytes_value(), "123456789");
797
798 // text
799 flags = 0;
800 CREATE_FIELD(MYSQL_TYPE_BLOB, 8, 0, flags);
801 ASSERT_TRUE(field->unpack_text("123456789", 9, &value));
802 ASSERT_EQ(value.string_value(), "123456789");
803 }
804
805 // unpack_binary (blob)
806 {
807 unsigned int flags = BINARY_FLAG;
808 proto::GenericValue value;
809 ColumnInfo info;
810 uint8_t data[8] = {0x00, 0x00, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33};
811 info.meta = 0;
812 CREATE_FIELD(MYSQL_TYPE_BLOB, 8, 0, flags);
813 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
814 { ASSERT_FALSE(field->unpack_binary(data, data + 4, info, &value)); }
815 {
816 info.meta = 1;
817 data[3] = 0x04;
818 ASSERT_TRUE(field->unpack_binary(data + 3, data + 8, info, &value));
819 ASSERT_EQ(value.bytes_value(), "0123");
820 data[3] = 0x00;
821 }
822 {
823 info.meta = 2;
824 data[2] = 0x04;
825 ASSERT_TRUE(field->unpack_binary(data + 2, data + 8, info, &value));
826 ASSERT_EQ(value.bytes_value(), "0123");
827 data[2] = 0x00;
828 }
829 {
830 info.meta = 3;
831 data[1] = 0x04;
832 ASSERT_TRUE(field->unpack_binary(data + 1, data + 8, info, &value));
833 ASSERT_EQ(value.bytes_value(), "0123");
834 data[1] = 0x00;
835 }
836 {
837 info.meta = 4;
838 data[0] = 0x04;
839 ASSERT_TRUE(field->unpack_binary(data + 0, data + 8, info, &value));
840 ASSERT_EQ(value.bytes_value(), "0123");
841 data[0] = 0x00;
842 }
843 {
844 info.meta = 4;
845 data[0] = 0x04;
846 ASSERT_FALSE(field->unpack_binary(data + 0, data + 7, info, &value));
847 data[0] = 0x00;
848 }
849 }
850
851 // unpack_binary (text no need convert)
852 {
853 unsigned int flags = 0;
854 proto::GenericValue value;
855 ColumnInfo info;
856 uint8_t data[8] = {0x00, 0x00, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33};
857 info.meta = 0;
858 CREATE_FIELD2(MYSQL_TYPE_BLOB, 8, 0, flags, false);
859 {
860 info.meta = 1;
861 data[3] = 0x04;
862 ASSERT_TRUE(field->unpack_binary(data + 3, data + 8, info, &value));
863 ASSERT_EQ(value.string_value(), "0123");
864 data[3] = 0x00;
865 }
866 }
867 // unpack_binary (text need convert)
868 {
869 unsigned int flags = 0;
870 proto::GenericValue value;
871 ColumnInfo info;
872 uint8_t data[8] = {0x00, 0x00, 0x00, 0x00, 0xce, 0xd2, 0x32, 0x33};
873 info.meta = 0;
874 CREATE_FIELD2(MYSQL_TYPE_BLOB, 8, 0, flags, true);
875 {
876 info.meta = 1;
877 data[3] = 0x04;
878 ASSERT_TRUE(field->unpack_binary(data + 3, data + 8, info, &value));
879 ASSERT_EQ(value.string_value(), "我23");
880 data[3] = 0x00;
881 }
882 }
883}
884
885TEST_F(FieldTest, TestFieldVarString) {
886 FieldPtr field;
887 // unpack_text (varchar)
888 {
889 unsigned int flags = 0;
890 proto::GenericValue value;
891 CREATE_FIELD2(MYSQL_TYPE_VAR_STRING, 8, 0, flags, false);
892 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
893 ASSERT_TRUE(field->unpack_text("123456789", 9, &value));
894 ASSERT_EQ(value.string_value(), "123456789");
895 }
896
897 // unpack_text (varbinary)
898 {
899 unsigned int flags = BINARY_FLAG;
900 proto::GenericValue value;
901 CREATE_FIELD2(MYSQL_TYPE_VAR_STRING, 8, 0, flags, false);
902 ASSERT_TRUE(field->unpack_text("313233343536373839", 18, &value));
903 ASSERT_EQ(value.bytes_value(), "123456789");
904 }
905
906 // unpack_binary (varbinary)
907 {
908 unsigned int flags = BINARY_FLAG;
909 proto::GenericValue value;
910 ColumnInfo info;
911 CREATE_FIELD2(MYSQL_TYPE_VAR_STRING, 8, 0, flags, false);
912 {
913 info.meta = 1;
914 uint8_t data[8] = {0x01, 0x30, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33};
915 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
916 ASSERT_TRUE(field->unpack_binary(data, data + 2, info, &value));
917 ASSERT_EQ(value.bytes_value(), "0");
918 }
919 {
920 info.meta = 256;
921 uint8_t data[258] = {0x00, 0x01};
922 std::string result("");
923 for (size_t i = 2; i < 258; ++i) {
924 data[i] = 0x30;
925 result.append("0");
926 }
927 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
928 ASSERT_FALSE(field->unpack_binary(data, data + 4, info, &value));
929 ASSERT_TRUE(field->unpack_binary(data, data + 258, info, &value));
930 ASSERT_EQ(value.bytes_value(), result);
931 }
932 }
933
934 // unpack_binary (varchar no need convert)
935 {
936 unsigned int flags = 0;
937 proto::GenericValue value;
938 ColumnInfo info;
939 CREATE_FIELD2(MYSQL_TYPE_VAR_STRING, 8, 0, flags, false);
940 {
941 info.meta = 1;
942 uint8_t data[8] = {0x01, 0x30, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33};
943 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
944 ASSERT_TRUE(field->unpack_binary(data, data + 2, info, &value));
945 ASSERT_EQ(value.string_value(), "0");
946 }
947 }
948
949 // unpack_binary (varchar need convert)
950 {
951 unsigned int flags = 0;
952 proto::GenericValue value;
953 ColumnInfo info;
954 CREATE_FIELD2(MYSQL_TYPE_VAR_STRING, 8, 0, flags, true);
955 {
956 info.meta = 1;
957 uint8_t data[8] = {0x03, 0xce, 0xd2, 0x30, 0x00, 0x00, 0x30, 0x31};
958 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
959 ASSERT_TRUE(field->unpack_binary(data, data + 4, info, &value));
960 ASSERT_EQ(value.string_value(), "我0");
961 }
962 }
963}
964
965TEST_F(FieldTest, TestFieldString) {
966 FieldPtr field;
967 // unpack_text
968 {
969 // string (char(xx))
970 unsigned int flags = 0;
971 proto::GenericValue value;
972 CREATE_FIELD(MYSQL_TYPE_STRING, 8, 0, flags);
973 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
974 ASSERT_TRUE(field->unpack_text("123456789", 9, &value));
975 ASSERT_EQ(value.string_value(), "123456789");
976
977 // string (binary(xx))
978 flags = BINARY_FLAG;
979 CREATE_FIELD(MYSQL_TYPE_STRING, 8, 0, flags);
980 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
981 ASSERT_TRUE(field->unpack_text("313233343536373839", 18, &value));
982 ASSERT_EQ(value.bytes_value(), "123456789");
983
984 // enum
985 flags = ENUM_FLAG;
986 CREATE_FIELD(MYSQL_TYPE_STRING, 8, 0, flags);
987 ASSERT_TRUE(field->unpack_text("1255", 4, &value));
988 ASSERT_EQ(value.int32_value(), 1255);
989
990 // set
991 flags = SET_FLAG;
992 CREATE_FIELD(MYSQL_TYPE_STRING, 8, 0, flags);
993 ASSERT_TRUE(field->unpack_text("255", 9, &value));
994 ASSERT_EQ(value.uint64_value(), 255);
995 }
996
997 // unpack_binary
998 {
999 unsigned int flags = 0;
1000 proto::GenericValue value;
1001 ColumnInfo info;
1002 CREATE_FIELD(MYSQL_TYPE_STRING, 8, 0, flags);
1003 {
1004 info.meta = 1;
1005 uint8_t data[8] = {0x01, 0x30, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33};
1006 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
1007 ASSERT_TRUE(field->unpack_binary(data, data + 2, info, &value));
1008 ASSERT_EQ(value.string_value(), "0");
1009 }
1010 // string
1011 {
1012 info.meta = 1 | (MYSQL_TYPE_STRING << 8);
1013 uint8_t data[8] = {0x01, 0x30, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33};
1014 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
1015 ASSERT_TRUE(field->unpack_binary(data, data + 2, info, &value));
1016 ASSERT_EQ(value.string_value(), "0");
1017 }
1018 // set
1019 {
1020 info.meta = 1 | (MYSQL_TYPE_SET << 8);
1021 uint8_t data[2] = {0x01, 0x00};
1022 ASSERT_TRUE(field->unpack_binary(data, data + 2, info, &value));
1023 ASSERT_EQ(value.uint64_value(), 1);
1024 }
1025 // enum len 1
1026 {
1027 info.meta = 1 | (MYSQL_TYPE_ENUM << 8);
1028 uint8_t data[2] = {0x01, 0x00};
1029 ASSERT_TRUE(field->unpack_binary(data, data + 2, info, &value));
1030 ASSERT_EQ(value.int32_value(), 1);
1031 }
1032 // enum len 2
1033 {
1034 info.meta = 2 | (MYSQL_TYPE_ENUM << 8);
1035 uint8_t data[2] = {0x01, 0x00};
1036 ASSERT_TRUE(field->unpack_binary(data, data + 2, info, &value));
1037 ASSERT_EQ(value.int32_value(), 1);
1038 }
1039 // enum len 3
1040 {
1041 info.meta = 3 | (MYSQL_TYPE_ENUM << 8);
1042 uint8_t data[3] = {0x01, 0x00};
1043 ASSERT_FALSE(field->unpack_binary(data, data + 3, info, &value));
1044 }
1045 }
1046}
1047
1048TEST_F(FieldTest, TestFieldStringWithParseStringValue) {
1049 FieldPtr field;
1050 // binary
1051 {
1052 unsigned int flags = BINARY_FLAG;
1053 proto::GenericValue value;
1054 CREATE_FIELD(MYSQL_TYPE_STRING, 256, 0, flags);
1055 FieldString *field1 = (FieldString *)field.get();
1056
1057 // len < 256
1058 {
1059 uint8_t data[8] = {0x01, 0x30, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33};
1060 ASSERT_FALSE(field1->parse_string_value(data, data, 1, &value));
1061 ASSERT_TRUE(field1->parse_string_value(data, data + 2, 1, &value));
1062 std::string result("0");
1063 result.resize(256);
1064 for (size_t i = 0; i < 255; ++i) {
1065 result[i + 1] = '\0';
1066 }
1067 ASSERT_EQ(value.bytes_value(), result);
1068 }
1069 // len >= 256
1070 {
1071 std::string result;
1072 result.resize(256);
1073 uint8_t data[258] = {0x00, 0x01};
1074 for (size_t i = 2; i < 258; ++i) {
1075 data[i] = 0x30;
1076 result[i - 2] = '0';
1077 }
1078 ASSERT_FALSE(field1->parse_string_value(data, data, 256, &value));
1079 ASSERT_FALSE(field1->parse_string_value(data, data + 20, 256, &value));
1080 ASSERT_TRUE(field1->parse_string_value(data, data + 258, 256, &value));
1081 ASSERT_EQ(value.bytes_value(), result);
1082 }
1083 }
1084 // string (no need convert)
1085 {
1086 unsigned int flags = 0;
1087 proto::GenericValue value;
1088 CREATE_FIELD2(MYSQL_TYPE_STRING, 256, 0, flags, false);
1089 FieldString *field1 = (FieldString *)field.get();
1090
1091 // len < 256
1092 {
1093 uint8_t data[8] = {0x01, 0x30, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33};
1094 ASSERT_FALSE(field1->parse_string_value(data, data, 1, &value));
1095 ASSERT_TRUE(field1->parse_string_value(data, data + 2, 1, &value));
1096 std::string result("0");
1097 ASSERT_EQ(value.string_value(), result);
1098 }
1099 // len >= 256
1100 {
1101 std::string result;
1102 result.resize(256);
1103 uint8_t data[258] = {0x00, 0x01};
1104 for (size_t i = 2; i < 258; ++i) {
1105 data[i] = 0x30;
1106 result[i - 2] = '0';
1107 }
1108 ASSERT_FALSE(field1->parse_string_value(data, data, 256, &value));
1109 ASSERT_FALSE(field1->parse_string_value(data, data + 20, 256, &value));
1110 ASSERT_TRUE(field1->parse_string_value(data, data + 258, 256, &value));
1111 ASSERT_EQ(value.string_value(), result);
1112 }
1113 }
1114 // string (need convert)
1115 {
1116 unsigned int flags = 0;
1117 proto::GenericValue value;
1118 CREATE_FIELD2(MYSQL_TYPE_STRING, 256, 0, flags, true);
1119 FieldString *field1 = (FieldString *)field.get();
1120
1121 // len < 256
1122 {
1123 uint8_t data[8] = {0x03, 0xce, 0xd2, 0x30, 0x00, 0x00, 0x30, 0x31};
1124 ASSERT_FALSE(field1->parse_string_value(data, data, 64, &value));
1125 ASSERT_TRUE(field1->parse_string_value(data, data + 4, 64, &value));
1126 std::string result("我0");
1127 ASSERT_EQ(value.string_value(), result);
1128 }
1129 }
1130}
1131
1132TEST_F(FieldTest, TestFieldStringWithParseSetValue) {
1133 FieldPtr field;
1134 {
1135 unsigned int flags = 0;
1136 proto::GenericValue value;
1137 CREATE_FIELD(MYSQL_TYPE_STRING, 8, 0, flags);
1138 FieldString *field1 = (FieldString *)field.get();
1139
1140 int32_t meta = 0;
1141 // len = 1
1142 {
1143 meta = 1;
1144 uint8_t data[8] = {0x01, 0x30, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33};
1145 ASSERT_FALSE(field1->parse_set_value(data, data, meta, &value));
1146 ASSERT_TRUE(field1->parse_set_value(data, data + 2, meta, &value));
1147 ASSERT_EQ(value.uint64_value(), 1);
1148 }
1149 // len = 2
1150 {
1151 meta = 2;
1152 uint8_t data[8] = {0x01, 0x30, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33};
1153 ASSERT_TRUE(field1->parse_set_value(data, data + meta, meta, &value));
1154 ASSERT_EQ(value.uint64_value(), 0x3001);
1155 }
1156 // len = 3
1157 {
1158 meta = 3;
1159 uint8_t data[8] = {0x01, 0x30, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33};
1160 ASSERT_TRUE(field1->parse_set_value(data, data + meta, meta, &value));
1161 ASSERT_EQ(value.uint64_value(), 0x3001);
1162 }
1163 // len = 4
1164 {
1165 meta = 4;
1166 uint8_t data[8] = {0x01, 0x30, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33};
1167 ASSERT_TRUE(field1->parse_set_value(data, data + meta, meta, &value));
1168 ASSERT_EQ(value.uint64_value(), 0x3001);
1169 }
1170 // len = 5
1171 {
1172 meta = 5;
1173 uint8_t data[8] = {0x01, 0x30, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04};
1174 ASSERT_TRUE(field1->parse_set_value(data, data + meta, meta, &value));
1175 ASSERT_EQ(value.uint64_value(), 0x0100003001);
1176 }
1177 // len = 6
1178 {
1179 meta = 6;
1180 uint8_t data[8] = {0x01, 0x30, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04};
1181 ASSERT_TRUE(field1->parse_set_value(data, data + meta, meta, &value));
1182 ASSERT_EQ(value.uint64_value(), 0x020100003001);
1183 }
1184 // len = 7
1185 {
1186 meta = 7;
1187 uint8_t data[8] = {0x01, 0x30, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04};
1188 ASSERT_TRUE(field1->parse_set_value(data, data + meta, meta, &value));
1189 ASSERT_EQ(value.uint64_value(), 0x03020100003001);
1190 }
1191 // len = 8
1192 {
1193 meta = 8;
1194 uint8_t data[8] = {0x01, 0x30, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04};
1195 ASSERT_TRUE(field1->parse_set_value(data, data + meta, meta, &value));
1196 ASSERT_EQ(value.uint64_value(), 0x0403020100003001);
1197 }
1198 // len = 9
1199 {
1200 meta = 9;
1201 uint8_t data[9] = {0x01, 0x30, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04};
1202 ASSERT_FALSE(field1->parse_set_value(data, data + meta, meta, &value));
1203 }
1204 }
1205}
1206
1207TEST_F(FieldTest, TestFieldJson) {
1208 FieldPtr field;
1209 // text
1210 {
1211 unsigned int flags = 0;
1212 proto::GenericValue value;
1213 CREATE_FIELD(MYSQL_TYPE_JSON, 8, 0, flags);
1214 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
1215 ASSERT_TRUE(field->unpack_text("[1,2,3,4]", 9, &value));
1216 ASSERT_EQ(value.bytes_value(), "[1,2,3,4]");
1217 }
1218
1219 // binary
1220 {
1221 unsigned int flags = 0;
1222 proto::GenericValue value;
1223 ColumnInfo info;
1224 CREATE_FIELD(MYSQL_TYPE_JSON, 8, 0, flags);
1225 {
1226 info.meta = 1;
1227 uint8_t data[8] = {0x01, 0x30, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33};
1228 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
1229 ASSERT_TRUE(field->unpack_binary(data, data + 2, info, &value));
1230 ASSERT_EQ(value.bytes_value(), "0");
1231 }
1232 {
1233 info.meta = 2;
1234 uint8_t data[8] = {0x02, 0x00, 0x30, 0x30, 0x30, 0x31, 0x32, 0x33};
1235 ASSERT_TRUE(field->unpack_binary(data, data + 8, info, &value));
1236 ASSERT_EQ(value.bytes_value(), "00");
1237 }
1238 {
1239 info.meta = 3;
1240 uint8_t data[8] = {0x03, 0x00, 0x00, 0x30, 0x30, 0x30, 0x32, 0x33};
1241 ASSERT_TRUE(field->unpack_binary(data, data + 8, info, &value));
1242 ASSERT_EQ(value.bytes_value(), "000");
1243 }
1244 {
1245 info.meta = 4;
1246 uint8_t data[8] = {0x04, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30};
1247 ASSERT_TRUE(field->unpack_binary(data, data + 8, info, &value));
1248 ASSERT_EQ(value.bytes_value(), "0000");
1249 }
1250 {
1251 info.meta = 5;
1252 uint8_t data[8] = {0x04, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30};
1253 ASSERT_FALSE(field->unpack_binary(data, data + 8, info, &value));
1254 }
1255 }
1256}
1257
1258TEST_F(FieldTest, TestFieldGeometry) {
1259 FieldPtr field;
1260 // text
1261 {
1262 unsigned int flags = 0;
1263 proto::GenericValue value;
1264 CREATE_FIELD(MYSQL_TYPE_GEOMETRY, 8, 0, flags);
1265 ASSERT_FALSE(field->unpack_text(nullptr, 0, &value));
1266 ASSERT_TRUE(field->unpack_text("POINT(108.23 34.12)", 19, &value));
1267 ASSERT_EQ(value.bytes_value(), "POINT(108.23 34.12)");
1268 }
1269
1270 // binary
1271 {
1272 unsigned int flags = 0;
1273 proto::GenericValue value;
1274 ColumnInfo info;
1275 CREATE_FIELD(MYSQL_TYPE_GEOMETRY, 8, 0, flags);
1276 {
1277 info.meta = 1;
1278 uint8_t data[8] = {0x01, 0x30, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33};
1279 ASSERT_FALSE(field->unpack_binary(data, data, info, &value));
1280 ASSERT_TRUE(field->unpack_binary(data, data + 2, info, &value));
1281 ASSERT_EQ(value.bytes_value(), "0");
1282 }
1283 {
1284 info.meta = 2;
1285 uint8_t data[8] = {0x02, 0x00, 0x30, 0x30, 0x30, 0x31, 0x32, 0x33};
1286 ASSERT_TRUE(field->unpack_binary(data, data + 8, info, &value));
1287 ASSERT_EQ(value.bytes_value(), "00");
1288 }
1289 {
1290 info.meta = 3;
1291 uint8_t data[8] = {0x03, 0x00, 0x00, 0x30, 0x30, 0x30, 0x32, 0x33};
1292 ASSERT_TRUE(field->unpack_binary(data, data + 8, info, &value));
1293 ASSERT_EQ(value.bytes_value(), "000");
1294 }
1295 {
1296 info.meta = 4;
1297 uint8_t data[8] = {0x04, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30};
1298 ASSERT_TRUE(field->unpack_binary(data, data + 8, info, &value));
1299 ASSERT_EQ(value.bytes_value(), "0000");
1300 }
1301 {
1302 info.meta = 5;
1303 uint8_t data[8] = {0x04, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30};
1304 ASSERT_FALSE(field->unpack_binary(data, data + 8, info, &value));
1305 }
1306 }
1307}
1308