MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
copy_info-t.cc
1 /* Copyright (c) 2011, 2013, 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 #include <gmock/gmock.h>
21 
22 #include "mock_field_timestamp.h"
23 #include "fake_table.h"
24 #include "test_utils.h"
25 #include "sql_data_change.h"
26 
27 namespace copy_info_unittest {
28 
31 
32 using ::testing::StrictMock;
33 using ::testing::_;
34 
35 /*
36  Tests for the functionality of the COPY_INFO class. We test all public
37  interfaces, and some of the protected parts:
38 
39  - COPY_INFO::get_function_default_columns, and
40  - COPY_INFO::get_cached_bitmap
41 */
42 class CopyInfoTest : public ::testing::Test
43 {
44 protected:
45  virtual void SetUp() { initializer.SetUp(); }
46  virtual void TearDown() { initializer.TearDown(); }
47 
48  Server_initializer initializer;
49 };
50 
51 
56 class Mock_field : public Field_long
57 {
58  uchar null_byte;
59 public:
60 
61  Mock_field(utype unireg) :
62  Field_long(NULL, 0, &null_byte, 0, unireg, "", false, false)
63  {}
64 
65  MOCK_METHOD1(store_timestamp, void(const timeval*));
66 };
67 
68 
69 /*
70  Compares two COPY_INFO::Statistics and makes sure they are equal.
71 */
72 void check_equality(const COPY_INFO::Statistics a,
73  const COPY_INFO::Statistics b)
74 {
75  EXPECT_EQ(a.records, b.records);
76  EXPECT_EQ(a.deleted, b.deleted);
77  EXPECT_EQ(a.updated, b.updated);
78  EXPECT_EQ(a.copied, b.copied);
79  EXPECT_EQ(a.error_count, b.error_count);
80  EXPECT_EQ(a.touched, b.touched);
81 }
82 
83 
84 /*
85  Convenience class for creating a COPY_INFO to represent an insert operation.
86 */
88 {
89 public:
90  Mock_COPY_INFO(operation_type optype,
91  List<Item> *inserted_columns,
92  enum_duplicates duplicate_handling,
93  bool ignore_errors)
94  : COPY_INFO(optype,
95  inserted_columns,
96  true, // manage_defaults
97  duplicate_handling,
98  ignore_errors)
99  {}
100 
101  // Import protected member functions, so we can test them.
104 };
105 
106 
107 /*
108  Convenience class for creating a COPY_INFO to represent an insert operation.
109 */
111 {
112 public:
114  COPY_INFO(COPY_INFO::INSERT_OPERATION, static_cast<List<Item>*>(NULL),
115  true, // manage_defaults
116  DUP_UPDATE, false)
117  {}
119  COPY_INFO(COPY_INFO::INSERT_OPERATION, fields,
120  true, // manage_defaults
121  DUP_UPDATE, false)
122  {}
123  // Import protected member functions, so we can test them.
126 };
127 
128 
129 /*
130  Convenience class for creating a COPY_INFO to represent an update
131  operation.
132 */
134 {
135 public:
137  : COPY_INFO(COPY_INFO::UPDATE_OPERATION, NULL, NULL)
138  {}
139  // Import protected member functions, so we can test them.
142 };
143 
144 
145 /*
146  Tests that constuctors initialize the stats object properly.
147 */
148 TEST_F(CopyInfoTest, constructors)
149 {
150  List<Item> inserted_columns;
151 
152  COPY_INFO insert(COPY_INFO::INSERT_OPERATION,
153  &inserted_columns,
154  true, // manage_defaults
155  DUP_UPDATE,
156  true);
157 
158  EXPECT_EQ(0U, insert.stats.records);
159  EXPECT_EQ(0U, insert.stats.deleted);
160  EXPECT_EQ(0U, insert.stats.updated);
161  EXPECT_EQ(0U, insert.stats.copied);
162  EXPECT_EQ(0U, insert.stats.error_count);
163  EXPECT_EQ(0U, insert.stats.touched);
164 
165  List<Item> columns;
166  List<Item> values;
167  COPY_INFO update(COPY_INFO::UPDATE_OPERATION, &columns, &values);
168 
169  EXPECT_EQ(0U, update.stats.records);
170  EXPECT_EQ(0U, update.stats.deleted);
171  EXPECT_EQ(0U, update.stats.updated);
172  EXPECT_EQ(0U, update.stats.copied);
173  EXPECT_EQ(0U, update.stats.error_count);
174  EXPECT_EQ(0U, update.stats.touched);
175 
176 }
177 
178 
179 /*
180  Tests the accessors when the COPY_INFO represents an insert operation.
181 */
182 TEST_F(CopyInfoTest, insertAccessors)
183 {
184  List<Item> inserted_columns;
185 
186  COPY_INFO insert(COPY_INFO::INSERT_OPERATION,
187  &inserted_columns,
188  true, // manage_defaults
189  DUP_REPLACE,
190  true);
191 
192  EXPECT_EQ(COPY_INFO::INSERT_OPERATION, insert.get_operation_type());
193  EXPECT_EQ(&inserted_columns, insert.get_changed_columns());
194  EXPECT_EQ(static_cast<List<Item>*>(NULL), insert.get_changed_columns2());
195  EXPECT_TRUE(insert.get_manage_defaults());
196  EXPECT_EQ(DUP_REPLACE, insert.get_duplicate_handling());
197  EXPECT_TRUE(insert.get_ignore_errors());
198 }
199 
200 
201 /*
202  Tests the accessors when the COPY_INFO represents a load data infile
203  operation.
204 */
205 TEST_F(CopyInfoTest, loadDataAccessors)
206 {
207  List<Item> inserted_columns;
208  List<Item> inserted_columns2;
209 
210  COPY_INFO load_data(COPY_INFO::INSERT_OPERATION,
211  &inserted_columns,
212  &inserted_columns2,
213  true, // manage_defaults
214  DUP_UPDATE,
215  true, // ignore_duplicates
216  123);
217 
218  EXPECT_EQ(COPY_INFO::INSERT_OPERATION, load_data.get_operation_type());
219  EXPECT_EQ(&inserted_columns, load_data.get_changed_columns());
220  EXPECT_EQ(&inserted_columns2, load_data.get_changed_columns2());
221  EXPECT_TRUE(load_data.get_manage_defaults());
222  EXPECT_EQ(DUP_UPDATE, load_data.get_duplicate_handling());
223  EXPECT_TRUE(load_data.get_ignore_errors());
224 }
225 
226 
227 /*
228  Tests the accessors when the COPY_INFO represents an update operation.
229 */
230 TEST_F(CopyInfoTest, updateAccessors)
231 {
232  List<Item> columns;
233  List<Item> values;
234 
235  COPY_INFO update(COPY_INFO::UPDATE_OPERATION, &columns, &values);
236 
237  EXPECT_EQ(COPY_INFO::UPDATE_OPERATION, update.get_operation_type());
238  EXPECT_EQ(&columns, update.get_changed_columns());
239  EXPECT_EQ(static_cast<List<Item>*>(NULL), update.get_changed_columns2());
240  EXPECT_TRUE(update.get_manage_defaults());
241  EXPECT_EQ(DUP_ERROR, update.get_duplicate_handling());
242  EXPECT_FALSE(update.get_ignore_errors());
243 }
244 
245 
246 Field_long make_field()
247 {
248  static uchar unused_null_byte;
249 
250  Field_long a(NULL,
251  0,
252  &unused_null_byte,
253  0,
254  Field::TIMESTAMP_DN_FIELD,
255  "a",
256  false,
257  false);
258  return a;
259 }
260 
261 
262 /*
263  Test of the lazy instantiation performed by get_function_default_columns().
264 
265  - The bitmap pointer is initially NULL.
266 
267  - That calling get_function_default_columns() indeed points the member to a
268  lazily instantiated bitmap.
269 
270  - That on a second call to get_function_default_columns(), a new bitmap is
271  not allocated.
272 
273  We repeat the test for insert and update operations.
274 */
275 TEST_F(CopyInfoTest, getFunctionDefaultColumns)
276 {
277  Mock_COPY_INFO_insert insert;
278  Mock_COPY_INFO_update update;
279 
280  Field_long a= make_field();
281  Fake_TABLE table(&a);
282 
283  MY_BITMAP *initial_value= NULL;
284 
285  EXPECT_EQ(initial_value, insert.get_cached_bitmap());
286 
287  insert.get_function_default_columns(&table);
288  EXPECT_NE(initial_value, insert.get_cached_bitmap())
289  << "The output parameter must be set!";
290 
291  const MY_BITMAP *function_default_columns= insert.get_cached_bitmap();
292  insert.get_function_default_columns(&table);
293  EXPECT_EQ(function_default_columns, insert.get_cached_bitmap())
294  << "Not supposed to allocate a new bitmap on second call.";
295 
296  EXPECT_EQ(initial_value, update.get_cached_bitmap());
297  update.get_function_default_columns(&table);
298  EXPECT_NE(initial_value, update.get_cached_bitmap())
299  << "The output parameter must be set!";
300 
301  function_default_columns= update.get_cached_bitmap();
302  update.get_function_default_columns(&table);
303  EXPECT_EQ(function_default_columns, update.get_cached_bitmap())
304  << "Not supposed to allocate a new bitmap on second call.";
305 }
306 
307 
308 /*
309  Here we test that calling COPY_INFO::set_function_defaults() indeed causes
310  store_timestamp to be called on the columns that are not on the list of
311  assigned_columns. We seize the opportunity to test
312  COPY_INFO::function_defaults_apply() since we have to call it anyways in
313  order for set_function_defaults() not to assert.
314 */
315 TEST_F(CopyInfoTest, setFunctionDefaults)
316 {
317  StrictMock<Mock_field> a(Field::TIMESTAMP_UN_FIELD);
318  StrictMock<Mock_field> b(Field::TIMESTAMP_DNUN_FIELD);
319  StrictMock<Mock_field> c(Field::TIMESTAMP_DNUN_FIELD);
320 
321  EXPECT_TRUE(a.has_update_default_function());
322  EXPECT_TRUE(b.has_update_default_function());
323  EXPECT_TRUE(c.has_update_default_function());
324 
325  Fake_TABLE table(&a, &b, &c);
326 
327  List<Item> assigned_columns;
328  assigned_columns.push_front(new Item_field(&a));
329 
330  Mock_COPY_INFO insert(COPY_INFO::INSERT_OPERATION,
331  &assigned_columns,
332  DUP_ERROR,
333  true);
334 
335  ASSERT_FALSE(insert.get_function_default_columns(&table)) << "Out of memory";
336 
337  insert.ignore_last_columns(&table, 1); // 'c'
338  insert.add_function_default_columns(&table, table.write_set);
339  EXPECT_FALSE(bitmap_is_set(table.write_set, 0));
340  EXPECT_TRUE (bitmap_is_set(table.write_set, 1));
341  EXPECT_FALSE(bitmap_is_set(table.write_set, 2));
342 
343  EXPECT_TRUE(insert.function_defaults_apply(&table)) << "They do apply";
344 
345  // We expect store_timestamp() to be called for b and not for c.
346  // We do not care about the argument to store_timestamp().
347  EXPECT_CALL(b, store_timestamp(_)).Times(1);
348  EXPECT_CALL(c, store_timestamp(_)).Times(0);
349  insert.set_function_defaults(&table);
350 }
351 
352 }