From 32bd0c7d1fd3e996bf4431ed2c2e22cc1bcde4cd Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 24 May 2013 19:09:59 +0400 Subject: Adding the timezone plugin service, to convert between MYSQL_TIME and my_time_t and back. Using the new service instead of direct access to thd. added: include/mysql/service_thd_timezone.h libservices/thd_timezone_service.c modified: include/my_time.h include/mysql.h.pp include/mysql/plugin.h include/mysql/plugin_audit.h.pp include/mysql/plugin_auth.h.pp include/mysql/plugin_ftparser.h.pp include/mysql/services.h include/mysql_time.h include/service_versions.h libservices/CMakeLists.txt sql/sql_class.cc sql/sql_plugin_services.h storage/connect/value.cpp --- include/my_time.h | 10 ----- include/mysql.h.pp | 1 + include/mysql/plugin.h | 2 +- include/mysql/plugin_audit.h.pp | 22 +++++++++++ include/mysql/plugin_auth.h.pp | 22 +++++++++++ include/mysql/plugin_ftparser.h.pp | 22 +++++++++++ include/mysql/service_thd_timezone.h | 74 ++++++++++++++++++++++++++++++++++++ include/mysql/services.h | 1 + include/mysql_time.h | 11 ++++++ include/service_versions.h | 2 +- libservices/CMakeLists.txt | 1 + libservices/thd_timezone_service.c | 18 +++++++++ sql/sql_class.cc | 21 ++++++++++ sql/sql_plugin_services.h | 8 +++- storage/connect/value.cpp | 5 +-- 15 files changed, 203 insertions(+), 17 deletions(-) create mode 100644 include/mysql/service_thd_timezone.h create mode 100644 libservices/thd_timezone_service.c diff --git a/include/my_time.h b/include/my_time.h index 9bd545bb850..046b5c94923 100644 --- a/include/my_time.h +++ b/include/my_time.h @@ -29,16 +29,6 @@ C_MODE_START extern ulonglong log_10_int[20]; extern uchar days_in_month[]; -/* - Portable time_t replacement. - Should be signed and hold seconds for 1902 -- 2038-01-19 range - i.e at least a 32bit variable - - Using the system built in time_t is not an option as - we rely on the above requirements in the time functions -*/ -typedef long my_time_t; - #define MY_TIME_T_MAX LONG_MAX #define MY_TIME_T_MIN LONG_MIN diff --git a/include/mysql.h.pp b/include/mysql.h.pp index d33822b2021..02eb62655df 100644 --- a/include/mysql.h.pp +++ b/include/mysql.h.pp @@ -143,6 +143,7 @@ const char *mysql_errno_to_sqlstate(unsigned int mysql_errno); my_bool my_thread_init(void); void my_thread_end(void); #include "mysql_time.h" +typedef long my_time_t; enum enum_mysql_timestamp_type { MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1, diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h index 38573180232..db9b8e2aa9a 100644 --- a/include/mysql/plugin.h +++ b/include/mysql/plugin.h @@ -72,7 +72,7 @@ typedef struct st_mysql_xid MYSQL_XID; #define MYSQL_PLUGIN_INTERFACE_VERSION 0x0103 /* MariaDB plugin interface version */ -#define MARIA_PLUGIN_INTERFACE_VERSION 0x0104 +#define MARIA_PLUGIN_INTERFACE_VERSION 0x0105 /* The allowable types of plugins diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index 1c4b46c2a01..8592eb9f852 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -85,6 +85,28 @@ extern struct kill_statement_service_st { enum thd_kill_levels (*thd_kill_level_func)(const void*); } *thd_kill_statement_service; enum thd_kill_levels thd_kill_level(const void*); +#include +typedef char my_bool; +#include "mysql_time.h" +typedef long my_time_t; +enum enum_mysql_timestamp_type +{ + MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1, + MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2 +}; +typedef struct st_mysql_time +{ + unsigned int year, month, day, hour, minute, second; + unsigned long second_part; + my_bool neg; + enum enum_mysql_timestamp_type time_type; +} MYSQL_TIME; +extern struct thd_timezone_service_st { + my_time_t (*thd_TIME_to_gmt_sec)(void* thd, const MYSQL_TIME *ltime, unsigned int *errcode); + void (*thd_gmt_sec_to_TIME)(void* thd, MYSQL_TIME *ltime, my_time_t t); +} *thd_timezone_service; +my_time_t thd_TIME_to_gmt_sec(void* thd, const MYSQL_TIME *ltime, uint *errcode); +void thd_gmt_sec_to_TIME(void* thd, MYSQL_TIME *ltime, my_time_t t); struct st_mysql_xid { long formatID; long gtrid_length; diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp index ac6e5e3b13d..81b717acc8f 100644 --- a/include/mysql/plugin_auth.h.pp +++ b/include/mysql/plugin_auth.h.pp @@ -85,6 +85,28 @@ extern struct kill_statement_service_st { enum thd_kill_levels (*thd_kill_level_func)(const void*); } *thd_kill_statement_service; enum thd_kill_levels thd_kill_level(const void*); +#include +typedef char my_bool; +#include "mysql_time.h" +typedef long my_time_t; +enum enum_mysql_timestamp_type +{ + MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1, + MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2 +}; +typedef struct st_mysql_time +{ + unsigned int year, month, day, hour, minute, second; + unsigned long second_part; + my_bool neg; + enum enum_mysql_timestamp_type time_type; +} MYSQL_TIME; +extern struct thd_timezone_service_st { + my_time_t (*thd_TIME_to_gmt_sec)(void* thd, const MYSQL_TIME *ltime, unsigned int *errcode); + void (*thd_gmt_sec_to_TIME)(void* thd, MYSQL_TIME *ltime, my_time_t t); +} *thd_timezone_service; +my_time_t thd_TIME_to_gmt_sec(void* thd, const MYSQL_TIME *ltime, uint *errcode); +void thd_gmt_sec_to_TIME(void* thd, MYSQL_TIME *ltime, my_time_t t); struct st_mysql_xid { long formatID; long gtrid_length; diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp index f5d6ac3b849..f28a508d62b 100644 --- a/include/mysql/plugin_ftparser.h.pp +++ b/include/mysql/plugin_ftparser.h.pp @@ -85,6 +85,28 @@ extern struct kill_statement_service_st { enum thd_kill_levels (*thd_kill_level_func)(const void*); } *thd_kill_statement_service; enum thd_kill_levels thd_kill_level(const void*); +#include +typedef char my_bool; +#include "mysql_time.h" +typedef long my_time_t; +enum enum_mysql_timestamp_type +{ + MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1, + MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2 +}; +typedef struct st_mysql_time +{ + unsigned int year, month, day, hour, minute, second; + unsigned long second_part; + my_bool neg; + enum enum_mysql_timestamp_type time_type; +} MYSQL_TIME; +extern struct thd_timezone_service_st { + my_time_t (*thd_TIME_to_gmt_sec)(void* thd, const MYSQL_TIME *ltime, unsigned int *errcode); + void (*thd_gmt_sec_to_TIME)(void* thd, MYSQL_TIME *ltime, my_time_t t); +} *thd_timezone_service; +my_time_t thd_TIME_to_gmt_sec(void* thd, const MYSQL_TIME *ltime, uint *errcode); +void thd_gmt_sec_to_TIME(void* thd, MYSQL_TIME *ltime, my_time_t t); struct st_mysql_xid { long formatID; long gtrid_length; diff --git a/include/mysql/service_thd_timezone.h b/include/mysql/service_thd_timezone.h new file mode 100644 index 00000000000..e6d92e73ece --- /dev/null +++ b/include/mysql/service_thd_timezone.h @@ -0,0 +1,74 @@ +#ifndef MYSQL_SERVICE_THD_TIMEZONE_INCLUDED +/* Copyright (C) 2013 MariaDB Foundation. + + 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, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +/** + @file + This service provdes functions to convert between my_time_t and + MYSQL_TIME taking into account the current value of the time_zone + session variable. + + The values of the my_time_t type are in Unix timestamp format, + i.e. the number of seconds since "1970-01-01 00:00:00 UTC". + + The values of the MYSQL_TIME type are in the current time zone, + according to thd->variables.time_zone. + + If the MYSQL_THD parameter is NULL, then global_system_variables.time_zone + is used for conversion. +*/ + +#ifndef MYSQL_ABI_CHECK +/* + This service currently does not depend on any system headers. + If it needs system headers in the future, make sure to put + them inside this ifndef. +*/ +#endif + +typedef char my_bool; +#include "mysql_time.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +extern struct thd_timezone_service_st { + my_time_t (*thd_TIME_to_gmt_sec)(MYSQL_THD thd, const MYSQL_TIME *ltime, unsigned int *errcode); + void (*thd_gmt_sec_to_TIME)(MYSQL_THD thd, MYSQL_TIME *ltime, my_time_t t); +} *thd_timezone_service; + +#ifdef MYSQL_DYNAMIC_PLUGIN + +#define thd_TIME_to_gmt_sec(thd, ltime, errcode) \ + (thd_timezone_service->thd_TIME_to_gmt_sec((thd), (ltime), (errcode))) + +#define thd_gmt_sec_to_TIME(thd, ltime, t) \ + (thd_timezone_service->thd_gmt_sec_to_TIME((thd), (ltime), (t))) + +#else + +my_time_t thd_TIME_to_gmt_sec(MYSQL_THD thd, const MYSQL_TIME *ltime, uint *errcode); +void thd_gmt_sec_to_TIME(MYSQL_THD thd, MYSQL_TIME *ltime, my_time_t t); + +#endif + +#ifdef __cplusplus +} +#endif + +#define MYSQL_SERVICE_THD_TIMEZONE_INCLUDED +#endif diff --git a/include/mysql/services.h b/include/mysql/services.h index e14523f4fa1..1145d19872b 100644 --- a/include/mysql/services.h +++ b/include/mysql/services.h @@ -25,6 +25,7 @@ extern "C" { #include #include #include +#include #ifdef __cplusplus } diff --git a/include/mysql_time.h b/include/mysql_time.h index 0a3f17a81fb..baa236e891e 100644 --- a/include/mysql_time.h +++ b/include/mysql_time.h @@ -16,6 +16,17 @@ #ifndef _mysql_time_h_ #define _mysql_time_h_ +/* + Portable time_t replacement. + Should be signed and hold seconds for 1902 -- 2038-01-19 range + i.e at least a 32bit variable + + Using the system built in time_t is not an option as + we rely on the above requirements in the time functions +*/ +typedef long my_time_t; + + /* Time declarations shared between the server and client API: you should not add anything to this header unless it's used diff --git a/include/service_versions.h b/include/service_versions.h index e0a717fea9e..2dffa7cf863 100644 --- a/include/service_versions.h +++ b/include/service_versions.h @@ -26,4 +26,4 @@ #define VERSION_progress_report 0x0100 #define VERSION_debug_sync 0x1000 #define VERSION_kill_statement 0x1000 - +#define VERSION_thd_timezone 0x0100 diff --git a/libservices/CMakeLists.txt b/libservices/CMakeLists.txt index 86ed3493993..e7dcf20e547 100644 --- a/libservices/CMakeLists.txt +++ b/libservices/CMakeLists.txt @@ -19,6 +19,7 @@ SET(MYSQLSERVICES_SOURCES my_snprintf_service.c thd_alloc_service.c thd_wait_service.c + thd_timezone_service.c progress_report_service.c debug_sync_service.c kill_statement_service.c) diff --git a/libservices/thd_timezone_service.c b/libservices/thd_timezone_service.c new file mode 100644 index 00000000000..2c93453f8ca --- /dev/null +++ b/libservices/thd_timezone_service.c @@ -0,0 +1,18 @@ +/* Copyright (C) 2013 MariaDB Foundation + Use is subject to license terms. + + 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, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include +SERVICE_VERSION thd_timezone_service= (void *) VERSION_thd_timezone; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 238bf46e528..016cff9c2d9 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -35,6 +35,7 @@ #include "sql_cache.h" // query_cache_abort #include "sql_base.h" // close_thread_tables #include "sql_time.h" // date_time_format_copy +#include "tztime.h" // MYSQL_TIME <-> my_time_t #include "sql_acl.h" // NO_ACCESS, // acl_getroot_no_password #include "sql_base.h" // close_temporary_tables @@ -1261,6 +1262,26 @@ void thd_get_xid(const MYSQL_THD thd, MYSQL_XID *xid) *xid = *(MYSQL_XID *) &thd->transaction.xid_state.xid; } + +extern "C" +my_time_t thd_TIME_to_gmt_sec(MYSQL_THD thd, const MYSQL_TIME *ltime, + unsigned int *errcode) +{ + Time_zone *tz= thd ? thd->variables.time_zone : + global_system_variables.time_zone; + return tz->TIME_to_gmt_sec(ltime, errcode); +} + + +extern "C" +void thd_gmt_sec_to_TIME(MYSQL_THD thd, MYSQL_TIME *ltime, my_time_t t) +{ + Time_zone *tz= thd ? thd->variables.time_zone : + global_system_variables.time_zone; + tz->gmt_sec_to_TIME(ltime, t); +} + + #ifdef _WIN32 extern "C" THD *_current_thd_noinline(void) { diff --git a/sql/sql_plugin_services.h b/sql/sql_plugin_services.h index d2f60a6e08c..838b994b6e8 100644 --- a/sql/sql_plugin_services.h +++ b/sql/sql_plugin_services.h @@ -54,6 +54,11 @@ static struct kill_statement_service_st thd_kill_statement_handler= { thd_kill_level }; +static struct thd_timezone_service_st thd_timezone_handler= { + thd_TIME_to_gmt_sec, + thd_gmt_sec_to_TIME +}; + static struct st_service_ref list_of_services[]= { { "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler }, @@ -61,6 +66,7 @@ static struct st_service_ref list_of_services[]= { "thd_wait_service", VERSION_thd_wait, &thd_wait_handler }, { "progress_report_service", VERSION_progress_report, &progress_report_handler }, { "debug_sync_service", VERSION_debug_sync, 0 }, // updated in plugin_init() - { "thd_kill_statement_service", VERSION_kill_statement, &thd_kill_statement_handler } + { "thd_kill_statement_service", VERSION_kill_statement, &thd_kill_statement_handler }, + { "thd_timezone_service", VERSION_thd_timezone, &thd_timezone_handler }, }; diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp index 20e8f58a61c..1c8182b6b8d 100644 --- a/storage/connect/value.cpp +++ b/storage/connect/value.cpp @@ -1224,9 +1224,6 @@ void DTVAL::SetTimeShift(void) /* though the gmtime C function. The purpose of this function is to */ /* extend the range of valid dates by accepting negative time values. */ /***********************************************************************/ -#define MYSQL_SERVER 1 -#include "tztime.h" -#include "sql_priv.h" #include "sql_class.h" #include "sql_time.h" @@ -1245,7 +1242,7 @@ static void TIME_to_localtime(struct tm *tm, const MYSQL_TIME *ltime) static struct tm *gmtime_mysql(const time_t *timep, struct tm *tm) { MYSQL_TIME ltime; - current_thd->variables.time_zone->gmt_sec_to_TIME(<ime, (my_time_t) *timep); + thd_gmt_sec_to_TIME(current_thd, <ime, (my_time_t) *timep); TIME_to_localtime(tm, <ime); return tm; } -- cgit v1.2.1