MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
item-t.cc
1 /* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
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 as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
15 
16 // First include (the generated) my_config.h, to get correct platform defines.
17 #include "my_config.h"
18 #include <gtest/gtest.h>
19 #include <gmock/gmock.h>
20 
21 #include "test_utils.h"
22 
23 #include "item.h"
24 #include "sql_class.h"
25 #include "tztime.h"
26 
27 #include "mock_field_timestamp.h"
28 
29 namespace item_unittest {
30 
33 using ::testing::Return;
34 
35 class ItemTest : public ::testing::Test
36 {
37 protected:
38  virtual void SetUp() { initializer.SetUp(); }
39  virtual void TearDown() { initializer.TearDown(); }
40 
41  THD *thd() { return initializer.thd(); }
42 
43  Server_initializer initializer;
44 };
45 
46 
52 {
53 public:
54  Mock_field_long(uint32 lenght)
55  : Field_long(0, // ptr_arg
56  lenght, // len_arg
57  NULL, // null_ptr_arg
58  0, // null_bit_arg
59  Field::NONE, // unireg_check_arg
60  0, // field_name_arg
61  false, // zero_arg
62  false) // unsigned_arg
63  {}
64 
65  // Avoid warning about hiding other overloaded versions of store().
66  using Field_long::store;
67 
68  /*
69  This is the only member function we need to override.
70  Note: Sun Studio needs a little help in resolving longlong.
71  */
72  MOCK_METHOD2(store, type_conversion_status(::longlong nr, bool unsigned_val));
73 };
74 
75 
76 TEST_F(ItemTest, ItemInt)
77 {
78  const int32 val= 42;
79  char stringbuf[10];
80  (void) my_snprintf(stringbuf, sizeof(stringbuf), "%d", val);
81 
82  // An Item expects to be owned by current_thd->free_list,
83  // so allocate with new, and do not delete it.
84  Item_int *item_int= new Item_int(val);
85 
86  EXPECT_EQ(Item::INT_ITEM, item_int->type());
87  EXPECT_EQ(INT_RESULT, item_int->result_type());
88  EXPECT_EQ(MYSQL_TYPE_LONGLONG, item_int->field_type());
89  EXPECT_EQ(val, item_int->val_int());
90  EXPECT_DOUBLE_EQ((double) val, item_int->val_real());
91  EXPECT_TRUE(item_int->basic_const_item());
92 
93  my_decimal decimal_val;
94  EXPECT_EQ(&decimal_val, item_int->val_decimal(&decimal_val));
95 
96  String string_val;
97  EXPECT_EQ(&string_val, item_int->val_str(&string_val));
98  EXPECT_STREQ(stringbuf, string_val.c_ptr_safe());
99 
100  Mock_field_long field_val(item_int->max_length);
101  // We expect to be called with arguments(nr == val, unsigned_val == false)
102  EXPECT_CALL(field_val, store(val, false))
103  .Times(1)
104  .WillRepeatedly(Return(TYPE_OK));
105  EXPECT_EQ(TYPE_OK, item_int->save_in_field(&field_val, true));
106 
107  Item *clone= item_int->clone_item();
108  EXPECT_TRUE(item_int->eq(clone, true));
109  EXPECT_TRUE(item_int->eq(item_int, true));
110 
111  String print_val;
112  item_int->print(&print_val, QT_ORDINARY);
113  EXPECT_STREQ(stringbuf, print_val.c_ptr_safe());
114 
115  const uint precision= item_int->decimal_precision();
116  EXPECT_EQ(MY_INT32_NUM_DECIMAL_DIGITS, precision);
117 
118  item_int->neg();
119  EXPECT_EQ(-val, item_int->val_int());
120  EXPECT_EQ(precision - 1, item_int->decimal_precision());
121 
122  // Functions inherited from parent class(es).
123  const table_map tmap= 0;
124  EXPECT_EQ(tmap, item_int->used_tables());
125 
126  /*
127  TODO: There are about 100 member functions in Item.
128  Figure out which ones are relevant for unit testing here.
129  */
130 }
131 
132 
133 TEST_F(ItemTest, ItemEqual)
134 {
135  // Bug#13720201 VALGRIND: VARIOUS BLOCKS OF BYTES DEFINITELY LOST
137  // foo is longer than STRING_BUFFER_USUAL_SIZE used by cmp_item_sort_string.
138  const char foo[]=
139  "0123456789012345678901234567890123456789"
140  "0123456789012345678901234567890123456789"
141  "0123456789012345678901234567890123456789";
142  Item_equal *item_equal=
143  new Item_equal(new Item_string(STRING_WITH_LEN(foo), &my_charset_bin),
144  new Item_field(&mft));
145  EXPECT_FALSE(item_equal->fix_fields(thd(), NULL));
146  EXPECT_EQ(0, item_equal->val_int());
147 }
148 
149 
150 TEST_F(ItemTest, ItemFuncDesDecrypt)
151 {
152  // Bug #59632 Assertion failed: arg_length > length
153  const uint length= 1U;
154  Item_int *item_one= new Item_int(1, length);
155  Item_int *item_two= new Item_int(2, length);
156  Item_func_des_decrypt *item_decrypt=
157  new Item_func_des_decrypt(item_two, item_one);
158 
159  EXPECT_FALSE(item_decrypt->fix_fields(thd(), NULL));
160  EXPECT_EQ(length, item_one->max_length);
161  EXPECT_EQ(length, item_two->max_length);
162  EXPECT_LE(item_decrypt->max_length, length);
163 }
164 
165 
166 TEST_F(ItemTest, ItemFuncExportSet)
167 {
168  String str;
169  Item *on_string= new Item_string(STRING_WITH_LEN("on"), &my_charset_bin);
170  Item *off_string= new Item_string(STRING_WITH_LEN("off"), &my_charset_bin);
171  Item *sep_string= new Item_string(STRING_WITH_LEN(","), &my_charset_bin);
172  {
173  // Testing basic functionality.
174  Item_func_export_set *export_set=
175  new Item_func_export_set(new Item_int(2),
176  on_string,
177  off_string,
178  sep_string,
179  new Item_int(4));
180  EXPECT_FALSE(export_set->fix_fields(thd(), NULL));
181  EXPECT_EQ(&str, export_set->val_str(&str));
182  EXPECT_STREQ("off,on,off,off", str.c_ptr_safe());
183  }
184  {
185  // Testing corner case: number_of_bits == zero.
186  Item_func_export_set *export_set=
187  new Item_func_export_set(new Item_int(2),
188  on_string,
189  off_string,
190  sep_string,
191  new Item_int(0));
192  EXPECT_FALSE(export_set->fix_fields(thd(), NULL));
193  EXPECT_EQ(&str, export_set->val_str(&str));
194  EXPECT_STREQ("", str.c_ptr_safe());
195  }
196 
197  /*
198  Bug#11765562 58545:
199  EXPORT_SET() CAN BE USED TO MAKE ENTIRE SERVER COMPLETELY UNRESPONSIVE
200  */
201  const ulong max_size= 1024;
202  const ulonglong repeat= max_size / 2;
203  Item *item_int_repeat= new Item_int(repeat);
204  Item *string_x= new Item_string(STRING_WITH_LEN("x"), &my_charset_bin);
205  String * const null_string= NULL;
206  thd()->variables.max_allowed_packet= max_size;
207  {
208  // Testing overflow caused by 'on-string'.
209  Mock_error_handler error_handler(thd(), ER_WARN_ALLOWED_PACKET_OVERFLOWED);
210  Item_func_export_set *export_set=
211  new Item_func_export_set(new Item_int(0xff),
212  new Item_func_repeat(string_x, item_int_repeat),
213  string_x,
214  sep_string);
215  EXPECT_FALSE(export_set->fix_fields(thd(), NULL));
216  EXPECT_EQ(null_string, export_set->val_str(&str));
217  EXPECT_STREQ("", str.c_ptr_safe());
218  EXPECT_EQ(1, error_handler.handle_called());
219  }
220  {
221  // Testing overflow caused by 'off-string'.
222  Mock_error_handler error_handler(thd(), ER_WARN_ALLOWED_PACKET_OVERFLOWED);
223  Item_func_export_set *export_set=
224  new Item_func_export_set(new Item_int(0xff),
225  string_x,
226  new Item_func_repeat(string_x, item_int_repeat),
227  sep_string);
228  EXPECT_FALSE(export_set->fix_fields(thd(), NULL));
229  EXPECT_EQ(null_string, export_set->val_str(&str));
230  EXPECT_STREQ("", str.c_ptr_safe());
231  EXPECT_EQ(1, error_handler.handle_called());
232  }
233  {
234  // Testing overflow caused by 'separator-string'.
235  Mock_error_handler error_handler(thd(), ER_WARN_ALLOWED_PACKET_OVERFLOWED);
236  Item_func_export_set *export_set=
237  new Item_func_export_set(new Item_int(0xff),
238  string_x,
239  string_x,
240  new Item_func_repeat(string_x, item_int_repeat));
241  EXPECT_FALSE(export_set->fix_fields(thd(), NULL));
242  EXPECT_EQ(null_string, export_set->val_str(&str));
243  EXPECT_STREQ("", str.c_ptr_safe());
244  EXPECT_EQ(1, error_handler.handle_called());
245  }
246 }
247 
248 
249 TEST_F(ItemTest, ItemFuncIntDivOverflow)
250 {
251  const char dividend_str[]=
252  "99999999999999999999999999999999999999999"
253  "99999999999999999999999999999999999999999";
254  const char divisor_str[]= "0.5";
255  Item_float *dividend= new Item_float(dividend_str, sizeof(dividend_str));
256  Item_float *divisor= new Item_float(divisor_str, sizeof(divisor_str));
257  Item_func_int_div* quotient= new Item_func_int_div(dividend, divisor);
258 
259  Mock_error_handler error_handler(thd(), ER_TRUNCATED_WRONG_VALUE);
260  EXPECT_FALSE(quotient->fix_fields(thd(), NULL));
261  initializer.set_expected_error(ER_DATA_OUT_OF_RANGE);
262  quotient->val_int();
263 }
264 
265 
266 TEST_F(ItemTest, ItemFuncIntDivUnderflow)
267 {
268  // Bug #11792200 - DIVIDING LARGE NUMBERS CAUSES STACK CORRUPTIONS
269  const char dividend_str[]= "1.175494351E-37";
270  const char divisor_str[]= "1.7976931348623157E+308";
271  Item_float *dividend= new Item_float(dividend_str, sizeof(dividend_str));
272  Item_float *divisor= new Item_float(divisor_str, sizeof(divisor_str));
273  Item_func_int_div* quotient= new Item_func_int_div(dividend, divisor);
274 
275  Mock_error_handler error_handler(thd(), ER_TRUNCATED_WRONG_VALUE);
276  EXPECT_FALSE(quotient->fix_fields(thd(), NULL));
277  EXPECT_EQ(0, quotient->val_int());
278 }
279 
280 
281 TEST_F(ItemTest, ItemFuncNegLongLongMin)
282 {
283  // Bug#14314156 MAIN.FUNC_MATH TEST FAILS ON MYSQL-TRUNK ON PB2
284  const longlong longlong_min= LONGLONG_MIN;
285  Item_func_neg *item_neg= new Item_func_neg(new Item_int(longlong_min));
286 
287  EXPECT_FALSE(item_neg->fix_fields(thd(), NULL));
288  initializer.set_expected_error(ER_DATA_OUT_OF_RANGE);
289  EXPECT_EQ(0, item_neg->int_op());
290 }
291 
292 
293 /*
294  This is not an exhaustive test. It simply demonstrates that more of the
295  initializations in mysqld.cc are needed for testing Item_xxx classes.
296 */
297 TEST_F(ItemTest, ItemFuncSetUserVar)
298 {
299  const longlong val1= 1;
300  Item_decimal *item_dec= new Item_decimal(val1, false);
301  Item_string *item_str= new Item_string("1", 1, &my_charset_latin1);
302 
303  LEX_STRING var_name= { C_STRING_WITH_LEN("a") };
304  Item_func_set_user_var *user_var=
305  new Item_func_set_user_var(var_name, item_str, false);
306  EXPECT_FALSE(user_var->set_entry(thd(), true));
307  EXPECT_FALSE(user_var->fix_fields(thd(), NULL));
308  EXPECT_EQ(val1, user_var->val_int());
309 
310  my_decimal decimal;
311  my_decimal *decval_1= user_var->val_decimal(&decimal);
312  user_var->save_item_result(item_str);
313  my_decimal *decval_2= user_var->val_decimal(&decimal);
314  user_var->save_item_result(item_dec);
315 
316  EXPECT_EQ(decval_1, decval_2);
317  EXPECT_EQ(decval_1, &decimal);
318 }
319 
320 
321 // Test of Item::operator new() when we simulate out-of-memory.
322 TEST_F(ItemTest, OutOfMemory)
323 {
324  Item_int *null_item= NULL;
325  Item_int *item= new Item_int(42);
326  EXPECT_NE(null_item, item);
327  delete null_item;
328 
329 #if !defined(DBUG_OFF)
330  // Setting debug flags triggers enter/exit trace, so redirect to /dev/null.
331  DBUG_SET("o," IF_WIN("NUL", "/dev/null"));
332 
333  DBUG_SET("+d,simulate_out_of_memory");
334  item= new Item_int(42);
335  EXPECT_EQ(null_item, item);
336 
337  DBUG_SET("+d,simulate_out_of_memory");
338  item= new (thd()->mem_root) Item_int(42);
339  EXPECT_EQ(null_item, item);
340 #endif
341 }
342 
343 
344 // We never use dynamic_cast, but we expect it to work.
345 TEST_F(ItemTest, DynamicCast)
346 {
347  Item *item= new Item_int(42);
348  const Item_int *null_item= NULL;
349  EXPECT_NE(null_item, dynamic_cast<Item_int*>(item));
350 }
351 
352 
353 TEST_F(ItemTest, ItemFuncXor)
354 {
355  const uint length= 1U;
356  Item_int *item_zero= new Item_int(0, length);
357  Item_int *item_one_a= new Item_int(1, length);
358 
359  Item_func_xor *item_xor=
360  new Item_func_xor(item_zero, item_one_a);
361 
362  EXPECT_FALSE(item_xor->fix_fields(thd(), NULL));
363  EXPECT_EQ(1, item_xor->val_int());
364  EXPECT_EQ(1U, item_xor->decimal_precision());
365 
366  Item_int *item_one_b= new Item_int(1, length);
367 
368  Item_func_xor *item_xor_same=
369  new Item_func_xor(item_one_a, item_one_b);
370 
371  EXPECT_FALSE(item_xor_same->fix_fields(thd(), NULL));
372  EXPECT_EQ(0, item_xor_same->val_int());
373  EXPECT_FALSE(item_xor_same->val_bool());
374  EXPECT_FALSE(item_xor_same->is_null());
375 
376  String print_buffer;
377  item_xor->print(&print_buffer, QT_ORDINARY);
378  EXPECT_STREQ("(0 xor 1)", print_buffer.c_ptr_safe());
379 
380  Item *neg_xor= item_xor->neg_transformer(thd());
381  EXPECT_FALSE(neg_xor->fix_fields(thd(), NULL));
382  EXPECT_EQ(0, neg_xor->val_int());
383  EXPECT_DOUBLE_EQ(0.0, neg_xor->val_real());
384  EXPECT_FALSE(neg_xor->val_bool());
385  EXPECT_FALSE(neg_xor->is_null());
386 
387  print_buffer= String();
388  neg_xor->print(&print_buffer, QT_ORDINARY);
389  EXPECT_STREQ("((not(0)) xor 1)", print_buffer.c_ptr_safe());
390 
391  Item_func_xor *item_xor_null=
392  new Item_func_xor(item_zero, new Item_null());
393  EXPECT_FALSE(item_xor_null->fix_fields(thd(), NULL));
394 
395  EXPECT_EQ(0, item_xor_null->val_int());
396  EXPECT_TRUE(item_xor_null->is_null());
397 }
398 
399 
400 /*
401  Testing MYSQL_TIME_cache.
402 */
403 TEST_F(ItemTest, MYSQL_TIME_cache)
404 {
405  String str_buff, *str;
406  MYSQL_TIME datetime6=
407  { 2011, 11, 7, 10, 20, 30, 123456, 0, MYSQL_TIMESTAMP_DATETIME };
408  MYSQL_TIME time6=
409  { 0, 0, 0, 10, 20, 30, 123456, 0, MYSQL_TIMESTAMP_TIME };
410  struct timeval tv6= {1320661230, 123456};
411  const MYSQL_TIME *ltime;
412  MYSQL_TIME_cache cache;
413 
414  /*
415  Testing DATETIME(6).
416  Initializing from MYSQL_TIME.
417  */
418  cache.set_datetime(&datetime6, 6);
419  EXPECT_EQ(1840440237558456896LL, cache.val_packed());
420  EXPECT_EQ(6, cache.decimals());
421  // Call val_str() then cptr()
422  str= cache.val_str(&str_buff);
423  EXPECT_STREQ("2011-11-07 10:20:30.123456", str->c_ptr_safe());
424  EXPECT_STREQ("2011-11-07 10:20:30.123456", cache.cptr());
425  cache.set_datetime(&datetime6, 6);
426  // Now call the other way around: cptr() then val_str()
427  EXPECT_STREQ("2011-11-07 10:20:30.123456", cache.cptr());
428  EXPECT_STREQ("2011-11-07 10:20:30.123456", str->c_ptr_safe());
429  // Testing get_TIME_ptr()
430  ltime= cache.get_TIME_ptr();
431  EXPECT_EQ(ltime->year, datetime6.year);
432  EXPECT_EQ(ltime->month, datetime6.month);
433  EXPECT_EQ(ltime->day, datetime6.day);
434  EXPECT_EQ(ltime->hour, datetime6.hour);
435  EXPECT_EQ(ltime->minute, datetime6.minute);
436  EXPECT_EQ(ltime->second, datetime6.second);
437  EXPECT_EQ(ltime->second_part, datetime6.second_part);
438  EXPECT_EQ(ltime->neg, datetime6.neg);
439  EXPECT_EQ(ltime->time_type, datetime6.time_type);
440  // Testing eq()
441  {
442  MYSQL_TIME datetime6_2= datetime6;
443  MYSQL_TIME_cache cache2;
444  datetime6_2.second_part+= 1;
445  cache2.set_datetime(&datetime6_2, 6);
446  EXPECT_EQ(cache.eq(cache), true);
447  EXPECT_EQ(cache.eq(cache2), false);
448  EXPECT_EQ(cache2.eq(cache2), true);
449  EXPECT_EQ(cache2.eq(cache), false);
450  }
451 
452  /*
453  Testing DATETIME(6).
454  Initializing from "struct timeval".
455  */
456  cache.set_datetime(tv6, 6, my_tz_UTC);
457  EXPECT_EQ(1840440237558456896LL, cache.val_packed());
458  EXPECT_EQ(6, cache.decimals());
459  str= cache.val_str(&str_buff);
460  EXPECT_STREQ("2011-11-07 10:20:30.123456", str->c_ptr_safe());
461  EXPECT_STREQ("2011-11-07 10:20:30.123456", cache.cptr());
462 
463  /*
464  Testing TIME(6).
465  Initializing from MYSQL_TIME.
466  */
467  cache.set_time(&time6, 6);
468  EXPECT_EQ(709173043776LL, cache.val_packed());
469  EXPECT_EQ(6, cache.decimals());
470  // Call val_str() then cptr()
471  str= cache.val_str(&str_buff);
472  EXPECT_STREQ("10:20:30.123456", str->c_ptr_safe());
473  EXPECT_STREQ("10:20:30.123456", cache.cptr());
474 
475  /*
476  Testing TIME(6).
477  Initializing from "struct timeval".
478  */
479  cache.set_time(tv6, 6, my_tz_UTC);
480  EXPECT_EQ(709173043776LL, cache.val_packed());
481  EXPECT_EQ(6, cache.decimals());
482  str= cache.val_str(&str_buff);
483  EXPECT_STREQ("10:20:30.123456", str->c_ptr_safe());
484  EXPECT_STREQ("10:20:30.123456", cache.cptr());
485 
486  /*
487  Testing DATETIME(5)
488  */
489  MYSQL_TIME datetime5=
490  { 2011, 11, 7, 10, 20, 30, 123450, 0, MYSQL_TIMESTAMP_DATETIME };
491  cache.set_datetime(&datetime5, 5);
492  EXPECT_EQ(1840440237558456890LL, cache.val_packed());
493  EXPECT_EQ(5, cache.decimals());
494  /* Call val_str() then cptr() */
495  str= cache.val_str(&str_buff);
496  EXPECT_STREQ("2011-11-07 10:20:30.12345", str->c_ptr_safe());
497  EXPECT_STREQ("2011-11-07 10:20:30.12345", cache.cptr());
498  cache.set_datetime(&datetime5, 5);
499  /* Now call the other way around: cptr() then val_str() */
500  EXPECT_STREQ("2011-11-07 10:20:30.12345", cache.cptr());
501  EXPECT_STREQ("2011-11-07 10:20:30.12345", str->c_ptr_safe());
502 
503  /*
504  Testing DATE.
505  Initializing from MYSQL_TIME.
506  */
507  MYSQL_TIME date=
508  { 2011, 11, 7, 0, 0, 0, 0, 0, MYSQL_TIMESTAMP_DATE };
509  cache.set_date(&date);
510  EXPECT_EQ(1840439528385413120LL, cache.val_packed());
511  EXPECT_EQ(0, cache.decimals());
512  str= cache.val_str(&str_buff);
513  EXPECT_STREQ("2011-11-07", str->c_ptr_safe());
514  EXPECT_STREQ("2011-11-07", cache.cptr());
515 
516  /*
517  Testing DATE.
518  Initializing from "struct tm".
519  */
520  cache.set_date(tv6, my_tz_UTC);
521  EXPECT_EQ(1840439528385413120LL, cache.val_packed());
522  EXPECT_EQ(0, cache.decimals());
523  str= cache.val_str(&str_buff);
524  EXPECT_STREQ("2011-11-07", str->c_ptr_safe());
525  EXPECT_STREQ("2011-11-07", cache.cptr());
526 }
527 
528 }