1 /* Copyright (c) 2015, 2021, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software Foundation,
21 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22
23 #include "json_binary.h"
24 #include "json_dom.h"
25 #include "sql_time.h"
26 #include <gtest/gtest.h>
27 #include "test_utils.h"
28 #include <cstring>
29 #include <memory>
30
31 namespace json_binary_unittest {
32
33 using namespace json_binary;
34
35 class JsonBinaryTest : public ::testing::Test
36 {
37 protected:
SetUp()38 virtual void SetUp() { initializer.SetUp(); }
TearDown()39 virtual void TearDown() { initializer.TearDown(); }
40 my_testing::Server_initializer initializer;
41 };
42
43
44 /**
45 Get a copy of the string value represented by val.
46 */
get_string(const Value & val)47 std::string get_string(const Value &val)
48 {
49 return std::string(val.get_data(), val.get_data_length());
50 }
51
52
TEST_F(JsonBinaryTest,BasicTest)53 TEST_F(JsonBinaryTest, BasicTest)
54 {
55 const char *doc= "false";
56
57 const char *msg;
58 size_t msg_offset;
59
60 std::auto_ptr<Json_dom> dom(Json_dom::parse(doc, strlen(doc),
61 &msg, &msg_offset));
62 String buf;
63 EXPECT_FALSE(serialize(dom.get(), &buf));
64 Value val1= parse_binary(buf.ptr(), buf.length());
65 EXPECT_TRUE(val1.is_valid());
66 EXPECT_EQ(Value::LITERAL_FALSE, val1.type());
67
68 doc= "-123";
69 dom.reset(Json_dom::parse(doc, strlen(doc), &msg, &msg_offset));
70 EXPECT_FALSE(serialize(dom.get(), &buf));
71 Value val2= parse_binary(buf.ptr(), buf.length());
72 EXPECT_TRUE(val2.is_valid());
73 EXPECT_EQ(Value::INT, val2.type());
74 EXPECT_EQ(-123LL, val2.get_int64());
75
76 doc= "3.14";
77 dom.reset(Json_dom::parse(doc, strlen(doc), &msg, &msg_offset));
78 EXPECT_FALSE(serialize(dom.get(), &buf));
79 Value val3= parse_binary(buf.ptr(), buf.length());
80 EXPECT_TRUE(val3.is_valid());
81 EXPECT_EQ(Value::DOUBLE, val3.type());
82 EXPECT_EQ(3.14, val3.get_double());
83
84 doc= "18446744073709551615";
85 dom.reset(Json_dom::parse(doc, strlen(doc), &msg, &msg_offset));
86 EXPECT_FALSE(serialize(dom.get(), &buf));
87 Value val4= parse_binary(buf.ptr(), buf.length());
88 EXPECT_TRUE(val4.is_valid());
89 EXPECT_EQ(Value::UINT, val4.type());
90 EXPECT_EQ(18446744073709551615ULL, val4.get_uint64());
91
92 doc= "\"abc\"";
93 dom.reset(Json_dom::parse(doc, strlen(doc), &msg, &msg_offset));
94 EXPECT_FALSE(serialize(dom.get(), &buf));
95 Value val5= parse_binary(buf.ptr(), buf.length());
96 EXPECT_TRUE(val5.is_valid());
97 EXPECT_EQ(Value::STRING, val5.type());
98 EXPECT_EQ("abc", get_string(val5));
99
100 doc= "[ 1, 2, 3 ]";
101 dom.reset(Json_dom::parse(doc, strlen(doc), &msg, &msg_offset));
102 EXPECT_FALSE(serialize(dom.get(), &buf));
103 Value val6= parse_binary(buf.ptr(), buf.length());
104 EXPECT_TRUE(val6.is_valid());
105 EXPECT_EQ(Value::ARRAY, val6.type());
106 EXPECT_EQ(3U, val6.element_count());
107 for (int i= 0; i < 3; i++)
108 {
109 Value v= val6.element(i);
110 EXPECT_EQ(Value::INT, v.type());
111 EXPECT_EQ(i + 1, v.get_int64());
112 }
113 EXPECT_EQ(Value::ERROR, val6.element(3).type());
114
115 doc= "[ 1, [ \"a\", [ 3.14 ] ] ]";
116 dom.reset(Json_dom::parse(doc, strlen(doc), &msg, &msg_offset));
117 EXPECT_FALSE(serialize(dom.get(), &buf));
118 // Top-level doc is an array of size 2.
119 Value val7= parse_binary(buf.ptr(), buf.length());
120 EXPECT_TRUE(val7.is_valid());
121 EXPECT_EQ(Value::ARRAY, val7.type());
122 EXPECT_EQ(2U, val7.element_count());
123 // First element is the integer 1.
124 Value v7_1= val7.element(0);
125 EXPECT_TRUE(v7_1.is_valid());
126 EXPECT_EQ(Value::INT, v7_1.type());
127 EXPECT_EQ(1, v7_1.get_int64());
128 // The second element is a nested array of size 2.
129 Value v7_2= val7.element(1);
130 EXPECT_TRUE(v7_2.is_valid());
131 EXPECT_EQ(Value::ARRAY, v7_2.type());
132 EXPECT_EQ(2U, v7_2.element_count());
133 // The first element of the nested array is the string "a".
134 Value v7_3= v7_2.element(0);
135 EXPECT_TRUE(v7_3.is_valid());
136 EXPECT_EQ(Value::STRING, v7_3.type());
137 EXPECT_EQ("a", get_string(v7_3));
138 // The second element of the nested array is yet another array.
139 Value v7_4= v7_2.element(1);
140 EXPECT_TRUE(v7_4.is_valid());
141 EXPECT_EQ(Value::ARRAY, v7_4.type());
142 // The second nested array has one element, the double 3.14.
143 EXPECT_EQ(1U, v7_4.element_count());
144 Value v7_5= v7_4.element(0);
145 EXPECT_TRUE(v7_5.is_valid());
146 EXPECT_EQ(Value::DOUBLE, v7_5.type());
147 EXPECT_EQ(3.14, v7_5.get_double());
148
149 doc= "{\"key\" : \"val\"}";
150 dom.reset(Json_dom::parse(doc, strlen(doc), &msg, &msg_offset));
151 EXPECT_FALSE(serialize(dom.get(), &buf));
152 Value val8= parse_binary(buf.ptr(), buf.length());
153 EXPECT_TRUE(val8.is_valid());
154 EXPECT_EQ(Value::OBJECT, val8.type());
155 EXPECT_EQ(1U, val8.element_count());
156 Value val8_k= val8.key(0);
157 EXPECT_TRUE(val8_k.is_valid());
158 EXPECT_EQ(Value::STRING, val8_k.type());
159 EXPECT_EQ("key", get_string(val8_k));
160 Value val8_v= val8.element(0);
161 EXPECT_TRUE(val8_v.is_valid());
162 EXPECT_EQ(Value::STRING, val8_v.type());
163 EXPECT_EQ("val", get_string(val8_v));
164 EXPECT_EQ(Value::ERROR, val8.key(1).type());
165 EXPECT_EQ(Value::ERROR, val8.element(1).type());
166
167 Value v8_v1= val8.lookup("key", 3);
168 EXPECT_EQ(Value::STRING, v8_v1.type());
169 EXPECT_TRUE(v8_v1.is_valid());
170 EXPECT_EQ("val", get_string(v8_v1));
171
172 doc= "{ \"a\" : \"b\", \"c\" : [ \"d\" ] }";
173 dom.reset(Json_dom::parse(doc, strlen(doc), &msg, &msg_offset));
174 EXPECT_FALSE(serialize(dom.get(), &buf));
175 Value val9= parse_binary(buf.ptr(), buf.length());
176 EXPECT_TRUE(val9.is_valid());
177 EXPECT_EQ(Value::OBJECT, val9.type());
178 EXPECT_EQ(2U, val9.element_count());
179 Value v9_k1= val9.key(0);
180 EXPECT_EQ(Value::STRING, v9_k1.type());
181 EXPECT_EQ("a", get_string(v9_k1));
182 Value v9_v1= val9.element(0);
183 EXPECT_EQ(Value::STRING, v9_v1.type());
184 EXPECT_EQ("b", get_string(v9_v1));
185 Value v9_k2= val9.key(1);
186 EXPECT_EQ(Value::STRING, v9_k2.type());
187 EXPECT_EQ("c", get_string(v9_k2));
188 Value v9_v2= val9.element(1);
189 EXPECT_EQ(Value::ARRAY, v9_v2.type());
190 EXPECT_EQ(1U, v9_v2.element_count());
191 Value v9_v2_1= v9_v2.element(0);
192 EXPECT_EQ(Value::STRING, v9_v2_1.type());
193 EXPECT_EQ("d", get_string(v9_v2_1));
194
195 EXPECT_EQ("b", get_string(val9.lookup("a", 1)));
196 Value v9_c= val9.lookup("c", 1);
197 EXPECT_EQ(Value::ARRAY, v9_c.type());
198 EXPECT_EQ(1U, v9_c.element_count());
199 Value v9_c1= v9_c.element(0);
200 EXPECT_EQ(Value::STRING, v9_c1.type());
201 EXPECT_EQ("d", get_string(v9_c1));
202
203 char blob[4];
204 int4store(blob, 0xCAFEBABEU);
205 Json_opaque opaque(MYSQL_TYPE_TINY_BLOB, blob, 4);
206 EXPECT_FALSE(serialize(&opaque, &buf));
207 Value val10= parse_binary(buf.ptr(), buf.length());
208 EXPECT_TRUE(val10.is_valid());
209 EXPECT_EQ(Value::OPAQUE, val10.type());
210 EXPECT_EQ(MYSQL_TYPE_TINY_BLOB, val10.field_type());
211 EXPECT_EQ(4U, val10.get_data_length());
212 EXPECT_EQ(0xCAFEBABEU, uint4korr(val10.get_data()));
213
214 doc= "[true,false,null,0,\"0\",\"\",{},[]]";
215 dom.reset(Json_dom::parse(doc, strlen(doc), &msg, &msg_offset));
216 EXPECT_FALSE(serialize(dom.get(), &buf));
217 Value val11= parse_binary(buf.ptr(), buf.length());
218 EXPECT_TRUE(val11.is_valid());
219 EXPECT_EQ(Value::ARRAY, val11.type());
220 EXPECT_EQ(8U, val11.element_count());
221 EXPECT_EQ(Value::LITERAL_TRUE, val11.element(0).type());
222 EXPECT_EQ(Value::LITERAL_FALSE, val11.element(1).type());
223 EXPECT_EQ(Value::LITERAL_NULL, val11.element(2).type());
224 EXPECT_EQ(Value::INT, val11.element(3).type());
225 EXPECT_EQ(Value::STRING, val11.element(4).type());
226 EXPECT_EQ(Value::STRING, val11.element(5).type());
227 EXPECT_EQ(Value::OBJECT, val11.element(6).type());
228 EXPECT_EQ(Value::ARRAY, val11.element(7).type());
229 EXPECT_EQ(0, val11.element(3).get_int64());
230 EXPECT_EQ("0", get_string(val11.element(4)));
231 EXPECT_EQ("", get_string(val11.element(5)));
232 EXPECT_EQ(0U, val11.element(6).element_count());
233 EXPECT_EQ(0U, val11.element(7).element_count());
234
235 doc= "{}";
236 dom.reset(Json_dom::parse(doc, strlen(doc), &msg, &msg_offset));
237 EXPECT_FALSE(serialize(dom.get(), &buf));
238 Value val12= parse_binary(buf.ptr(), buf.length());
239 EXPECT_TRUE(val12.is_valid());
240 EXPECT_EQ(Value::OBJECT, val12.type());
241 EXPECT_EQ(0U, val12.element_count());
242 EXPECT_EQ(Value::ERROR, val12.lookup("", 0).type());
243 EXPECT_EQ(Value::ERROR, val12.lookup("key", 3).type());
244 EXPECT_FALSE(val12.lookup("no such key", 11).is_valid());
245
246 doc= "[]";
247 dom.reset(Json_dom::parse(doc, strlen(doc), &msg, &msg_offset));
248 EXPECT_FALSE(serialize(dom.get(), &buf));
249 Value val13= parse_binary(buf.ptr(), buf.length());
250 EXPECT_TRUE(val13.is_valid());
251 EXPECT_EQ(Value::ARRAY, val13.type());
252 EXPECT_EQ(0U, val13.element_count());
253
254 doc= "{\"key1\":1, \"key2\":2, \"key1\":3, \"key1\\u0000x\":4, "
255 "\"key1\\u0000y\":5, \"a\":6, \"ab\":7, \"b\":8, \"\":9, \"\":10}";
256 const std::string expected_keys[]=
257 {
258 "", "a", "b", "ab", "key1", "key2",
259 std::string("key1\0x", 6), std::string("key1\0y", 6)
260 };
261 const int64 expected_values[]= { 9, 6, 8, 7, 1, 2, 4, 5 };
262 dom.reset(Json_dom::parse(doc, strlen(doc), &msg, &msg_offset));
263 EXPECT_FALSE(serialize(dom.get(), &buf));
264 Value val14= parse_binary(buf.ptr(), buf.length());
265 EXPECT_TRUE(val14.is_valid());
266 EXPECT_EQ(Value::OBJECT, val14.type());
267 EXPECT_EQ(8U, val14.element_count());
268 for (size_t i= 0; i < val14.element_count(); i++)
269 {
270 EXPECT_EQ(expected_keys[i], get_string(val14.key(i)));
271
272 Value val= val14.element(i);
273 EXPECT_EQ(Value::INT, val.type());
274 EXPECT_EQ(expected_values[i], val.get_int64());
275
276 Value val_lookup= val14.lookup(expected_keys[i].data(),
277 expected_keys[i].length());
278 EXPECT_EQ(Value::INT, val_lookup.type());
279 EXPECT_EQ(expected_values[i], val_lookup.get_int64());
280 }
281
282 // Store a decimal.
283 my_decimal md;
284 EXPECT_EQ(E_DEC_OK, double2my_decimal(E_DEC_FATAL_ERROR, 123.45, &md));
285 EXPECT_EQ(5U, md.precision());
286 EXPECT_EQ(2, md.frac);
287
288 Json_decimal jd(md);
289 EXPECT_FALSE(serialize(&jd, &buf));
290 Value val15= parse_binary(buf.ptr(), buf.length());
291 EXPECT_TRUE(val15.is_valid());
292 EXPECT_EQ(Value::OPAQUE, val15.type());
293 EXPECT_EQ(MYSQL_TYPE_NEWDECIMAL, val15.field_type());
294
295 my_decimal md_out;
296 EXPECT_FALSE(Json_decimal::convert_from_binary(val15.get_data(),
297 val15.get_data_length(),
298 &md_out));
299 EXPECT_EQ(5U, md_out.precision());
300 EXPECT_EQ(2, md_out.frac);
301 double d_out;
302 EXPECT_EQ(E_DEC_OK,
303 my_decimal2double(E_DEC_FATAL_ERROR, &md_out, &d_out));
304 EXPECT_EQ(123.45, d_out);
305 }
306
307
308 /*
309 Test storing of TIME, DATE and DATETIME.
310 */
TEST_F(JsonBinaryTest,DateAndTimeTest)311 TEST_F(JsonBinaryTest, DateAndTimeTest)
312 {
313 const char *tstr= "13:14:15.654321";
314 const char *dstr= "20140517";
315 const char *dtstr= "2015-01-15 15:16:17.123456";
316 MYSQL_TIME t;
317 MYSQL_TIME d;
318 MYSQL_TIME dt;
319 MYSQL_TIME_STATUS status;
320 EXPECT_FALSE(str_to_time(&my_charset_utf8mb4_bin, tstr, strlen(tstr),
321 &t, 0, &status));
322 EXPECT_FALSE(str_to_datetime(&my_charset_utf8mb4_bin, dstr, strlen(dstr),
323 &d, 0, &status));
324 EXPECT_FALSE(str_to_datetime(&my_charset_utf8mb4_bin, dtstr, strlen(dtstr),
325 &dt, 0, &status));
326
327 // Create an array that contains a TIME, a DATE and a DATETIME.
328 Json_array array;
329 Json_datetime tt(t, MYSQL_TYPE_TIME);
330 Json_datetime td(d, MYSQL_TYPE_DATE);
331 Json_datetime tdt(dt, MYSQL_TYPE_DATETIME);
332 array.append_clone(&tt);
333 array.append_clone(&td);
334 array.append_clone(&tdt);
335
336 // Store the array ...
337 String buf;
338 EXPECT_FALSE(serialize(&array, &buf));
339
340 // ... and read it back.
341 Value val= parse_binary(buf.ptr(), buf.length());
342 EXPECT_TRUE(val.is_valid());
343 EXPECT_EQ(Value::ARRAY, val.type());
344 EXPECT_EQ(3U, val.element_count());
345
346 // The first element should be the TIME "13:14:15.654321".
347 Value t_val= val.element(0);
348 EXPECT_EQ(Value::OPAQUE, t_val.type());
349 EXPECT_EQ(MYSQL_TYPE_TIME, t_val.field_type());
350 const size_t json_datetime_packed_size= Json_datetime::PACKED_SIZE;
351 EXPECT_EQ(json_datetime_packed_size, t_val.get_data_length());
352 MYSQL_TIME t_out;
353 Json_datetime::from_packed(t_val.get_data(), t_val.field_type(), &t_out);
354 EXPECT_EQ(13U, t_out.hour);
355 EXPECT_EQ(14U, t_out.minute);
356 EXPECT_EQ(15U, t_out.second);
357 EXPECT_EQ(654321U, t_out.second_part);
358 EXPECT_FALSE(t_out.neg);
359 EXPECT_EQ(MYSQL_TIMESTAMP_TIME, t_out.time_type);
360
361 // The second element should be the DATE "2014-05-17".
362 Value d_val= val.element(1);
363 EXPECT_EQ(Value::OPAQUE, d_val.type());
364 EXPECT_EQ(MYSQL_TYPE_DATE, d_val.field_type());
365 EXPECT_EQ(json_datetime_packed_size, d_val.get_data_length());
366 MYSQL_TIME d_out;
367 Json_datetime::from_packed(d_val.get_data(), d_val.field_type(), &d_out);
368 EXPECT_EQ(2014U, d_out.year);
369 EXPECT_EQ(5U, d_out.month);
370 EXPECT_EQ(17U, d_out.day);
371 EXPECT_FALSE(d_out.neg);
372 EXPECT_EQ(MYSQL_TIMESTAMP_DATE, d_out.time_type);
373
374 // The third element should be the DATETIME "2015-01-15 15:16:17.123456".
375 Value dt_val= val.element(2);
376 EXPECT_EQ(Value::OPAQUE, dt_val.type());
377 EXPECT_EQ(MYSQL_TYPE_DATETIME, dt_val.field_type());
378 EXPECT_EQ(json_datetime_packed_size, dt_val.get_data_length());
379 MYSQL_TIME dt_out;
380 Json_datetime::from_packed(dt_val.get_data(), dt_val.field_type(), &dt_out);
381 EXPECT_EQ(2015U, dt_out.year);
382 EXPECT_EQ(1U, dt_out.month);
383 EXPECT_EQ(15U, dt_out.day);
384 EXPECT_EQ(15U, dt_out.hour);
385 EXPECT_EQ(16U, dt_out.minute);
386 EXPECT_EQ(17U, dt_out.second);
387 EXPECT_EQ(123456U, dt_out.second_part);
388 EXPECT_FALSE(dt_out.neg);
389 EXPECT_EQ(MYSQL_TIMESTAMP_DATETIME, dt_out.time_type);
390 }
391
392
393 /*
394 Validate that the contents of an array are as expected. The array
395 should contain values that alternate between literal true, literal
396 false, literal null and the string "a".
397 */
validate_array_contents(const Value & array,size_t expected_size)398 void validate_array_contents(const Value &array, size_t expected_size)
399 {
400 EXPECT_EQ(Value::ARRAY, array.type());
401 EXPECT_TRUE(array.is_valid());
402 EXPECT_EQ(expected_size, array.element_count());
403 for (size_t i= 0; i < array.element_count(); i++)
404 {
405 Value val= array.element(i);
406 EXPECT_TRUE(val.is_valid());
407 Value::enum_type t= val.type();
408 if (i % 4 == 0)
409 EXPECT_EQ(Value::LITERAL_TRUE, t);
410 else if (i % 4 == 1)
411 EXPECT_EQ(Value::LITERAL_FALSE, t);
412 else if (i % 4 == 2)
413 EXPECT_EQ(Value::LITERAL_NULL, t);
414 else
415 {
416 EXPECT_EQ(Value::STRING, t);
417 EXPECT_EQ("a", get_string(val));
418 }
419 }
420 }
421
422
423 /*
424 Test some arrays and objects that exceed 64KB. Arrays and objects
425 are stored in a different format if more than two bytes are required
426 for the internal offsets.
427 */
TEST_F(JsonBinaryTest,LargeDocumentTest)428 TEST_F(JsonBinaryTest, LargeDocumentTest)
429 {
430 Json_array array;
431 Json_boolean literal_true(true);
432 Json_boolean literal_false(false);
433 Json_null literal_null;
434 Json_string string("a");
435
436 for (int i= 0; i < 20000; i++)
437 {
438 array.append_clone(&literal_true);
439 array.append_clone(&literal_false);
440 array.append_clone(&literal_null);
441 array.append_clone(&string);
442 }
443 EXPECT_EQ(80000U, array.size());
444
445 String buf;
446 EXPECT_FALSE(serialize(&array, &buf));
447 Value val= parse_binary(buf.ptr(), buf.length());
448 {
449 SCOPED_TRACE("");
450 validate_array_contents(val, array.size());
451 }
452
453 /*
454 Extract the raw binary representation of the large array, and verify
455 that it is valid.
456 */
457 String raw;
458 EXPECT_FALSE(val.raw_binary(&raw));
459 {
460 SCOPED_TRACE("");
461 validate_array_contents(parse_binary(raw.ptr(), raw.length()),
462 array.size());
463 }
464
465 Json_array array2;
466 array2.append_clone(&array);
467 array2.append_clone(&array);
468 EXPECT_FALSE(serialize(&array2, &buf));
469 Value val2= parse_binary(buf.ptr(), buf.length());
470 EXPECT_TRUE(val2.is_valid());
471 EXPECT_EQ(Value::ARRAY, val2.type());
472 EXPECT_EQ(2U, val2.element_count());
473 {
474 SCOPED_TRACE("");
475 validate_array_contents(val2.element(0), array.size());
476 }
477 {
478 SCOPED_TRACE("");
479 validate_array_contents(val2.element(1), array.size());
480 }
481
482 Json_object object;
483 object.add_clone("a", &array);
484 Json_string s_c("c");
485 object.add_clone("b", &s_c);
486 EXPECT_FALSE(serialize(&object, &buf));
487 Value val3= parse_binary(buf.ptr(), buf.length());
488 EXPECT_TRUE(val3.is_valid());
489 EXPECT_EQ(Value::OBJECT, val3.type());
490 EXPECT_EQ(2U, val3.element_count());
491 EXPECT_EQ("a", get_string(val3.key(0)));
492 {
493 SCOPED_TRACE("");
494 validate_array_contents(val3.element(0), array.size());
495 }
496 EXPECT_EQ("b", get_string(val3.key(1)));
497 EXPECT_EQ(Value::STRING, val3.element(1).type());
498 EXPECT_EQ("c", get_string(val3.element(1)));
499
500 {
501 SCOPED_TRACE("");
502 validate_array_contents(val3.lookup("a", 1), array.size());
503 }
504 EXPECT_EQ("c", get_string(val3.lookup("b", 1)));
505
506 /*
507 Extract the raw binary representation of the large object, and verify
508 that it is valid.
509 */
510 EXPECT_FALSE(val3.raw_binary(&raw));
511 {
512 SCOPED_TRACE("");
513 Value val_a= parse_binary(raw.ptr(), raw.length()).lookup("a", 1);
514 validate_array_contents(val_a, array.size());
515 }
516
517 /*
518 Bug#23031146: INSERTING 64K SIZE RECORDS TAKE TOO MUCH TIME
519
520 If a big (>64KB) sub-document was located at a deep nesting level,
521 serialization used to be very slow.
522 */
523 {
524 SCOPED_TRACE("");
525 // Wrap "array" in 50 more levels of arrays.
526 const size_t depth= 50;
527 Json_array deeply_nested_array;
528 Json_array *current_array= &deeply_nested_array;
529 for (size_t i= 1; i < depth; i++)
530 {
531 Json_array *a= new (std::nothrow) Json_array();
532 ASSERT_FALSE(current_array->append_alias(a));
533 current_array= a;
534 }
535 current_array->append_clone(&array);
536 // Serialize it. This used to take "forever".
537 ASSERT_FALSE(serialize(&deeply_nested_array, &buf));
538 // Parse the serialized DOM and verify its contents.
539 Value val= parse_binary(buf.ptr(), buf.length());
540 for (size_t i= 0; i < depth; i++)
541 {
542 ASSERT_EQ(Value::ARRAY, val.type());
543 ASSERT_EQ(1U, val.element_count());
544 val= val.element(0);
545 }
546 validate_array_contents(val, array.size());
547
548 // Now test the same with object.
549 Json_object deeply_nested_object;
550 Json_object *current_object= &deeply_nested_object;
551 for (size_t i= 1; i < depth; i++)
552 {
553 Json_object *o= new (std::nothrow) Json_object();
554 ASSERT_FALSE(current_object->add_alias("key", o));
555 current_object= o;
556 }
557 current_object->add_clone("key", &array);
558 ASSERT_FALSE(serialize(&deeply_nested_object, &buf));
559 val= parse_binary(buf.ptr(), buf.length());
560 for (size_t i= 0; i < depth; i++)
561 {
562 ASSERT_EQ(Value::OBJECT, val.type());
563 ASSERT_EQ(1U, val.element_count());
564 ASSERT_EQ("key", get_string(val.key(0)));
565 val= val.element(0);
566 }
567 validate_array_contents(val, array.size());
568 }
569 }
570
571
572 /*
573 Various tests for the Value::raw_binary() function.
574 */
TEST_F(JsonBinaryTest,RawBinaryTest)575 TEST_F(JsonBinaryTest, RawBinaryTest)
576 {
577 Json_array array;
578 Json_string as("a string");
579 array.append_clone(&as);
580 Json_int ji(-123);
581 array.append_clone(&ji);
582 Json_uint jui(42);
583 array.append_clone(&jui);
584 Json_double jd(1.5);
585 array.append_clone(&jd);
586 Json_null jn;
587 array.append_clone(&jn);
588 Json_boolean jbt(true);
589 array.append_clone(&jbt);
590 Json_boolean jbf(false);
591 array.append_clone(&jbf);
592 Json_opaque jo(MYSQL_TYPE_BLOB, "abcd", 4);
593 array.append_clone(&jo);
594
595 Json_object object;
596 object.add_clone("key", &jbt);
597 array.append_clone(&object);
598
599 Json_array array2;
600 array2.append_clone(&jbf);
601 array.append_clone(&array2);
602
603 String buf;
604 EXPECT_FALSE(json_binary::serialize(&array, &buf));
605 Value v1= parse_binary(buf.ptr(), buf.length());
606
607 String raw;
608 EXPECT_FALSE(v1.raw_binary(&raw));
609 Value v1_copy= parse_binary(raw.ptr(), raw.length());
610 EXPECT_EQ(Value::ARRAY, v1_copy.type());
611 EXPECT_EQ(array.size(), v1_copy.element_count());
612
613 EXPECT_FALSE(v1.element(0).raw_binary(&raw));
614 Value v1_0= parse_binary(raw.ptr(), raw.length());
615 EXPECT_EQ(Value::STRING, v1_0.type());
616 EXPECT_EQ("a string", std::string(v1_0.get_data(), v1_0.get_data_length()));
617
618 EXPECT_FALSE(v1.element(1).raw_binary(&raw));
619 Value v1_1= parse_binary(raw.ptr(), raw.length());
620 EXPECT_EQ(Value::INT, v1_1.type());
621 EXPECT_EQ(-123, v1_1.get_int64());
622
623 EXPECT_FALSE(v1.element(2).raw_binary(&raw));
624 Value v1_2= parse_binary(raw.ptr(), raw.length());
625 EXPECT_EQ(Value::UINT, v1_2.type());
626 EXPECT_EQ(42U, v1_2.get_uint64());
627
628 EXPECT_FALSE(v1.element(3).raw_binary(&raw));
629 Value v1_3= parse_binary(raw.ptr(), raw.length());
630 EXPECT_EQ(Value::DOUBLE, v1_3.type());
631 EXPECT_EQ(1.5, v1_3.get_double());
632
633 EXPECT_FALSE(v1.element(4).raw_binary(&raw));
634 Value v1_4= parse_binary(raw.ptr(), raw.length());
635 EXPECT_EQ(Value::LITERAL_NULL, v1_4.type());
636
637 EXPECT_FALSE(v1.element(5).raw_binary(&raw));
638 Value v1_5= parse_binary(raw.ptr(), raw.length());
639 EXPECT_EQ(Value::LITERAL_TRUE, v1_5.type());
640
641 EXPECT_FALSE(v1.element(6).raw_binary(&raw));
642 Value v1_6= parse_binary(raw.ptr(), raw.length());
643 EXPECT_EQ(Value::LITERAL_FALSE, v1_6.type());
644
645 EXPECT_FALSE(v1.element(7).raw_binary(&raw));
646 Value v1_7= parse_binary(raw.ptr(), raw.length());
647 EXPECT_EQ(Value::OPAQUE, v1_7.type());
648 EXPECT_EQ(MYSQL_TYPE_BLOB, v1_7.field_type());
649 EXPECT_EQ("abcd", std::string(v1_7.get_data(), v1_7.get_data_length()));
650
651 EXPECT_FALSE(v1.element(8).raw_binary(&raw));
652 Value v1_8= parse_binary(raw.ptr(), raw.length());
653 EXPECT_EQ(Value::OBJECT, v1_8.type());
654 EXPECT_EQ(object.cardinality(), v1_8.element_count());
655 EXPECT_EQ(Value::LITERAL_TRUE, v1_8.lookup("key", 3).type());
656
657 EXPECT_FALSE(v1.element(8).key(0).raw_binary(&raw));
658 Value v1_8_key= parse_binary(raw.ptr(), raw.length());
659 EXPECT_EQ(Value::STRING, v1_8_key.type());
660 EXPECT_EQ("key", std::string(v1_8_key.get_data(),
661 v1_8_key.get_data_length()));
662
663 EXPECT_FALSE(v1.element(8).element(0).raw_binary(&raw));
664 Value v1_8_val= parse_binary(raw.ptr(), raw.length());
665 EXPECT_EQ(Value::LITERAL_TRUE, v1_8_val.type());
666
667 EXPECT_FALSE(v1.element(9).raw_binary(&raw));
668 Value v1_9= parse_binary(raw.ptr(), raw.length());
669 EXPECT_EQ(Value::ARRAY, v1_9.type());
670 EXPECT_EQ(array2.size(), v1_9.element_count());
671 EXPECT_EQ(Value::LITERAL_FALSE, v1_9.element(0).type());
672
673 EXPECT_FALSE(v1.element(9).element(0).raw_binary(&raw));
674 Value v1_9_0= parse_binary(raw.ptr(), raw.length());
675 EXPECT_EQ(Value::LITERAL_FALSE, v1_9_0.type());
676 }
677
678
679 /*
680 Create a JSON string of the given size, serialize it as a JSON binary, and
681 then deserialize it and verify that we get the same string back.
682 */
serialize_deserialize_string(size_t size)683 void serialize_deserialize_string(size_t size)
684 {
685 SCOPED_TRACE(testing::Message() << "size = " << size);
686 char *str= new char[size];
687 memset(str, 'a', size);
688 Json_string jstr(std::string(str, size));
689
690 String buf;
691 EXPECT_FALSE(json_binary::serialize(&jstr, &buf));
692 Value v= parse_binary(buf.ptr(), buf.length());
693 EXPECT_EQ(Value::STRING, v.type());
694 EXPECT_EQ(size, v.get_data_length());
695 EXPECT_EQ(0, memcmp(str, v.get_data(), size));
696
697 delete[] str;
698 }
699
700
701 /*
702 Test strings of variable length. Test especially around the boundaries
703 where the representation of the string length changes:
704
705 - Strings of length 0-127 use 1 byte length fields.
706 - Strings of length 128-16383 use 2 byte length fields.
707 - Strings of length 16384-2097151 use 3 byte length fields.
708 - Strings of length 2097152-268435455 use 4 byte length fields.
709 - Strings of length 268435456-... use 5 byte length fields.
710
711 We probably don't have enough memory to test the last category here...
712 */
TEST_F(JsonBinaryTest,StringLengthTest)713 TEST_F(JsonBinaryTest, StringLengthTest)
714 {
715 serialize_deserialize_string(0);
716 serialize_deserialize_string(1);
717 serialize_deserialize_string(127);
718 serialize_deserialize_string(128);
719 serialize_deserialize_string(16383);
720 serialize_deserialize_string(16384);
721 serialize_deserialize_string(2097151);
722 serialize_deserialize_string(2097152);
723 serialize_deserialize_string(3000000);
724 }
725
726 }
727