17 #include "my_config.h"
18 #include <gtest/gtest.h>
20 #include "test_utils.h"
21 #include "fake_table.h"
27 namespace field_unittests {
35 virtual void SetUp() { initializer.SetUp(); }
36 virtual void TearDown() { initializer.TearDown(); }
38 THD *thd() {
return initializer.thd(); }
48 EXPECT_EQ(first.year, second.year);
49 EXPECT_EQ(first.month, second.month);
50 EXPECT_EQ(first.day, second.day);
51 EXPECT_EQ(first.hour, second.hour);
52 EXPECT_EQ(first.minute, second.minute);
53 EXPECT_EQ(first.second, second.second);
55 EXPECT_EQ(first.neg, second.neg);
56 EXPECT_EQ(first.time_type, second.time_type);
80 virtual bool store_time(
MYSQL_TIME *time, uint precision)
87 void verify_time(
MYSQL_TIME *time, uint precision)
89 compareMysqlTime(*time, t);
90 EXPECT_EQ(precision, p);
94 virtual void prepare_for_resend() {}
96 virtual bool store_null() {
return false; }
97 virtual bool store_tiny(longlong from) {
return false; }
98 virtual bool store_short(longlong from) {
return false; }
99 virtual bool store_long(longlong from) {
return false; }
100 virtual bool store_longlong(longlong from,
bool unsigned_flag) {
return false; }
101 virtual bool store_decimal(
const my_decimal *) {
return false; }
102 virtual bool store(
const char *from,
size_t length,
104 virtual bool store(
const char *from,
size_t length,
107 virtual bool store(
float from, uint32 decimals,
String *buffer) {
return false; }
108 virtual bool store(
double from, uint32 decimals,
String *buffer) {
return false; }
109 virtual bool store(
MYSQL_TIME *time, uint precision) {
return false; }
110 virtual bool store_date(
MYSQL_TIME *time) {
return false; }
111 virtual bool store(
Field *field) {
return false; }
113 virtual bool send_out_parameters(
List<Item_param> *sp_params) {
return false; }
114 virtual enum enum_protocol_type type() {
return PROTOCOL_LOCAL; };
121 uchar nullPtr[1]= {0};
122 MYSQL_TIME time= {0, 0, 0, 12, 23, 12, 123400,
false, MYSQL_TIMESTAMP_TIME};
127 EXPECT_EQ(4UL, field->decimals());
128 EXPECT_EQ(MYSQL_TYPE_TIME, field->type());
129 EXPECT_EQ(MYSQL_TYPE_TIME2, field->binlog_type());
131 longlong packed= TIME_to_longlong_packed(&time);
134 EXPECT_DOUBLE_EQ(122312.1234, field->val_real());
135 EXPECT_EQ(122312, field->val_int());
141 my_decimal2double(0, dec, &res);
142 EXPECT_DOUBLE_EQ(122312.1234, res);
144 EXPECT_EQ(5UL, field->pack_length());
145 EXPECT_EQ(5UL, field->pack_length_from_metadata(4));
146 EXPECT_EQ(5UL, field->row_pack_length());
149 field->sql_type(str);
150 EXPECT_STREQ(
"time(4)", str.c_ptr_safe());
152 EXPECT_EQ(1, field->zero_pack());
153 EXPECT_EQ(&my_charset_bin, field->sort_charset());
157 EXPECT_EQ(field->decimals(), copy->decimals());
158 EXPECT_EQ(field->type(), copy->type());
159 EXPECT_DOUBLE_EQ(field->val_real(), copy->val_real());
160 EXPECT_EQ(field->val_int(), copy->val_int());
162 EXPECT_EQ(0, field->cmp(field->ptr, copy->ptr));
165 EXPECT_EQ(0, field->reset());
166 EXPECT_DOUBLE_EQ(0.0, field->val_real());
167 EXPECT_EQ(0, field->val_int());
172 EXPECT_EQ(4UL, field->decimals());
173 EXPECT_EQ(MYSQL_TYPE_TIME, field->type());
174 EXPECT_DOUBLE_EQ(122312.1234, field->val_real());
175 EXPECT_EQ(122312, field->val_int());
179 EXPECT_STREQ(
"12:23:12.1234", field->val_str(&timeStr, &timeStr)->c_ptr());
182 EXPECT_DOUBLE_EQ(122312.1234, field->val_real());
185 MYSQL_TIME bigTime= {0, 0, 0, 123, 45, 45, 555500,
false, MYSQL_TIMESTAMP_TIME};
187 EXPECT_FALSE(field->
get_date(&dateTime, 0));
191 EXPECT_STREQ(
"03:45:45.555500", timeStr.c_ptr() + 11);
194 EXPECT_FALSE(field->get_time(&t));
195 compareMysqlTime(bigTime, t);
197 Mock_protocol protocol(thd());
198 EXPECT_FALSE(field->send_binary(&protocol));
203 EXPECT_TRUE(field->is_temporal());
204 EXPECT_EQ(STRING_RESULT, field->result_type());
205 EXPECT_EQ(15UL, field->max_display_length());
206 EXPECT_TRUE(field->str_needs_quotes());
213 EXPECT_EQ(INT_RESULT, field->cmp_type());
214 EXPECT_EQ(INT_RESULT, field->cmp_type());
215 EXPECT_EQ(DERIVATION_NUMERIC, field->derivation());
216 EXPECT_EQ(&my_charset_numeric, field->charset());
217 EXPECT_TRUE(field->can_be_compared_as_longlong());
218 EXPECT_TRUE(field->binary());
224 EXPECT_EQ(TYPE_OK, field->
store(
"12:23:12.123456", 15, &my_charset_numeric));
225 EXPECT_DOUBLE_EQ(122312.1235, field->val_real());
227 EXPECT_EQ(TYPE_OK, field->store_decimal(dec));
228 EXPECT_DOUBLE_EQ(122312.1234, field->val_real());
230 EXPECT_EQ(TYPE_OK, field->
store(-234545,
false));
231 EXPECT_DOUBLE_EQ(-234545.0, field->val_real());
235 Mock_error_handler error_handler(thd(), ER_TRUNCATED_WRONG_VALUE);
236 EXPECT_EQ(TYPE_WARN_OUT_OF_RANGE, field->
store(0x80000000,
true));
238 EXPECT_EQ(1, error_handler.handle_called());
240 EXPECT_DOUBLE_EQ(8385959, field->val_real());
243 EXPECT_EQ(TYPE_OK, field->
store(1234545.555555));
244 EXPECT_DOUBLE_EQ(1234545.5556, field->val_real());
248 EXPECT_EQ(TYPE_OK, f->store_time(&time, MYSQL_TIMESTAMP_TIME));
249 EXPECT_DOUBLE_EQ(122312.1234, f->val_real());
250 EXPECT_STREQ(
"12:23:12.1234", f->val_str(&timeStr)->c_ptr());
251 EXPECT_STREQ(
"122312", f->val_int_as_str(&timeStr,
false)->c_ptr());
252 EXPECT_TRUE(f->eq(copy));
253 EXPECT_TRUE(f->eq_def(copy));
258 Mock_table m_table(thd());
262 EXPECT_FALSE(f->get_timestamp(&tv, &warnings));
263 EXPECT_EQ(123400, tv.tv_usec);
269 TEST_F(FieldTest, FieldTimefCompare)
271 const int nFields= 7;
272 uchar fieldBufs[nFields][6];
273 uchar nullPtrs[nFields];
276 {0, 0, 0, 12, 23, 12, 100000,
true, MYSQL_TIMESTAMP_TIME},
277 {0, 0, 0, 0, 0, 0, 10000,
true, MYSQL_TIMESTAMP_TIME},
278 {0, 0, 0, 0, 0, 0, 0,
false, MYSQL_TIMESTAMP_TIME},
279 {0, 0, 0, 0, 0, 0, 999900,
false, MYSQL_TIMESTAMP_TIME},
280 {0, 0, 0, 0, 0, 0, 999990,
false, MYSQL_TIMESTAMP_TIME},
281 {0, 0, 0, 11, 59, 59, 999999,
false, MYSQL_TIMESTAMP_TIME},
282 {0, 0, 0, 12, 00, 00, 100000,
false, MYSQL_TIMESTAMP_TIME}};
284 Field* fields[nFields];
285 uchar sortStrings[nFields][6];
286 for (
int i=0;
i < nFields; ++
i)
289 sprintf(fieldName,
"f%c",
i);
290 fields[
i]=
new Field_timef(fieldBufs[
i], nullPtrs+i,
false, Field::NONE,
293 longlong packed= TIME_to_longlong_packed(×[
i]);
294 EXPECT_EQ(0, fields[
i]->store_packed(packed));
298 for (
int i=0; i < nFields; ++
i)
299 for (
int j=0; j < nFields; ++j)
304 EXPECT_GT(0, memcmp(sortStrings[i], sortStrings[j],
305 fields[i]->pack_length()))
306 << fields[
i]->val_str(&tmp)->c_ptr() <<
" < "
307 << fields[j]->val_str(&tmp)->c_ptr();
308 EXPECT_GT(0, fields[i]->cmp(fields[i]->ptr, fields[j]->ptr))
309 << fields[
i]->val_str(&tmp)->c_ptr() <<
" < "
310 << fields[j]->val_str(&tmp)->c_ptr();
314 EXPECT_LT(0, memcmp(sortStrings[i], sortStrings[j],
315 fields[i]->pack_length()))
316 << fields[
i]->val_str(&tmp)->c_ptr() <<
" > "
317 << fields[j]->val_str(&tmp)->c_ptr();
318 EXPECT_LT(0, fields[i]->cmp(fields[i]->ptr, fields[j]->ptr))
319 << fields[
i]->val_str(&tmp)->c_ptr() <<
" > "
320 << fields[j]->val_str(&tmp)->c_ptr();
324 EXPECT_EQ(0, memcmp(sortStrings[i], sortStrings[j],
325 fields[i]->pack_length()))
326 << fields[
i]->val_str(&tmp)->c_ptr() <<
" = "
327 << fields[j]->val_str(&tmp)->c_ptr();
328 EXPECT_EQ(0, fields[i]->cmp(fields[i]->ptr, fields[j]->ptr))
329 << fields[
i]->val_str(&tmp)->c_ptr() <<
" = "
330 << fields[j]->val_str(&tmp)->c_ptr();
336 TEST_F(FieldTest, FieldTime)
339 uchar nullPtr[1]= {0};
340 MYSQL_TIME bigTime= {0, 0, 0, 123, 45, 45, 555500,
false, MYSQL_TIMESTAMP_TIME};
346 EXPECT_FALSE(field->get_time(&t));
347 compareMysqlTime(bigTime, t);
351 const char *type_names3[]= {
"one",
"two",
"three", NULL };
352 unsigned int type_lengths3[]= { 3
U, 3
U, 5U, 0U };
353 TYPELIB tl3= { 3,
"tl3", type_names3, type_lengths3 };
355 const char *type_names4[]= {
"one",
"two",
"three",
"four", NULL };
356 unsigned int type_lengths4[]= { 3
U, 3
U, 5U, 4U, 0U };
357 TYPELIB tl4= { 4,
"tl4", type_names4, type_lengths4 };
378 TEST_F(FieldTest, CopyFieldSet)
381 char fields[]=
"one,two";
382 my_ulonglong typeset= find_typeset(fields, &tl3, &err);
387 bitmap_set_all(f_to->table->write_set);
388 uchar to_fieldval= 0;
389 f_to->ptr= &to_fieldval;
391 Field_set *f_from= create_field_set(&tl4);
392 bitmap_set_all(f_from->table->write_set);
393 uchar from_fieldval=
static_cast<uchar
>(typeset);
394 f_from->ptr= &from_fieldval;
397 cf->set(f_to, f_from,
false);
401 EXPECT_FALSE(cf->tmp.is_alloced());
404 delete f_from->table;
424 void test_make_sort_key(
Field *field, uchar *from,
const uchar *expected,
427 const uint pack_length= field->pack_length();
429 table.s->db_low_byte_first=
false;
432 for (uint key_length= min_key_length; key_length <= pack_length; ++key_length)
434 uchar buff[MAX_FIELD_WIDTH + 1];
435 memset(buff,
'a', pack_length + 1);
439 for (uint i= 0; i < key_length; ++
i)
440 ASSERT_FALSE(buff[i] ==
'a')
441 <<
"Too few bytes written at " << i
442 <<
" with buffer size " << key_length <<
".";
445 for (uint i= 0; i < key_length; ++
i)
446 ASSERT_EQ(expected[i], buff[i])
447 <<
"Wrong output at " << i
448 <<
" with buffer size " << key_length
449 <<
" and pack length " << pack_length <<
".";
451 EXPECT_EQ(
'a', buff[key_length])
452 <<
"Buffer overrun" <<
" with buffer size " << key_length <<
".";
456 uchar buff[MAX_FIELD_WIDTH];
457 memset(buff,
'a', pack_length + 1);
459 EXPECT_EQ(
'a', buff[pack_length]) <<
"Buffer overrun";
464 void test_make_sort_key(
Field *field)
466 const int pack_length= field->pack_length();
468 uchar from[MAX_FIELD_WIDTH];
469 memset(from,
'b', pack_length);
471 uchar
to[MAX_FIELD_WIDTH + 1];
472 memset(to,
'b', pack_length + 1);
474 test_make_sort_key(field, from, to, 1);
480 static size_t mock_strnxfrm(
const CHARSET_INFO *, uchar *,
size_t,
481 uint,
const uchar *,
size_t, uint);
495 mutable bool strnxfrm_called;
496 Mock_charset() { strnxfrm_called=
false; coll= &mock_collation; mbmaxlen= 1; }
501 size_t mock_strnxfrm(
const CHARSET_INFO *charset, uchar *,
size_t dstlen, uint,
502 const uchar *,
size_t, uint)
505 static_cast<const Mock_charset*
>(charset)->strnxfrm_called=
true;
510 void test_integer_field(
Field *field)
512 uchar from[MAX_FIELD_WIDTH], expected[MAX_FIELD_WIDTH];
513 const int pack_length= field->pack_length();
514 for (
int i= 0; i < pack_length; ++
i)
517 #ifdef WORDS_BIGENDIAN
518 expected[
i]=
'0' +
i;
520 expected[pack_length - 1 -
i]=
'0' +
i;
523 test_make_sort_key(field, from, expected, pack_length);
531 TEST_F(FieldTest, MakeSortKey)
534 SCOPED_TRACE(
"Field_decimal");
535 Field_decimal fd(NULL, 64, NULL,
'\0', Field::NONE,
"", 0,
false,
false);
536 test_make_sort_key(&fd);
539 SCOPED_TRACE(
"Field_new_decimal");
541 test_make_sort_key(&fnd);
544 SCOPED_TRACE(
"Field_tiny");
545 Field_tiny ft(NULL, 0, NULL,
'\0', Field::NONE,
"",
false,
true);
546 test_make_sort_key(&ft);
549 SCOPED_TRACE(
"Field_short");
551 test_integer_field(&fs);
554 SCOPED_TRACE(
"Field_long");
556 test_integer_field(&fl);
559 SCOPED_TRACE(
"Field_longlong");
560 Field_longlong fll(NULL, 64, NULL,
'\0', Field::NONE,
"", 0,
true);
561 test_integer_field(&fll);
564 SCOPED_TRACE(
"Field_float");
565 Field_float ff(NULL, 0, NULL,
'\0', Field::NONE,
"", 0,
false,
false);
567 uchar
to []= { 128, 0, 0, 0 };
568 test_make_sort_key(&ff, reinterpret_cast<uchar*>(&from), to, 4);
571 SCOPED_TRACE(
"Field_double");
572 Field_double fd(NULL, 0, NULL,
'\0', Field::NONE,
"", 0,
false,
false);
574 uchar expected []= { 128, 0, 0, 0, 0, 0, 0, 0 };
575 test_make_sort_key(&fd, reinterpret_cast<uchar*>(&from), expected, 1);
578 SCOPED_TRACE(
"Field_null");
580 cs.state= MY_CHARSET_UNDEFINED;
582 test_make_sort_key(&fn);
585 SCOPED_TRACE(
"Field_timestamp");
587 test_integer_field(&fts);
590 SCOPED_TRACE(
"Field_timestampf");
592 ftsf(NULL, NULL, 0, Field::NONE,
"", DATETIME_MAX_DECIMALS);
593 test_make_sort_key(&ftsf);
596 SCOPED_TRACE(
"field_newdate");
598 uchar from []= {
'3',
'2',
'1' };
599 uchar expected []= {
'1',
'2',
'3' };
600 test_make_sort_key(&fnd, from, expected, 3);
603 SCOPED_TRACE(
"Field_time");
605 uchar from []= { 3, 2, 1 };
606 uchar expected []= { 129, 2, 3 };
607 test_make_sort_key(&ft, from, expected, 3);
610 SCOPED_TRACE(
"Field_timef");
612 test_make_sort_key(&ftf);
615 SCOPED_TRACE(
"Field_datetime");
617 test_integer_field(&fdt);
620 SCOPED_TRACE(
"Field_string");
621 Mock_charset mock_charset;
622 Field_string fs(NULL, 0, NULL,
'\0', Field::NONE,
"", &mock_charset);
624 fs.make_sort_key(&to, 666);
627 SCOPED_TRACE(
"Field_varstring");
628 Mock_charset mock_charset;
630 uchar ptr[8]= {0, 0, 0, 0, 0, 0, 0, 0};
631 Field_varstring fvs(ptr, 0, 0, NULL,
'\0', Field::NONE,
"", &fake_share,
634 fvs.make_sort_key(&to, 666);
637 SCOPED_TRACE(
"Field_blob");
639 cs.state= MY_CHARSET_UNDEFINED;
643 SCOPED_TRACE(
"Field_enum");
644 for (
int pack_length= 1; pack_length <= 8; ++pack_length)
645 for (
int key_length= 1; key_length <= 8; ++key_length)
647 Field_enum fe(NULL, 0, NULL,
'\0', Field::NONE,
"", pack_length, NULL,
649 uchar from []= {
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8' };
651 #ifdef WORDS_BIGENDIAN
652 {
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8' };
653 test_make_sort_key(&fe, from, expected, key_length);
655 {
'8',
'7',
'6',
'5',
'4',
'3',
'2',
'1' };
656 test_make_sort_key(&fe, from, expected + 8 - pack_length, key_length);
661 SCOPED_TRACE(
"Field_bit");
662 Field_bit fb(NULL, 0, NULL,
'\0', NULL,
'\0', Field::NONE,
"");
667 void testCopyInteger(
bool is_big_endian,
bool is_unsigned)
669 const uchar from_template[]= {
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8' },
670 expected_for_big_endian[]= {
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8' },
671 expected_for_little_endian[]= {
'8',
'7',
'6',
'5',
'4',
'3',
'2',
'1' };
673 const size_t max_length=
sizeof(from_template);
674 for (uint from_length= 1; from_length < max_length; ++from_length)
675 for (uint to_length= 1; to_length <= from_length; ++to_length)
677 uchar to[]= {
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0' };
678 uchar from[max_length];
679 memcpy(from, from_template, max_length);
682 copy_integer<true>(
to, to_length, from, from_length, is_unsigned);
684 copy_integer<false>(
to, to_length, from, from_length, is_unsigned);
686 EXPECT_EQ(
'0', to[to_length])
687 <<
"Buffer overrun @ position " << to_length <<
".";
689 ASSERT_EQ(is_unsigned ? 0 : 128, to[0] & 128)
690 <<
"Sign bit should" << (is_unsigned ?
" not" :
"") <<
" be flipped";
692 const uchar *expected=
693 is_big_endian ? expected_for_big_endian :
694 expected_for_little_endian + max_length - from_length;
696 for (uint i= 1; i < to_length; ++
i)
698 ASSERT_FALSE(to[i] ==
'\0')
699 <<
"Too few bytes written @ position " << i
700 <<
" when copying a size " << from_length <<
" integer into a size "
701 << to_length <<
" integer.";
703 ASSERT_EQ(expected[i], to[i])
704 <<
"Result differs at position " << i
705 <<
" when copying a size " << from_length <<
" integer into a size "
706 << to_length <<
" integer.";
713 TEST_F(FieldTest, copyInteger)
716 SCOPED_TRACE(
"Big endian unsigned");
717 testCopyInteger(
true,
true);
720 SCOPED_TRACE(
"Big endian signed");
721 testCopyInteger(
true,
false);
724 SCOPED_TRACE(
"Little endian unsigned");
725 testCopyInteger(
false,
true);
728 SCOPED_TRACE(
"Little endian signed");
729 testCopyInteger(
false,
false);
736 #include "field_date-t.cc"
737 #include "field_datetime-t.cc"
738 #include "field_long-t.cc"
739 #include "field_newdecimal-t.cc"
740 #include "field_timestamp-t.cc"