MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
item_func_now_local-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 #include "my_config.h"
18 #include <gtest/gtest.h>
19 
20 #include "mock_field_datetime.h"
21 #include "mock_field_timestamp.h"
22 #include "mock_field_timestampf.h"
23 #include "test_utils.h"
24 #include "item.h"
25 #include "sql_class.h"
26 #include "rpl_handler.h" // delegates_init()
27 #include "tztime.h"
28 
29 namespace item_func_now_local_unittest {
30 
33 
34 const int CURRENT_TIMESTAMP_WHOLE_SECONDS= 123456;
35 const int CURRENT_TIMESTAMP_FRACTIONAL_SECONDS= 654321;
36 
37 /*
38  Test of the interface of Item_func_now_local.
39  */
40 class ItemFuncNowLocalTest : public ::testing::Test
41 {
42 protected:
43  virtual void SetUp()
44  {
45  initializer.SetUp();
46  timeval now=
47  {
48  CURRENT_TIMESTAMP_WHOLE_SECONDS, CURRENT_TIMESTAMP_FRACTIONAL_SECONDS
49  };
50  get_thd()->set_time(&now);
51  }
52 
53  virtual void TearDown() { initializer.TearDown(); }
54 
55  THD *get_thd() { return initializer.thd(); }
56 
57  Server_initializer initializer;
58 };
59 
60 
61 /*
62  Tests that the THD start time is stored correctly in a Field_timestamp using
63  the Item::save_in_field() interface.
64 */
65 TEST_F(ItemFuncNowLocalTest, saveInField)
66 {
69 
70  item->fix_length_and_dec();
71  f.make_writable();
72  item->save_in_field(&f, true);
73 
74  EXPECT_EQ(get_thd()->query_start_timeval().tv_sec, f.to_timeval().tv_sec);
75  // CURRENT_TIMESTAMP should truncate.
76  EXPECT_EQ(0, f.to_timeval().tv_usec);
77 }
78 
79 
80 /*
81  Tests that Item_func_now_local::store_in() goes through the optimized
82  interface Field::store_timestamp() on a Field_timestamp.
83 */
84 TEST_F(ItemFuncNowLocalTest, storeInTimestamp)
85 {
88 
89  EXPECT_EQ(get_thd()->query_start_timeval().tv_sec, f.to_timeval().tv_sec);
90  // CURRENT_TIMESTAMP should truncate.
91  EXPECT_EQ(0, f.to_timeval().tv_usec);
92  EXPECT_TRUE(f.store_timestamp_called);
93 }
94 
95 int powers_of_10[DATETIME_MAX_DECIMALS + 1] =
96 { 1, 10, 100, 1000, 10000, 100000, 1000000 };
97 
98 /*
99  Truncates the number n to a precision of ( DATETIME_MAX_DECIMALS - scale ).
100 */
101 int truncate(int n, int scale)
102 {
103  EXPECT_TRUE(scale >= 0);
104  EXPECT_TRUE(scale <= DATETIME_MAX_DECIMALS);
105  return (n / powers_of_10[DATETIME_MAX_DECIMALS - scale]) *
106  powers_of_10[DATETIME_MAX_DECIMALS - scale];
107 }
108 
109 /*
110  Tests that Item_func_now_local::store_in() goes through the optimized
111  interface Field_temporal_with_date_and_time::store_timestamp_internal() on a
112  Field_timestampf.
113 
114  We also test that the CURRENT_TIMESTAMP value gets truncated, not rounded.
115 */
116 TEST_F(ItemFuncNowLocalTest, storeInTimestampf)
117 {
118  for(ulong scale= 0; scale <= DATETIME_MAX_DECIMALS; ++scale)
119  {
120  Mock_field_timestampf f(Field::NONE, scale);
121  f.make_writable();
123 
124  EXPECT_EQ(get_thd()->query_start_timeval().tv_sec, f.to_timeval().tv_sec);
125  // CURRENT_TIMESTAMP should truncate.
126  EXPECT_EQ(truncate(CURRENT_TIMESTAMP_FRACTIONAL_SECONDS, scale),
127  f.to_timeval().tv_usec);
128  EXPECT_TRUE(f.store_timestamp_internal_called);
129  }
130 }
131 
132 
133 /*
134  Tests that Item_func_now_local::store_in() works correctly even though it does
135  not use the optimized interface.
136 */
137 TEST_F(ItemFuncNowLocalTest, storeInDatetime)
138 {
140  MYSQL_TIME now_time;
141  THD *thd= get_thd();
142  timeval now= { 1313677243, 1234 }; // Thu Aug 18 16:20:43 CEST 2011 and 1234 ms
143  thd->set_time(&now);
144 
146  thd->variables.time_zone->gmt_sec_to_TIME(&now_time, thd->start_time);
147  MYSQL_TIME stored_time;
148  f.get_time(&stored_time);
149 
150  EXPECT_EQ(now_time.year, stored_time.year);
151  EXPECT_EQ(now_time.month, stored_time.month);
152  EXPECT_EQ(now_time.day, stored_time.day);
153  EXPECT_EQ(now_time.hour, stored_time.hour);
154  EXPECT_EQ(now_time.minute, stored_time.minute);
155  EXPECT_EQ(now_time.second, stored_time.second);
156  // CURRENT_TIMESTAMP truncates.
157  EXPECT_EQ(0u, stored_time.second_part);
158  EXPECT_EQ(now_time.neg, stored_time.neg);
159  EXPECT_EQ(now_time.time_type, stored_time.time_type);
160 }
161 
162 }