MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
field_datetime-t.cc
1 /* Copyright (c) 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 
20 #include "field_temporal_utils.h"
21 #include "test_utils.h"
22 #include "fake_table.h"
23 
24 #include "field.h"
25 
26 namespace field_datetime_unittests {
27 
30 
31 class FieldDatetimeTest : public ::testing::Test
32 {
33 protected:
34  virtual void SetUp() { initializer.SetUp(); }
35  virtual void TearDown() { initializer.TearDown(); }
36 
37  THD *thd() { return initializer.thd(); }
38 
39  Server_initializer initializer;
40 
41  Field_set *create_field_set(TYPELIB *tl);
42 };
43 
44 
46 {
47 private:
48  uchar buffer[PACK_LENGTH];
49  uchar null_byte;
50 
51  void initialize()
52  {
53  ptr= buffer;
54  null_ptr= &null_byte;
55  memset(buffer, 0, PACK_LENGTH);
56  null_byte= '\0';
57  }
58 
59 public:
60 
62  : Field_datetime(0, // ptr_arg
63  NULL, // null_ptr_arg
64  1, // null_bit_arg
65  Field::NONE, // unireg_check_arg
66  "field_name") // field_name_arg
67  {
68  initialize();
69  }
70 
71  void make_writable() { bitmap_set_bit(table->write_set, field_index); }
72 };
73 
74 
75 TEST_F(FieldDatetimeTest, StoreLegalStringValues)
76 {
77  char buff[MAX_FIELD_WIDTH];
78  String str(buff, sizeof(buff), &my_charset_bin);
79  String unused;
80 
81  Mock_field_datetime field_dt;
82  Fake_TABLE table(&field_dt);
83  table.in_use= thd();
84  field_dt.make_writable();
85  thd()->count_cuted_fields= CHECK_FIELD_WARN;
86 
87  {
88  SCOPED_TRACE("");
89  test_store_string(&field_dt, STRING_WITH_LEN("2001-01-01 00:00:01"),
90  "2001-01-01 00:00:01", 0, TYPE_OK);
91  }
92  {
93  SCOPED_TRACE("");
94  test_store_string(&field_dt, STRING_WITH_LEN("0000-00-00 00:00:00"),
95  "0000-00-00 00:00:00", 0, TYPE_OK);
96  }
97  {
98  SCOPED_TRACE("");
99  test_store_string(&field_dt, STRING_WITH_LEN("0001-00-00 00:00:00"),
100  "0001-00-00 00:00:00", 0, TYPE_OK);
101  }
102 }
103 
104 
105 TEST_F(FieldDatetimeTest, StoreIllegalStringValues)
106 {
107  Mock_field_datetime field_dt;
108  Fake_TABLE table(&field_dt);
109  table.in_use= thd();
110  field_dt.make_writable();
111  thd()->count_cuted_fields= CHECK_FIELD_WARN;
112 
113  // Bad year
114  {
115  SCOPED_TRACE("");
116  test_store_string(&field_dt, STRING_WITH_LEN("99999-01-01 00:00:01"),
117  "0000-00-00 00:00:00",
118  WARN_DATA_TRUNCATED, TYPE_ERR_BAD_VALUE);
119  }
120 
121  // Bad month
122  {
123  SCOPED_TRACE("");
124  test_store_string(&field_dt, STRING_WITH_LEN("2001-13-01 00:00:01"),
125  "0000-00-00 00:00:00",
126  WARN_DATA_TRUNCATED, TYPE_ERR_BAD_VALUE);
127  }
128 
129  // Bad day
130  {
131  SCOPED_TRACE("");
132  test_store_string(&field_dt, STRING_WITH_LEN("2001-01-32 00:00:01"),
133  "0000-00-00 00:00:00",
134  WARN_DATA_TRUNCATED, TYPE_ERR_BAD_VALUE);
135  }
136 
137  // Bad hour
138  {
139  SCOPED_TRACE("");
140  test_store_string(&field_dt, STRING_WITH_LEN("2001-01-01 72:00:01"),
141  "0000-00-00 00:00:00",
142  WARN_DATA_TRUNCATED, TYPE_ERR_BAD_VALUE);
143  }
144 
145  // Bad minute
146  {
147  SCOPED_TRACE("");
148  test_store_string(&field_dt, STRING_WITH_LEN("2001-01-01 00:72:01"),
149  "0000-00-00 00:00:00",
150  WARN_DATA_TRUNCATED, TYPE_ERR_BAD_VALUE);
151  }
152 
153  // Bad second
154  {
155  SCOPED_TRACE("");
156  test_store_string(&field_dt, STRING_WITH_LEN("2001-01-01 00:00:72"),
157  "0000-00-00 00:00:00",
158  WARN_DATA_TRUNCATED, TYPE_ERR_BAD_VALUE);
159  }
160 
161  // Not a day
162  {
163  SCOPED_TRACE("");
164  test_store_string(&field_dt, STRING_WITH_LEN("foo"), "0000-00-00 00:00:00",
165  WARN_DATA_TRUNCATED, TYPE_ERR_BAD_VALUE);
166  }
167 }
168 
169 
170 // Store zero date using different combinations of SQL modes
171 static const int no_modes= 4;
172 static const sql_mode_t strict_modes[no_modes]=
173  {
174  0,
175  MODE_STRICT_TRANS_TABLES,
176  MODE_STRICT_ALL_TABLES,
177  MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES
178  };
179 
180 
188 TEST_F(FieldDatetimeTest, StoreZeroDateSqlModeNoZeroRestrictions)
189 {
190  Mock_field_datetime field_dt;
191  Fake_TABLE table(&field_dt);
192  table.in_use= thd();
193  field_dt.make_writable();
194  thd()->count_cuted_fields= CHECK_FIELD_WARN;
195 
196  for (int i= 0; i < no_modes; i++)
197  {
198  SCOPED_TRACE("");
199  store_zero_in_sql_mode(&field_dt,
200  STRING_WITH_LEN("0000-00-00 00:00:00"),
201  "0000-00-00 00:00:00",
202  TYPE_OK, strict_modes[i], 0);
203  }
204 
205  for (int i= 0; i < no_modes; i++)
206  {
207  SCOPED_TRACE("");
208  store_zero_in_sql_mode(&field_dt,
209  STRING_WITH_LEN("0000-01-01 00:00:00"),
210  "0000-01-01 00:00:00",
211  TYPE_OK, strict_modes[i], 0);
212  }
213 
214  for (int i= 0; i < no_modes; i++)
215  {
216  SCOPED_TRACE("");
217  store_zero_in_sql_mode(&field_dt,
218  STRING_WITH_LEN("2001-00-01 00:00:00"),
219  "2001-00-01 00:00:00",
220  TYPE_OK, strict_modes[i], 0);
221  }
222 
223  for (int i= 0; i < no_modes; i++)
224  {
225  SCOPED_TRACE("");
226  store_zero_in_sql_mode(&field_dt,
227  STRING_WITH_LEN("2001-01-00 00:00:00"),
228  "2001-01-00 00:00:00",
229  TYPE_OK, strict_modes[i], 0);
230  }
231 }
232 
233 
234 static const type_conversion_status nozero_expected_status[]=
235  {
236  TYPE_NOTE_TIME_TRUNCATED,
237  TYPE_ERR_BAD_VALUE,
238  TYPE_ERR_BAD_VALUE,
239  TYPE_ERR_BAD_VALUE
240  };
241 
249 TEST_F(FieldDatetimeTest, StoreZeroDateSqlModeNoZeroDate)
250 {
251  Mock_field_datetime field_dt;
252  Fake_TABLE table(&field_dt);
253  table.in_use= thd();
254  field_dt.make_writable();
255  thd()->count_cuted_fields= CHECK_FIELD_WARN;
256 
257  // With "MODE_NO_ZERO_DATE" set - Errors if date is all null
258  for (int i= 0; i < no_modes; i++)
259  {
260  SCOPED_TRACE("");
261  store_zero_in_sql_mode(&field_dt,
262  STRING_WITH_LEN("0000-00-00 00:00:00"),
263  "0000-00-00 00:00:00",
264  nozero_expected_status[i],
265  MODE_NO_ZERO_DATE | strict_modes[i],
266  ER_WARN_DATA_OUT_OF_RANGE);
267  }
268 
269  // Zero year, month or day is fine
270  for (int i= 0; i < no_modes; i++)
271  {
272  SCOPED_TRACE("");
273  store_zero_in_sql_mode(&field_dt,
274  STRING_WITH_LEN("0000-01-01 00:00:00"),
275  "0000-01-01 00:00:00",
276  TYPE_OK,
277  MODE_NO_ZERO_DATE | strict_modes[i],
278  0);
279  }
280 
281  for (int i= 0; i < no_modes; i++)
282  {
283  SCOPED_TRACE("");
284  store_zero_in_sql_mode(&field_dt,
285  STRING_WITH_LEN("2001-00-01 00:00:00"),
286  "2001-00-01 00:00:00",
287  TYPE_OK,
288  MODE_NO_ZERO_DATE | strict_modes[i],
289  0);
290  }
291 
292  for (int i= 0; i < no_modes; i++)
293  {
294  SCOPED_TRACE("");
295  store_zero_in_sql_mode(&field_dt,
296  STRING_WITH_LEN("2001-01-00 00:00:00"),
297  "2001-01-00 00:00:00",
298  TYPE_OK,
299  MODE_NO_ZERO_DATE | strict_modes[i],
300  0);
301  }
302 }
303 
310 TEST_F(FieldDatetimeTest, StoreZeroDateSqlModeNoZeroInDate)
311 {
312  Mock_field_datetime field_dt;
313  Fake_TABLE table(&field_dt);
314  table.in_use= thd();
315  field_dt.make_writable();
316  thd()->count_cuted_fields= CHECK_FIELD_WARN;
317 
318  // With "MODE_NO_ZERO_IN_DATE" set - Entire date zero is ok
319  for (int i= 0; i < no_modes; i++)
320  {
321  SCOPED_TRACE("");
322  store_zero_in_sql_mode(&field_dt,
323  STRING_WITH_LEN("0000-00-00 00:00:00"),
324  "0000-00-00 00:00:00",
325  TYPE_OK,
326  MODE_NO_ZERO_IN_DATE | strict_modes[i],
327  0);
328  }
329 
330  // Year 0 is valid in strict mode too
331  for (int i= 0; i < no_modes; i++)
332  {
333  SCOPED_TRACE("");
334  store_zero_in_sql_mode(&field_dt,
335  STRING_WITH_LEN("0000-01-01 00:00:00"),
336  "0000-01-01 00:00:00",
337  TYPE_OK,
338  MODE_NO_ZERO_IN_DATE | strict_modes[i],
339  0);
340  }
341 
342  // Month 0 is NOT valid in strict mode, stores all-zero date
343  for (int i= 0; i < no_modes; i++)
344  {
345  SCOPED_TRACE("");
346  store_zero_in_sql_mode(&field_dt,
347  STRING_WITH_LEN("2001-00-01 00:00:00"),
348  "0000-00-00 00:00:00",
349  nozero_expected_status[i],
350  MODE_NO_ZERO_IN_DATE | strict_modes[i],
351  ER_WARN_DATA_OUT_OF_RANGE);
352  }
353 
354  // Day 0 is NOT valid in strict mode, stores all-zero date
355  for (int i= 0; i < no_modes; i++)
356  {
357  SCOPED_TRACE("");
358  store_zero_in_sql_mode(&field_dt,
359  STRING_WITH_LEN("2001-01-00 00:00:00"),
360  "0000-00-00 00:00:00",
361  nozero_expected_status[i],
362  MODE_NO_ZERO_IN_DATE | strict_modes[i],
363  ER_WARN_DATA_OUT_OF_RANGE);
364  }
365 }
366 
367 
368 }