MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sql_table-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 Foundation,
14  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15 
16 // First include (the generated) my_config.h, to get correct platform defines,
17 // then gtest.h (before any other MySQL headers), to avoid min() macros etc ...
18 #include "my_config.h"
19 #include <gtest/gtest.h>
20 
21 #include "mock_create_field.h"
22 #include "test_utils.h"
23 #include "mock_field_timestamp.h"
24 #include "item.h"
25 #include "sql_class.h"
26 #include "rpl_handler.h" // delegates_init()
27 #include "sql_table.h"
28 
29 namespace sql_table_unittest {
30 
33 
34 /*
35  Test of functionality in the file sql_table.cc
36  */
37 class SqlTableTest : public ::testing::Test
38 {
39 protected:
40  virtual void SetUp() { initializer.SetUp(); }
41  virtual void TearDown() { initializer.TearDown(); }
42 
43  THD *get_thd() { return initializer.thd(); }
44 
45  Server_initializer initializer;
46 };
47 
48 
49 /*
50  Test of promote_first_timestamp_column(). We pass it a list of two TIMESTAMP
51  NOT NULL columns, the first of which should be promoted to DEFAULT
52  CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP. The second column should not
53  be promoted.
54  */
55 TEST_F(SqlTableTest, PromoteFirstTimestampColumn1)
56 {
57  Mock_create_field column_1_definition(MYSQL_TYPE_TIMESTAMP, NULL, NULL);
58  Mock_create_field column_2_definition(MYSQL_TYPE_TIMESTAMP, NULL, NULL);
59  column_1_definition.flags|= NOT_NULL_FLAG;
60  column_2_definition.flags|= NOT_NULL_FLAG;
61  List<Create_field> definitions;
62  definitions.push_front(&column_1_definition);
63  definitions.push_back(&column_2_definition);
64  promote_first_timestamp_column(&definitions);
65  EXPECT_EQ(Field::TIMESTAMP_DNUN_FIELD, column_1_definition.unireg_check);
66  EXPECT_EQ(Field::NONE, column_2_definition.unireg_check);
67 }
68 
69 
70 
71 /*
72  Test of promote_first_timestamp_column(). We pass it a list of two TIMESTAMP
73  NOT NULL columns, the first of which should be promoted to DEFAULT
74  CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP. The second column should not
75  be promoted.
76  */
77 TEST_F(SqlTableTest, PromoteFirstTimestampColumn2)
78 {
79  Mock_create_field column_1_definition(MYSQL_TYPE_TIMESTAMP2, NULL, NULL);
80  Mock_create_field column_2_definition(MYSQL_TYPE_TIMESTAMP2, NULL, NULL);
81  column_1_definition.flags|= NOT_NULL_FLAG;
82  column_2_definition.flags|= NOT_NULL_FLAG;
83  List<Create_field> definitions;
84  definitions.push_front(&column_1_definition);
85  definitions.push_back(&column_2_definition);
86  promote_first_timestamp_column(&definitions);
87  EXPECT_EQ(Field::TIMESTAMP_DNUN_FIELD, column_1_definition.unireg_check);
88  EXPECT_EQ(Field::NONE, column_2_definition.unireg_check);
89 }
90 
91 
92 /*
93  Test of promote_first_timestamp_column(). We pass it a list of two columns,
94  one TIMESTAMP NULL DEFAULT 1, and one TIMESTAMP NOT NULL. No promotion
95  should take place.
96  */
97 TEST_F(SqlTableTest, PromoteFirstTimestampColumn3)
98 {
99  Item_string *item_str= new Item_string("1", 1, &my_charset_latin1);
100  Mock_create_field column_1_definition(MYSQL_TYPE_TIMESTAMP, item_str, NULL);
101  Mock_create_field column_2_definition(MYSQL_TYPE_TIMESTAMP, NULL, NULL);
102  column_2_definition.flags|= NOT_NULL_FLAG;
103  List<Create_field> definitions;
104  definitions.push_front(&column_1_definition);
105  definitions.push_back(&column_2_definition);
106  promote_first_timestamp_column(&definitions);
107  EXPECT_EQ(Field::NONE, column_1_definition.unireg_check);
108  EXPECT_EQ(Field::NONE, column_2_definition.unireg_check);
109 }
110 
111 
113 const char srv_mysql50_table_name_prefix[10] = "#mysql50#";
114 
115 /*
116  This is a test case based on innobase_init()
117  There was an out-of-bounds read when converting "-@" to a table name.
118  */
119 TEST_F(SqlTableTest, FileNameToTableName)
120 {
121  struct PackStuff
122  {
123  char foo1;
124  char str[3];
125  char foo2;
126  };
127  PackStuff foo;
128  memcpy(foo.str, "-@", 3);
129  MEM_NOACCESS(&foo.foo1, 1);
130  MEM_NOACCESS(&foo.foo2, 1);
131 
132  const char test_filename[] = "-@";
133  char test_tablename[sizeof test_filename
134  + sizeof(srv_mysql50_table_name_prefix) - 1];
135 
136  // This one used to fail with AddressSanitizer
137  uint name_length;
138  name_length= filename_to_tablename(test_filename,
139  test_tablename,
140  sizeof(test_tablename)
141 #ifndef DBUG_OFF
142  , true
143 #endif
144  );
145  EXPECT_EQ((sizeof(test_tablename)) - 1, name_length);
146 
147  // This one used to fail if compiled with -DHAVE_VALGRIND
148  name_length= filename_to_tablename(foo.str,
149  test_tablename,
150  sizeof(test_tablename)
151 #ifndef DBUG_OFF
152  , true
153 #endif
154  );
155  EXPECT_EQ((sizeof(test_tablename)) - 1, name_length);
156 
157 }
158 
159 }