mysql5/mysql-5.7.27/unittest/gunit/item_func_now_local-t.cc

164 lines
4.9 KiB
C++

/* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
// First include (the generated) my_config.h, to get correct platform defines.
#include "my_config.h"
#include <gtest/gtest.h>
#include "mock_field_datetime.h"
#include "mock_field_timestamp.h"
#include "mock_field_timestampf.h"
#include "test_utils.h"
#include "item.h"
#include "item_timefunc.h"
#include "sql_class.h"
#include "rpl_handler.h" // delegates_init()
#include "tztime.h"
namespace item_func_now_local_unittest {
using my_testing::Server_initializer;
using my_testing::Mock_error_handler;
const int CURRENT_TIMESTAMP_WHOLE_SECONDS= 123456;
const int CURRENT_TIMESTAMP_FRACTIONAL_SECONDS= 654321;
/*
Test of the interface of Item_func_now_local.
*/
class ItemFuncNowLocalTest : public ::testing::Test
{
protected:
virtual void SetUp()
{
initializer.SetUp();
timeval now=
{
CURRENT_TIMESTAMP_WHOLE_SECONDS, CURRENT_TIMESTAMP_FRACTIONAL_SECONDS
};
get_thd()->set_time(&now);
}
virtual void TearDown() { initializer.TearDown(); }
THD *get_thd() { return initializer.thd(); }
Server_initializer initializer;
};
/*
Tests that the THD start time is stored correctly in a Field_timestamp using
the Item::save_in_field() interface.
*/
TEST_F(ItemFuncNowLocalTest, saveInField)
{
Item_func_now_local *item= new Item_func_now_local(0);
Mock_field_timestamp f;
item->fix_length_and_dec();
f.make_writable();
item->save_in_field(&f, true);
EXPECT_EQ(get_thd()->query_start_timeval().tv_sec, f.to_timeval().tv_sec);
// CURRENT_TIMESTAMP should truncate.
EXPECT_EQ(0, f.to_timeval().tv_usec);
}
/*
Tests that Item_func_now_local::store_in() goes through the optimized
interface Field::store_timestamp() on a Field_timestamp.
*/
TEST_F(ItemFuncNowLocalTest, storeInTimestamp)
{
Mock_field_timestamp f;
Item_func_now_local::store_in(&f);
EXPECT_EQ(get_thd()->query_start_timeval().tv_sec, f.to_timeval().tv_sec);
// CURRENT_TIMESTAMP should truncate.
EXPECT_EQ(0, f.to_timeval().tv_usec);
EXPECT_TRUE(f.store_timestamp_called);
}
int powers_of_10[DATETIME_MAX_DECIMALS + 1] =
{ 1, 10, 100, 1000, 10000, 100000, 1000000 };
/*
Truncates the number n to a precision of ( DATETIME_MAX_DECIMALS - scale ).
*/
int truncate(int n, int scale)
{
EXPECT_TRUE(scale >= 0);
EXPECT_TRUE(scale <= DATETIME_MAX_DECIMALS);
return (n / powers_of_10[DATETIME_MAX_DECIMALS - scale]) *
powers_of_10[DATETIME_MAX_DECIMALS - scale];
}
/*
Tests that Item_func_now_local::store_in() goes through the optimized
interface Field_temporal_with_date_and_time::store_timestamp_internal() on a
Field_timestampf.
We also test that the CURRENT_TIMESTAMP value gets truncated, not rounded.
*/
TEST_F(ItemFuncNowLocalTest, storeInTimestampf)
{
for(ulong scale= 0; scale <= DATETIME_MAX_DECIMALS; ++scale)
{
Mock_field_timestampf f(Field::NONE, scale);
f.make_writable();
Item_func_now_local::store_in(&f);
EXPECT_EQ(get_thd()->query_start_timeval().tv_sec, f.to_timeval().tv_sec);
// CURRENT_TIMESTAMP should truncate.
EXPECT_EQ(truncate(CURRENT_TIMESTAMP_FRACTIONAL_SECONDS, scale),
f.to_timeval().tv_usec);
EXPECT_TRUE(f.store_timestamp_internal_called);
}
}
/*
Tests that Item_func_now_local::store_in() works correctly even though it does
not use the optimized interface.
*/
TEST_F(ItemFuncNowLocalTest, storeInDatetime)
{
Mock_field_datetime f;
MYSQL_TIME now_time;
THD *thd= get_thd();
timeval now= { 1313677243, 1234 }; // Thu Aug 18 16:20:43 CEST 2011 and 1234 ms
thd->set_time(&now);
Item_func_now_local::store_in(&f);
thd->variables.time_zone->gmt_sec_to_TIME(&now_time, thd->start_time);
MYSQL_TIME stored_time;
f.get_time(&stored_time);
EXPECT_EQ(now_time.year, stored_time.year);
EXPECT_EQ(now_time.month, stored_time.month);
EXPECT_EQ(now_time.day, stored_time.day);
EXPECT_EQ(now_time.hour, stored_time.hour);
EXPECT_EQ(now_time.minute, stored_time.minute);
EXPECT_EQ(now_time.second, stored_time.second);
// CURRENT_TIMESTAMP truncates.
EXPECT_EQ(0u, stored_time.second_part);
EXPECT_EQ(now_time.neg, stored_time.neg);
EXPECT_EQ(now_time.time_type, stored_time.time_type);
}
}