1/* Copyright (c) 2011, Monty Program Ab
2 Copyright (c) 2011, Oleksandr Byelkin
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7
8 1. Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 2. Redistributions in binary form must the following disclaimer in
12 the documentation and/or other materials provided with the
13 distribution.
14
15 THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND ANY
16 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
19 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
22 USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 SUCH DAMAGE.
27*/
28
29#include <my_global.h>
30#include <my_sys.h>
31#include <m_string.h>
32#include <ma_dyncol.h>
33#include <tap.h>
34
35void test_value_single_null()
36{
37 int rc= FALSE;
38 uint ids[1]= {1};
39 DYNAMIC_COLUMN_VALUE val, res;
40 DYNAMIC_COLUMN str;
41 /* init values */
42 val.type= DYN_COL_NULL;
43 mariadb_dyncol_value_init(&res);
44 /* create column */
45 if (mariadb_dyncol_create_many_num(&str, 1, ids, &val, 1))
46 goto err;
47 dynstr_append(&str, "\1"); str.length--; //check for overflow
48 /* read column */
49 if (mariadb_dyncol_get_num(&str, 1, &res))
50 goto err;
51 rc= (res.type == DYN_COL_NULL);
52err:
53 ok(rc, "%s", "NULL");
54 /* cleanup */
55 mariadb_dyncol_free(&str);
56}
57
58void test_value_single_uint(ulonglong num, const char *name)
59{
60 int rc= FALSE;
61 uint ids[1]= {1};
62 DYNAMIC_COLUMN_VALUE val, res;
63 DYNAMIC_COLUMN str;
64 /* init values */
65 val.type= DYN_COL_UINT;
66 val.x.ulong_value= num;
67 mariadb_dyncol_value_init(&res);
68 /* create column */
69 if (mariadb_dyncol_create_many_num(&str, 1, ids, &val, 1))
70 goto err;
71 dynstr_append(&str, "\1"); str.length--; //check for overflow
72 /* read column */
73 if (mariadb_dyncol_get_num(&str, 1, &res))
74 goto err;
75 rc= (res.type == DYN_COL_UINT) && (res.x.ulong_value == num);
76 num= res.x.ulong_value;
77err:
78 ok(rc, "%s - %llu", name, num);
79 /* cleanup */
80 mariadb_dyncol_free(&str);
81}
82
83void test_value_single_sint(longlong num, const char *name)
84{
85 int rc= FALSE;
86 uint ids[1]= {1};
87 DYNAMIC_COLUMN_VALUE val, res;
88 DYNAMIC_COLUMN str;
89 /* init values */
90 val.type= DYN_COL_INT;
91 val.x.long_value= num;
92 mariadb_dyncol_value_init(&res);
93 /* create column */
94 if (mariadb_dyncol_create_many_num(&str, 1, ids, &val, 1))
95 goto err;
96 dynstr_append(&str, "\1"); str.length--; //check for overflow
97 /* read column */
98 if (mariadb_dyncol_get_num(&str, 1, &res))
99 goto err;
100 rc= (res.type == DYN_COL_INT) && (res.x.long_value == num);
101 num= res.x.ulong_value;
102err:
103 ok(rc, "%s - %lld", name, num);
104 /* cleanup */
105 mariadb_dyncol_free(&str);
106}
107
108
109void test_value_single_double(double num, const char *name)
110{
111 int rc= FALSE;
112 uint ids[1]= {1};
113 DYNAMIC_COLUMN_VALUE val, res;
114 DYNAMIC_COLUMN str;
115 /* init values */
116 val.type= DYN_COL_DOUBLE;
117 val.x.double_value= num;
118 mariadb_dyncol_value_init(&res);
119 /* create column */
120 if (mariadb_dyncol_create_many_num(&str, 1, ids, &val, 1))
121 goto err;
122 dynstr_append(&str, "\1"); str.length--; //check for overflow
123 /* read column */
124 if (mariadb_dyncol_get_num(&str, 1, &res))
125 goto err;
126 rc= (res.type == DYN_COL_DOUBLE) && (res.x.double_value == num);
127 num= res.x.double_value;
128err:
129 ok(rc, "%s - %lf", name, num);
130 /* cleanup */
131 mariadb_dyncol_free(&str);
132}
133
134void test_value_single_decimal(const char *num)
135{
136 char *end= (((char*)num) + strlen(num));
137 char buff[80];
138 int rc= FALSE;
139 int length= 80;
140 uint ids[1]= {1};
141 DYNAMIC_COLUMN_VALUE val, res;
142 DYNAMIC_COLUMN str;
143
144 /* init values */
145 mariadb_dyncol_prepare_decimal(&val); // special procedure for decimal!!!
146 if (string2decimal(num, &val.x.decimal.value, &end) != E_DEC_OK)
147 goto err;
148 mariadb_dyncol_value_init(&res);
149
150 /* create column */
151 if (mariadb_dyncol_create_many_num(&str, 1, ids, &val, 1))
152 goto err;
153 dynstr_append(&str, "\1"); str.length--; //check for overflow
154 /* read column */
155 if (mariadb_dyncol_get_num(&str, 1, &res))
156 goto err;
157 rc= ((res.type == DYN_COL_DECIMAL) &&
158 (decimal_cmp(&res.x.decimal.value, &val.x.decimal.value) == 0));
159 decimal2string(&res.x.decimal.value, buff, &length, 0, 0, ' ');
160err:
161 ok(rc, "%s - %s", num, buff);
162 /* cleanup */
163 mariadb_dyncol_free(&str);
164}
165
166static CHARSET_INFO *charset_list[]=
167{
168#ifdef HAVE_CHARSET_big5
169 &my_charset_big5_chinese_ci,
170 &my_charset_big5_bin,
171#endif
172#ifdef HAVE_CHARSET_euckr
173 &my_charset_euckr_korean_ci,
174 &my_charset_euckr_bin,
175#endif
176#ifdef HAVE_CHARSET_gb2312
177 &my_charset_gb2312_chinese_ci,
178 &my_charset_gb2312_bin,
179#endif
180#ifdef HAVE_CHARSET_gbk
181 &my_charset_gbk_chinese_ci,
182 &my_charset_gbk_bin,
183#endif
184#ifdef HAVE_CHARSET_latin1
185 &my_charset_latin1,
186 &my_charset_latin1_bin,
187#endif
188#ifdef HAVE_CHARSET_sjis
189 &my_charset_sjis_japanese_ci,
190 &my_charset_sjis_bin,
191#endif
192#ifdef HAVE_CHARSET_tis620
193 &my_charset_tis620_thai_ci,
194 &my_charset_tis620_bin,
195#endif
196#ifdef HAVE_CHARSET_ujis
197 &my_charset_ujis_japanese_ci,
198 &my_charset_ujis_bin,
199#endif
200#ifdef HAVE_CHARSET_utf8
201 &my_charset_utf8_general_ci,
202#ifdef HAVE_UCA_COLLATIONS
203 &my_charset_utf8_unicode_ci,
204#endif
205 &my_charset_utf8_bin,
206#endif
207};
208
209
210void test_value_single_string(const char *string, size_t len,
211 CHARSET_INFO *cs)
212{
213 int rc= FALSE;
214 uint ids[1]= {1};
215 DYNAMIC_COLUMN_VALUE val, res;
216 DYNAMIC_COLUMN str;
217
218 /* init values */
219 val.type= DYN_COL_STRING;
220 val.x.string.value.str= (char*)string;
221 val.x.string.value.length= len;
222 val.x.string.charset= cs;
223 mariadb_dyncol_value_init(&res);
224
225 /* create column */
226 if (mariadb_dyncol_create_many_num(&str, 1, ids, &val, 1))
227 goto err;
228 dynstr_append(&str, "\1"); str.length--; //check for overflow
229 /* read column */
230 if (mariadb_dyncol_get_num(&str, 1, &res))
231 goto err;
232 rc= ((res.type == DYN_COL_STRING) &&
233 (res.x.string.value.length == len) &&
234 (memcmp(res.x.string.value.str, string, len) == 0) &&
235 (res.x.string.charset->number == cs->number));
236err:
237 ok(rc, "'%s' - '%s' %u %u-%s", string,
238 res.x.string.value.str, (uint)res.x.string.value.length,
239 (uint)res.x.string.charset->number, res.x.string.charset->name);
240 /* cleanup */
241 val.x.string.value.str= NULL; // we did not allocated it
242 mariadb_dyncol_free(&str);
243}
244
245void test_value_single_date(uint year, uint month, uint day, const char *name)
246{
247 int rc= FALSE;
248 uint ids[1]= {1};
249 DYNAMIC_COLUMN_VALUE val, res;
250 DYNAMIC_COLUMN str;
251 /* init values */
252 val.type= DYN_COL_DATE;
253 val.x.time_value.time_type= MYSQL_TIMESTAMP_DATE;
254 val.x.time_value.year= year;
255 val.x.time_value.month= month;
256 val.x.time_value.day= day;
257 mariadb_dyncol_value_init(&res);
258 /* create column */
259 if (mariadb_dyncol_create_many_num(&str, 1, ids, &val, 1))
260 goto err;
261 dynstr_append(&str, "\1"); str.length--; //check for overflow
262 /* read column */
263 if (mariadb_dyncol_get_num(&str, 1, &res))
264 goto err;
265 rc= ((res.type == DYN_COL_DATE) &&
266 (res.x.time_value.time_type == MYSQL_TIMESTAMP_DATE) &&
267 (res.x.time_value.year == year) &&
268 (res.x.time_value.month == month) &&
269 (res.x.time_value.day == day));
270err:
271 ok(rc, "%s - %04u-%02u-%02u", name, year, month, day);
272 /* cleanup */
273 mariadb_dyncol_free(&str);
274}
275
276void test_value_single_time(uint neg, uint hour, uint minute, uint second,
277 uint mic, const char *name)
278{
279 int rc= FALSE;
280 uint ids[1]= {1};
281 DYNAMIC_COLUMN_VALUE val, res;
282 DYNAMIC_COLUMN str;
283 /* init values */
284 val.type= DYN_COL_TIME;
285 val.x.time_value.time_type= MYSQL_TIMESTAMP_TIME;
286 val.x.time_value.neg= neg;
287 val.x.time_value.hour= hour;
288 val.x.time_value.minute= minute;
289 val.x.time_value.second= second;
290 val.x.time_value.second_part= mic;
291 mariadb_dyncol_value_init(&res);
292 /* create column */
293 if (mariadb_dyncol_create_many_num(&str, 1, ids, &val, 1))
294 goto err;
295 dynstr_append(&str, "\1"); str.length--; //check for overflow
296 /* read column */
297 if (mariadb_dyncol_get_num(&str, 1, &res))
298 goto err;
299 rc= ((res.type == DYN_COL_TIME) &&
300 (res.x.time_value.time_type == MYSQL_TIMESTAMP_TIME) &&
301 (res.x.time_value.neg == (int)neg) &&
302 (res.x.time_value.hour == hour) &&
303 (res.x.time_value.minute == minute) &&
304 (res.x.time_value.second == second) &&
305 (res.x.time_value.second_part == mic));
306err:
307 ok(rc, "%s - %c%02u:%02u:%02u.%06u", name, (neg ? '-' : '+'),
308 hour, minute, second, mic);
309 /* cleanup */
310 mariadb_dyncol_free(&str);
311}
312
313
314void test_value_single_datetime(uint neg, uint year, uint month, uint day,
315 uint hour, uint minute, uint second,
316 uint mic, const char *name)
317{
318 int rc= FALSE;
319 uint ids[1]= {1};
320 DYNAMIC_COLUMN_VALUE val, res;
321 DYNAMIC_COLUMN str;
322 /* init values */
323 val.type= DYN_COL_DATETIME;
324 val.x.time_value.time_type= MYSQL_TIMESTAMP_DATETIME;
325 val.x.time_value.neg= neg;
326 val.x.time_value.year= year;
327 val.x.time_value.month= month;
328 val.x.time_value.day= day;
329 val.x.time_value.hour= hour;
330 val.x.time_value.minute= minute;
331 val.x.time_value.second= second;
332 val.x.time_value.second_part= mic;
333 mariadb_dyncol_value_init(&res);
334 /* create column */
335 if (mariadb_dyncol_create_many_num(&str, 1, ids, &val, 1))
336 goto err;
337 dynstr_append(&str, "\1"); str.length--; //check for overflow
338 /* read column */
339 if (mariadb_dyncol_get_num(&str, 1, &res))
340 goto err;
341 rc= ((res.type == DYN_COL_DATETIME) &&
342 (res.x.time_value.time_type == MYSQL_TIMESTAMP_DATETIME) &&
343 (res.x.time_value.neg == (int)neg) &&
344 (res.x.time_value.year == year) &&
345 (res.x.time_value.month == month) &&
346 (res.x.time_value.day == day) &&
347 (res.x.time_value.hour == hour) &&
348 (res.x.time_value.minute == minute) &&
349 (res.x.time_value.second == second) &&
350 (res.x.time_value.second_part == mic));
351err:
352 ok(rc, "%s - %c %04u-%02u-%02u %02u:%02u:%02u.%06u", name, (neg ? '-' : '+'),
353 year, month, day, hour, minute, second, mic);
354 /* cleanup */
355 mariadb_dyncol_free(&str);
356}
357
358
359void test_value_multi(ulonglong num0,
360 longlong num1,
361 double num2,
362 const char *num3,
363 const char *string4, size_t len4, CHARSET_INFO *cs4,
364 uint year5, uint month5, uint day5,
365 uint neg6, uint hour6, uint minute6,
366 uint second6, uint mic6,
367 uint neg7, uint year7, uint month7, uint day7,
368 uint hour7, uint minute7, uint second7,
369 uint mic7,
370 uint *column_numbers,
371 const char *name)
372{
373 char *end3= (((char*)num3) + strlen(num3));
374 int rc= FALSE;
375 uint i;
376 DYNAMIC_COLUMN_VALUE val[9], res[9];
377 DYNAMIC_COLUMN str;
378 /* init values */
379 val[0].type= DYN_COL_UINT;
380 val[0].x.ulong_value= num0;
381 val[1].type= DYN_COL_INT;
382 val[1].x.long_value= num1;
383 val[2].type= DYN_COL_DOUBLE;
384 val[2].x.double_value= num2;
385 mariadb_dyncol_prepare_decimal(val + 3); // special procedure for decimal!!!
386 if (string2decimal(num3, &val[3].x.decimal.value, &end3) != E_DEC_OK)
387 goto err;
388 val[4].type= DYN_COL_STRING;
389 val[4].x.string.value.str= (char*)string4;
390 val[4].x.string.value.length= len4;
391 val[4].x.string.charset= cs4;
392 val[5].type= DYN_COL_DATE;
393 val[5].x.time_value.time_type= MYSQL_TIMESTAMP_DATE;
394 val[5].x.time_value.year= year5;
395 val[5].x.time_value.month= month5;
396 val[5].x.time_value.day= day5;
397 val[6].type= DYN_COL_TIME;
398 val[6].x.time_value.time_type= MYSQL_TIMESTAMP_TIME;
399 val[6].x.time_value.neg= neg6;
400 val[6].x.time_value.hour= hour6;
401 val[6].x.time_value.minute= minute6;
402 val[6].x.time_value.second= second6;
403 val[6].x.time_value.second_part= mic6;
404 val[7].type= DYN_COL_DATETIME;
405 val[7].x.time_value.time_type= MYSQL_TIMESTAMP_DATETIME;
406 val[7].x.time_value.neg= neg7;
407 val[7].x.time_value.year= year7;
408 val[7].x.time_value.month= month7;
409 val[7].x.time_value.day= day7;
410 val[7].x.time_value.hour= hour7;
411 val[7].x.time_value.minute= minute7;
412 val[7].x.time_value.second= second7;
413 val[7].x.time_value.second_part= mic7;
414 val[8].type= DYN_COL_NULL;
415 for (i= 0; i < 9; i++)
416 mariadb_dyncol_value_init(res + i);
417 /* create column */
418 if (mariadb_dyncol_create_many_num(&str, 9, column_numbers, val, 1))
419 goto err;
420 dynstr_append(&str, "\1"); str.length--; //check for overflow
421 /* read column */
422 for (i= 0; i < 9; i++)
423 if (mariadb_dyncol_get_num(&str, column_numbers[i], res + i))
424 goto err;
425 rc= ((res[0].type == DYN_COL_UINT) &&
426 (res[0].x.ulong_value == num0) &&
427 (res[1].type == DYN_COL_INT) &&
428 (res[1].x.long_value == num1) &&
429 (res[2].type == DYN_COL_DOUBLE) &&
430 (res[2].x.double_value == num2) &&
431 (res[3].type == DYN_COL_DECIMAL) &&
432 (decimal_cmp(&res[3].x.decimal.value, &val[3].x.decimal.value) == 0) &&
433 (res[4].type == DYN_COL_STRING) &&
434 (res[4].x.string.value.length == len4) &&
435 (memcmp(res[4].x.string.value.str, string4, len4) == 0) &&
436 (res[4].x.string.charset->number == cs4->number) &&
437 (res[5].type == DYN_COL_DATE) &&
438 (res[5].x.time_value.time_type == MYSQL_TIMESTAMP_DATE) &&
439 (res[5].x.time_value.year == year5) &&
440 (res[5].x.time_value.month == month5) &&
441 (res[5].x.time_value.day == day5) &&
442 (res[6].type == DYN_COL_TIME) &&
443 (res[6].x.time_value.time_type == MYSQL_TIMESTAMP_TIME) &&
444 (res[6].x.time_value.neg == (int)neg6) &&
445 (res[6].x.time_value.hour == hour6) &&
446 (res[6].x.time_value.minute == minute6) &&
447 (res[6].x.time_value.second == second6) &&
448 (res[6].x.time_value.second_part == mic6) &&
449 (res[7].type == DYN_COL_DATETIME) &&
450 (res[7].x.time_value.time_type == MYSQL_TIMESTAMP_DATETIME) &&
451 (res[7].x.time_value.neg == (int)neg7) &&
452 (res[7].x.time_value.year == year7) &&
453 (res[7].x.time_value.month == month7) &&
454 (res[7].x.time_value.day == day7) &&
455 (res[7].x.time_value.hour == hour7) &&
456 (res[7].x.time_value.minute == minute7) &&
457 (res[7].x.time_value.second == second7) &&
458 (res[7].x.time_value.second_part == mic7) &&
459 (res[8].type == DYN_COL_NULL));
460err:
461 ok(rc, "%s", name);
462 /* cleanup */
463 val[4].x.string.value.str= NULL; // we did not allocated it
464 mariadb_dyncol_free(&str);
465}
466
467
468void test_value_multi_same_num()
469{
470 int rc= FALSE;
471 uint i;
472 DYNAMIC_COLUMN_VALUE val[5];
473 uint column_numbers[]= {3,4,5,3,6}; // same column numbers
474 DYNAMIC_COLUMN str;
475 /* init values */
476 for (i= 0; i < 5; i++)
477 val[i].type= DYN_COL_NULL;
478 /* create column */
479 if (!mariadb_dyncol_create_many_num(&str, 5, column_numbers, val, 1))
480 goto err;
481 rc= TRUE;
482err:
483 ok(rc, "%s", "same column numbers check");
484 /* cleanup */
485 mariadb_dyncol_free(&str);
486}
487
488
489void test_update_multi(uint *column_numbers, uint *column_values,
490 my_bool *null_values, int only_add, int all)
491{
492 int rc= FALSE;
493 int i, j;
494 DYNAMIC_COLUMN str;
495 DYNAMIC_COLUMN_VALUE val;
496
497 val.type= DYN_COL_UINT;
498 val.x.ulong_value= column_values[0];
499 if (mariadb_dyncol_create_many_num(&str, 1, column_numbers, &val, 1))
500 goto err;
501 for (i= 1; i < all; i++)
502 {
503 val.type= (null_values[i] ? DYN_COL_NULL : DYN_COL_UINT);
504 val.x.ulong_value= column_values[i];
505 if (mariadb_dyncol_update_many_num(&str, 1, column_numbers +i, &val))
506 goto err;
507
508 /* check value(s) */
509 for (j= i; j >= (i < only_add ? 0 : i); j--)
510 {
511 if (mariadb_dyncol_get_num(&str, column_numbers[j], &val))
512 goto err;
513 if (null_values[j])
514 {
515 if (val.type != DYN_COL_NULL ||
516 mariadb_dyncol_exists_num(&str, column_numbers[j]) == ER_DYNCOL_YES)
517 goto err;
518 }
519 else
520 {
521 if (val.type != DYN_COL_UINT ||
522 val.x.ulong_value != column_values[j] ||
523 mariadb_dyncol_exists_num(&str, column_numbers[j]) == ER_DYNCOL_NO)
524 goto err;
525 }
526 }
527 if (i < only_add)
528 {
529 uint elements, *num;
530 if (mariadb_dyncol_list_num(&str, &elements, &num))
531 {
532 my_free(num);
533 goto err;
534 }
535 /* cross check arrays */
536 if ((int)elements != i + 1)
537 {
538 my_free(num);
539 goto err;
540 }
541 for(j= 0; j < i + 1; j++)
542 {
543 int k;
544 for(k= 0;
545 k < i + 1 && column_numbers[j] != num[k];
546 k++);
547 if (k >= i + 1)
548 {
549 my_free(num);
550 goto err;
551 }
552 for(k= 0;
553 k < i + 1 && column_numbers[k] != num[j];
554 k++);
555 if (k >= i + 1)
556 {
557 my_free(num);
558 goto err;
559 }
560 }
561 my_free(num);
562 }
563 }
564
565 rc= TRUE;
566err:
567 ok(rc, "%s", "add/delete/update");
568 /* cleanup */
569 mariadb_dyncol_free(&str);
570}
571
572void test_empty_string()
573{
574 DYNAMIC_COLUMN_VALUE val, res;
575 DYNAMIC_COLUMN str;
576 uint *array_of_uint;
577 uint number_of_uint;
578 int rc;
579 uint ids[1]= {1};
580 DYNAMIC_COLUMN_VALUE vals[1];
581 /* empty string */
582 bzero(&str, sizeof(str));
583
584 rc= mariadb_dyncol_get_num(&str, 1, &res);
585 ok( (rc == ER_DYNCOL_OK) && (res.type == DYN_COL_NULL), "%s", "empty get");
586
587 vals[0].type= DYN_COL_NULL;
588 rc= mariadb_dyncol_update_many_num(&str, 1, ids, vals);
589 ok( (rc == ER_DYNCOL_OK) && (str.str == 0), "%s", "empty delete");
590
591 rc= mariadb_dyncol_exists_num(&str, 1);
592 ok( (rc == ER_DYNCOL_NO), "%s", "empty exists");
593
594 rc= mariadb_dyncol_list_num(&str, &number_of_uint, &array_of_uint);
595 ok( (rc == ER_DYNCOL_OK) && (number_of_uint == 0) && (str.str == 0),
596 "%s", "empty list");
597
598 val.type= DYN_COL_UINT;
599 val.x.ulong_value= 1212;
600 rc= mariadb_dyncol_update_many_num(&str, 1, ids, &val);
601 if (rc == ER_DYNCOL_OK)
602 rc= mariadb_dyncol_get_num(&str, 1, &res);
603 ok( (rc == ER_DYNCOL_OK) && (str.str != 0) &&
604 (res.type == DYN_COL_UINT) && (res.x.ulong_value == val.x.ulong_value),
605 "%s", "empty update");
606 mariadb_dyncol_free(&str);
607}
608
609static void test_mdev_4994()
610{
611 DYNAMIC_COLUMN dyncol;
612 LEX_STRING key= {0,0};
613 DYNAMIC_COLUMN_VALUE val;
614 int rc;
615
616 val.type= DYN_COL_NULL;
617
618 mariadb_dyncol_init(&dyncol);
619 rc= mariadb_dyncol_create_many_named(&dyncol, 1, &key, &val, 0); /* crash */
620 ok( (rc == ER_DYNCOL_OK), "%s", "test_mdev_4994");
621 mariadb_dyncol_free(&dyncol);
622}
623
624static void test_mdev_4995()
625{
626 DYNAMIC_COLUMN dyncol;
627 uint column_count= 5;
628 int rc;
629
630 mariadb_dyncol_init(&dyncol);
631 rc= mariadb_dyncol_column_count(&dyncol,&column_count);
632
633 ok( (rc == ER_DYNCOL_OK), "%s", "test_mdev_4995");
634}
635
636void test_update_many(uint *column_numbers, uint *column_values,
637 uint column_count,
638 uint *update_numbers, uint *update_values,
639 my_bool *update_nulls, uint update_count,
640 uint *result_numbers, uint *result_values,
641 uint result_count)
642{
643 int rc= FALSE;
644 uint i;
645 DYNAMIC_COLUMN str1;
646 DYNAMIC_COLUMN str2;
647 DYNAMIC_COLUMN_VALUE *val, *upd, *res;
648
649 val= (DYNAMIC_COLUMN_VALUE *)malloc(sizeof(DYNAMIC_COLUMN_VALUE) *
650 column_count);
651 upd= (DYNAMIC_COLUMN_VALUE *)malloc(sizeof(DYNAMIC_COLUMN_VALUE) *
652 update_count);
653 res= (DYNAMIC_COLUMN_VALUE *)malloc(sizeof(DYNAMIC_COLUMN_VALUE) *
654 result_count);
655
656
657 for (i= 0; i < column_count; i++)
658 {
659 val[i].type= DYN_COL_UINT;
660 val[i].x.ulong_value= column_values[i];
661 }
662 for (i= 0; i < update_count; i++)
663 {
664 if (update_nulls[i])
665 upd[i].type= DYN_COL_NULL;
666 else
667 {
668 upd[i].type= DYN_COL_UINT;
669 upd[i].x.ulong_value= update_values[i];
670 }
671 }
672 for (i= 0; i < result_count; i++)
673 {
674 res[i].type= DYN_COL_UINT;
675 res[i].x.ulong_value= result_values[i];
676 }
677 if (mariadb_dyncol_create_many_num(&str1, column_count, column_numbers, val, 1))
678 goto err;
679 if (mariadb_dyncol_update_many_num(&str1, update_count, update_numbers, upd))
680 goto err;
681 if (mariadb_dyncol_create_many_num(&str2, result_count, result_numbers, res, 1))
682 goto err;
683 if (str1.length == str2.length &&
684 memcmp(str1.str, str2.str, str1.length) ==0)
685 rc= TRUE;
686
687err:
688 ok(rc, "%s", "update_many");
689 /* cleanup */
690 free(val);
691 free(upd);
692 free(res);
693 mariadb_dyncol_free(&str1);
694 mariadb_dyncol_free(&str2);
695}
696
697static void test_mdev_9773()
698{
699 int rc;
700 uint i;
701 uint num_keys[5]= {1,2,3,4,5};
702 char const *strval[]= {"Val1", "Val2", "Val3", "Val4", "Val5"};
703 DYNAMIC_COLUMN_VALUE vals[5];
704 DYNAMIC_COLUMN dynstr;
705 uint unpack_columns= 0;
706 MYSQL_LEX_STRING *unpack_keys= 0;
707 DYNAMIC_COLUMN_VALUE *unpack_vals= 0;
708
709 for (i = 0; i < 5; i++)
710 {
711 vals[i].type= DYN_COL_STRING;
712 vals[i].x.string.value.str= (char *)strval[i];
713 vals[i].x.string.value.length= strlen(strval[i]);
714 vals[i].x.string.charset= &my_charset_latin1;
715 }
716
717 mariadb_dyncol_init(&dynstr);
718
719 /* create numeric */
720 rc= mariadb_dyncol_create_many_num(&dynstr, 5, num_keys, vals, 1);
721
722 if (rc == ER_DYNCOL_OK)
723 rc= mariadb_dyncol_unpack(&dynstr, &unpack_columns, &unpack_keys,
724 &unpack_vals);
725 ok (rc == ER_DYNCOL_OK && unpack_columns == 5, "5 fields unpacked");
726 for (i = 0; i < unpack_columns; i++)
727 {
728 ok(memcmp(unpack_vals[i].x.string.value.str,
729 vals[i].x.string.value.str, vals[i].x.string.value.length) == 0,
730 "unpack %u", i);
731 }
732
733 my_free(unpack_keys);
734 my_free(unpack_vals);
735 mariadb_dyncol_free(&dynstr);
736}
737
738int main(int argc __attribute__((unused)), char **argv)
739{
740 uint i;
741 char *big_string= (char *)malloc(1024*1024);
742
743 MY_INIT(argv[0]);
744 plan(68);
745
746 if (!big_string)
747 exit(1);
748 for (i= 0; i < 1024*1024; i++)
749 big_string[i]= ('0' + (i % 10));
750 test_value_single_null();
751 test_value_single_uint(0, "0");
752 test_value_single_uint(0xffffffffffffffffULL, "0xffffffffffffffff");
753 test_value_single_uint(0xaaaaaaaaaaaaaaaaULL, "0xaaaaaaaaaaaaaaaa");
754 test_value_single_uint(0x5555555555555555ULL, "0x5555555555555555");
755 test_value_single_uint(27652, "27652");
756 test_value_single_sint(0, "0");
757 test_value_single_sint(1, "1");
758 test_value_single_sint(-1, "-1");
759 test_value_single_sint(0x7fffffffffffffffLL, "0x7fffffffffffffff");
760 test_value_single_sint(0xaaaaaaaaaaaaaaaaLL, "0xaaaaaaaaaaaaaaaa");
761 test_value_single_sint(0x5555555555555555LL, "0x5555555555555555");
762 test_value_single_sint(0x8000000000000000LL, "0x8000000000000000");
763 test_value_single_double(0.0, "0.0");
764 test_value_single_double(1.0, "1.0");
765 test_value_single_double(-1.0, "-1.0");
766 test_value_single_double(1.0e100, "1.0e100");
767 test_value_single_double(1.0e-100, "1.0e-100");
768 test_value_single_double(9999999999999999999999999999999999999.0,
769 "9999999999999999999999999999999999999.0");
770 test_value_single_double(-9999999999999999999999999999999999999.0,
771 "-9999999999999999999999999999999999999.0");
772 test_value_single_decimal("0");
773 test_value_single_decimal("1");
774 test_value_single_decimal("-1");
775 test_value_single_decimal("9999999999999999999999999999999");
776 test_value_single_decimal("-9999999999999999999999999999999");
777 test_value_single_decimal("0.9999999999999999999999999999999");
778 test_value_single_decimal("-0.9999999999999999999999999999999");
779 test_value_single_string("", 0, charset_list[0]);
780 test_value_single_string("", 1, charset_list[0]);
781 test_value_single_string("1234567890", 11, charset_list[0]);
782 test_value_single_string("nulls\0\0\0\0\0", 10, charset_list[0]);
783 sprintf(big_string, "%x", 0x7a);
784 test_value_single_string(big_string, 0x7a, charset_list[0]);
785 sprintf(big_string, "%x", 0x80);
786 test_value_single_string(big_string, 0x80, charset_list[0]);
787 sprintf(big_string, "%x", 0x7ffa);
788 test_value_single_string(big_string, 0x7ffa, charset_list[0]);
789 sprintf(big_string, "%x", 0x8000);
790 test_value_single_string(big_string, 0x8000, charset_list[0]);
791 sprintf(big_string, "%x", 1024*1024);
792 test_value_single_string(big_string, 1024*1024, charset_list[0]);
793 test_value_single_date(0, 0, 0, "zero date");
794 test_value_single_date(9999, 12, 31, "max date");
795 test_value_single_date(2011, 3, 26, "some date");
796 test_value_single_time(0, 0, 0, 0, 0, "zero time");
797 test_value_single_time(1, 23, 59, 59, 999999, "min time");
798 test_value_single_time(0, 23, 59, 59, 999999, "max time");
799 test_value_single_time(0, 21, 36, 20, 28, "some time");
800 test_value_single_datetime(0, 0, 0, 0, 0, 0, 0, 0, "zero datetime");
801 test_value_single_datetime(1, 9999, 12, 31, 23, 59, 59, 999999,
802 "min datetime");
803 test_value_single_datetime(0, 9999, 12, 31, 23, 59, 59, 999999,
804 "max datetime");
805 test_value_single_datetime(0, 2011, 3, 26, 21, 53, 12, 3445,
806 "some datetime");
807 {
808 uint column_numbers[]= {100,1,2,3,4,5,6,7,8};
809 test_value_multi(0, 0, 0.0, "0",
810 "", 0, charset_list[0],
811 0, 0, 0,
812 0, 0, 0, 0, 0,
813 0, 0, 0, 0, 0, 0, 0, 0,
814 column_numbers,
815 "zero data");
816 }
817 {
818 uint column_numbers[]= {10,1,12,37,4,57,6,76,87};
819 test_value_multi(0xffffffffffffffffULL, 0x7fffffffffffffffLL,
820 99999999.999e120, "9999999999999999999999999999999",
821 big_string, 1024*1024, charset_list[0],
822 9999, 12, 31,
823 0, 23, 59, 59, 999999,
824 0, 9999, 12, 31, 23, 59, 59, 999999,
825 column_numbers,
826 "much data");
827 }
828 free(big_string);
829 {
830 uint column_numbers[]= {101,12,122,37,24,572,16,726,77};
831 test_value_multi(37878, -3344,
832 2873.3874, "92743.238984789898",
833 "string", 6, charset_list[0],
834 2011, 3, 26,
835 1, 23, 23, 20, 333,
836 0, 2011, 3, 26, 23, 23, 53, 334,
837 column_numbers,
838 "zero data");
839 }
840 test_value_multi_same_num();
841 {
842 uint column_numbers[]= {1,2,3,4,5,6,7,2, 3, 4};
843 uint column_values[]= {1,2,3,4,5,6,7,0,30,40};
844 my_bool null_values[]= {0,0,0,0,0,0,0,1, 0, 0};
845
846 test_update_multi(column_numbers, column_values, null_values, 7, 10);
847 }
848 {
849 uint column_numbers[]= {4,3,2,1, 1,2,3,4};
850 uint column_values[]= {4,3,2,1, 0,0,0,0};
851 my_bool null_values[]= {0,0,0,0, 1,1,1,1};
852
853 test_update_multi(column_numbers, column_values, null_values, 4, 8);
854 }
855 {
856 uint column_numbers[]= {4,3,2,1, 4,3,2,1};
857 uint column_values[]= {4,3,2,1, 0,0,0,0};
858 my_bool null_values[]= {0,0,0,0, 1,1,1,1};
859
860 test_update_multi(column_numbers, column_values, null_values, 4, 8);
861 }
862 test_empty_string();
863 {
864 uint column_numbers[]= {1, 2, 3};
865 uint column_values[]= {1, 2, 3};
866 uint update_numbers[]= {4, 3, 2, 1};
867 uint update_values[]= {40,30, 0,10};
868 my_bool update_nulls[]={0, 0, 1, 0};
869 uint result_numbers[]= {1, 3, 4};
870 uint result_values[]= {10,30,40};
871 test_update_many(column_numbers, column_values, 3,
872 update_numbers, update_values, update_nulls, 4,
873 result_numbers, result_values, 3);
874 }
875 test_mdev_4994();
876 test_mdev_4995();
877 test_mdev_9773();
878
879 my_end(0);
880 return exit_status();
881}
882