MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
field_date-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_date_unittests {
27 
30 
31 class FieldDateTest : 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  // Store zero date using different combinations of SQL modes
44  static const int no_modes= 4;
45  static const sql_mode_t strict_modes[no_modes];
46 
47  static const type_conversion_status nozero_expected_status[];
48 };
49 
50 const sql_mode_t FieldDateTest::strict_modes[no_modes]=
51 {
52  0,
53  MODE_STRICT_TRANS_TABLES,
54  MODE_STRICT_ALL_TABLES,
55  MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES
56 };
57 
58 const type_conversion_status FieldDateTest::nozero_expected_status[]=
59 {
60  TYPE_NOTE_TIME_TRUNCATED,
61  TYPE_ERR_BAD_VALUE,
62  TYPE_ERR_BAD_VALUE,
63  TYPE_ERR_BAD_VALUE
64 };
65 
66 
68 {
69 private:
70  uchar buffer[PACK_LENGTH];
71  uchar null_byte;
72 
73  void initialize()
74  {
75  ptr= buffer;
76  null_ptr= &null_byte;
77  memset(buffer, 0, PACK_LENGTH);
78  null_byte= '\0';
79  }
80 public:
81 
83  : Field_newdate(0, // ptr_arg
84  NULL, // null_ptr_arg
85  1, // null_bit_arg
86  Field::NONE, // unireg_check_arg
87  "field_name") // field_name_arg
88  {
89  initialize();
90  }
91 
92  void make_writable() { bitmap_set_bit(table->write_set, field_index); }
93 };
94 
95 
96 TEST_F(FieldDateTest, StoreLegalStringValues)
97 {
98  Mock_field_date field_date;
99  Fake_TABLE table(&field_date);
100  table.in_use= thd();
101  field_date.make_writable();
102 
103  {
104  SCOPED_TRACE("");
105  test_store_string(&field_date, STRING_WITH_LEN("2001-01-01"),
106  "2001-01-01", 0, TYPE_OK);
107  }
108  {
109  SCOPED_TRACE("");
110  test_store_string(&field_date, STRING_WITH_LEN("0000-00-00"),
111  "0000-00-00", 0, TYPE_OK);
112  }
113  {
114  SCOPED_TRACE("");
115  test_store_string(&field_date, STRING_WITH_LEN("0001-00-00"),
116  "0001-00-00", 0, TYPE_OK);
117  }
118 }
119 
120 TEST_F(FieldDateTest, StoreIllegalStringValues)
121 {
122  Mock_field_date field_date;
123  Fake_TABLE table(&field_date);
124  table.in_use= thd();
125  field_date.make_writable();
126  thd()->count_cuted_fields= CHECK_FIELD_WARN;
127 
128  // Truncates time
129  {
130  SCOPED_TRACE("");
131  test_store_string(&field_date, STRING_WITH_LEN("2001-01-01 00:00:01"),
132  "2001-01-01",
133  WARN_DATA_TRUNCATED, TYPE_NOTE_TIME_TRUNCATED);
134  }
135 
136  // Bad year
137  {
138  SCOPED_TRACE("");
139  test_store_string(&field_date, STRING_WITH_LEN("99999-01-01"),
140  "0000-00-00",
141  WARN_DATA_TRUNCATED, TYPE_ERR_BAD_VALUE);
142  }
143 
144  // Bad month
145  {
146  SCOPED_TRACE("");
147  test_store_string(&field_date, STRING_WITH_LEN("2001-13-01"), "0000-00-00",
148  WARN_DATA_TRUNCATED, TYPE_ERR_BAD_VALUE);
149  }
150 
151  // Bad day
152  {
153  SCOPED_TRACE("");
154  test_store_string(&field_date, STRING_WITH_LEN("2001-01-32"), "0000-00-00",
155  WARN_DATA_TRUNCATED, TYPE_ERR_BAD_VALUE);
156  }
157 
158  // Not a date
159  {
160  SCOPED_TRACE("");
161  test_store_string(&field_date, STRING_WITH_LEN("foo"), "0000-00-00",
162  WARN_DATA_TRUNCATED, TYPE_ERR_BAD_VALUE);
163  }
164 }
165 
166 
167 
175 TEST_F(FieldDateTest, StoreZeroDateSqlModeNoZeroRestrictions)
176 {
177  Mock_field_date field_date;
178  Fake_TABLE table(&field_date);
179  table.in_use= thd();
180  field_date.make_writable();
181  thd()->count_cuted_fields= CHECK_FIELD_WARN;
182 
183  for (int i= 0; i < no_modes; i++)
184  {
185  SCOPED_TRACE("");
186  store_zero_in_sql_mode(&field_date, STRING_WITH_LEN("0000-00-00"),
187  "0000-00-00", TYPE_OK, strict_modes[i], 0);
188  }
189 
190  for (int i= 0; i < no_modes; i++)
191  {
192  SCOPED_TRACE("");
193  store_zero_in_sql_mode(&field_date, STRING_WITH_LEN("0000-01-01"),
194  "0000-01-01", TYPE_OK, strict_modes[i], 0);
195 
196  }
197 
198  for (int i= 0; i < no_modes; i++)
199  {
200  SCOPED_TRACE("");
201  store_zero_in_sql_mode(&field_date, STRING_WITH_LEN("2001-00-01"),
202  "2001-00-01", TYPE_OK, strict_modes[i], 0);
203 
204  }
205 
206  for (int i= 0; i < no_modes; i++)
207  {
208  SCOPED_TRACE("");
209  store_zero_in_sql_mode(&field_date, STRING_WITH_LEN("2001-01-00"),
210  "2001-01-00", TYPE_OK, strict_modes[i], 0);
211  }
212 }
213 
214 
222 TEST_F(FieldDateTest, StoreZeroDateSqlModeNoZeroDate)
223 {
224  Mock_field_date field_date;
225  Fake_TABLE table(&field_date);
226  table.in_use= thd();
227  field_date.make_writable();
228  thd()->count_cuted_fields= CHECK_FIELD_WARN;
229 
230  // With "MODE_NO_ZERO_DATE" set - Errors if date is all null
231  for (int i= 0; i < no_modes; i++)
232  {
233  SCOPED_TRACE("");
234  store_zero_in_sql_mode(&field_date,
235  STRING_WITH_LEN("0000-00-00"),
236  "0000-00-00",
237  nozero_expected_status[i],
238  MODE_NO_ZERO_DATE | strict_modes[i],
239  ER_WARN_DATA_OUT_OF_RANGE);
240  }
241 
242  // Zero year, month or day is fine
243  for (int i= 0; i < no_modes; i++)
244  {
245  SCOPED_TRACE("");
246  store_zero_in_sql_mode(&field_date,
247  STRING_WITH_LEN("0000-01-01"),
248  "0000-01-01",
249  TYPE_OK,
250  MODE_NO_ZERO_DATE | strict_modes[i],
251  0);
252  }
253 
254  for (int i= 0; i < no_modes; i++)
255  {
256  SCOPED_TRACE("");
257  store_zero_in_sql_mode(&field_date,
258  STRING_WITH_LEN("2001-00-01"),
259  "2001-00-01",
260  TYPE_OK,
261  MODE_NO_ZERO_DATE | strict_modes[i],
262  0);
263  }
264 
265  for (int i= 0; i < no_modes; i++)
266  {
267  SCOPED_TRACE("");
268  store_zero_in_sql_mode(&field_date,
269  STRING_WITH_LEN("2001-01-00"),
270  "2001-01-00",
271  TYPE_OK,
272  MODE_NO_ZERO_DATE | strict_modes[i],
273  0);
274  }
275 }
276 
283 TEST_F(FieldDateTest, StoreZeroDateSqlModeNoZeroInDate)
284 {
285  Mock_field_date field_date;
286  Fake_TABLE table(&field_date);
287  table.in_use= thd();
288  field_date.make_writable();
289  thd()->count_cuted_fields= CHECK_FIELD_WARN;
290 
291  // With "MODE_NO_ZERO_IN_DATE" set - Entire date zero is ok
292  for (int i= 0; i < no_modes; i++)
293  {
294  SCOPED_TRACE("");
295  store_zero_in_sql_mode(&field_date,
296  STRING_WITH_LEN("0000-00-00"),
297  "0000-00-00",
298  TYPE_OK,
299  MODE_NO_ZERO_IN_DATE | strict_modes[i],
300  0);
301  }
302 
303  // Year 0 is valid in strict mode too
304  for (int i= 0; i < no_modes; i++)
305  {
306  SCOPED_TRACE("");
307  store_zero_in_sql_mode(&field_date,
308  STRING_WITH_LEN("0000-01-01"),
309  "0000-01-01",
310  TYPE_OK,
311  MODE_NO_ZERO_IN_DATE | strict_modes[i],
312  0);
313  }
314 
315  // Month 0 is NOT valid in strict mode, stores all-zero date
316  for (int i= 0; i < no_modes; i++)
317  {
318  SCOPED_TRACE("");
319  store_zero_in_sql_mode(&field_date,
320  STRING_WITH_LEN("2001-00-01"),
321  "0000-00-00",
322  nozero_expected_status[i],
323  MODE_NO_ZERO_IN_DATE | strict_modes[i],
324  ER_WARN_DATA_OUT_OF_RANGE);
325  }
326 
327  // Day 0 is NOT valid in strict mode, stores all-zero date
328  for (int i= 0; i < no_modes; i++)
329  {
330  SCOPED_TRACE("");
331  store_zero_in_sql_mode(&field_date,
332  STRING_WITH_LEN("2001-01-00"),
333  "0000-00-00",
334  nozero_expected_status[i],
335  MODE_NO_ZERO_IN_DATE | strict_modes[i],
336  ER_WARN_DATA_OUT_OF_RANGE);
337  }
338 }
339 
340 
341 }