diff options
author | Sergei Golubchik <serg@mariadb.org> | 2018-05-14 10:47:13 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2018-05-17 15:33:39 +0200 |
commit | dfd6702a29643e8f3d875b4d67bcf021714432a5 (patch) | |
tree | e87d1a05899bd668536e3d174fee5fb361bb0627 /storage | |
parent | 28dbdf3d79cfd39ffa2e1d087662ac82c9281d1d (diff) | |
download | mariadb-git-dfd6702a29643e8f3d875b4d67bcf021714432a5.tar.gz |
MDEV-16157 federated corrupts timestamps
do "set time_zone='+00:00'" on remote server
after connecting.
temporarily reset local time zone to my_tz_OFFSET0
whenever Field::val_str() or Field::store()
methods are used.
Diffstat (limited to 'storage')
-rw-r--r-- | storage/federatedx/federatedx_io_mysql.cc | 3 | ||||
-rw-r--r-- | storage/federatedx/ha_federatedx.cc | 25 |
2 files changed, 27 insertions, 1 deletions
diff --git a/storage/federatedx/federatedx_io_mysql.cc b/storage/federatedx/federatedx_io_mysql.cc index a83e54513d3..cc4d8ca7c70 100644 --- a/storage/federatedx/federatedx_io_mysql.cc +++ b/storage/federatedx/federatedx_io_mysql.cc @@ -453,7 +453,8 @@ int federatedx_io_mysql::actual_query(const char *buffer, size_t length) mysql.reconnect= 1; } - error= mysql_real_query(&mysql, buffer, (ulong)length); + if (!(error= mysql_real_query(&mysql, STRING_WITH_LEN("set time_zone='+00:00'")))) + error= mysql_real_query(&mysql, buffer, (ulong)length); DBUG_RETURN(error); } diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc index 8c21906fe84..8f793230926 100644 --- a/storage/federatedx/ha_federatedx.cc +++ b/storage/federatedx/ha_federatedx.cc @@ -318,6 +318,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "sql_servers.h" #include "sql_analyse.h" // append_escaped() #include "sql_show.h" // append_identifier() +#include "tztime.h" // my_tz_find() #ifdef I_AM_PARANOID #define MIN_PORT 1023 @@ -340,6 +341,8 @@ static const uint sizeof_trailing_comma= sizeof(", ") - 1; static const uint sizeof_trailing_and= sizeof(" AND ") - 1; static const uint sizeof_trailing_where= sizeof(" WHERE ") - 1; +static Time_zone *UTC= 0; + /* Static declaration for handerton */ static handler *federatedx_create_handler(handlerton *hton, TABLE_SHARE *table, @@ -860,8 +863,10 @@ uint ha_federatedx::convert_row_to_internal_format(uchar *record, Field **field; int column= 0; my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set); + Time_zone *saved_time_zone= table->in_use->variables.time_zone; DBUG_ENTER("ha_federatedx::convert_row_to_internal_format"); + table->in_use->variables.time_zone= UTC; lengths= io->fetch_lengths(result); for (field= table->field; *field; field++, column++) @@ -885,6 +890,7 @@ uint ha_federatedx::convert_row_to_internal_format(uchar *record, } (*field)->move_field_offset(-old_ptr); } + table->in_use->variables.time_zone= saved_time_zone; dbug_tmp_restore_column_map(table->write_set, old_map); DBUG_RETURN(0); } @@ -1213,6 +1219,7 @@ bool ha_federatedx::create_where_from_key(String *to, char tmpbuff[FEDERATEDX_QUERY_BUFFER_SIZE]; String tmp(tmpbuff, sizeof(tmpbuff), system_charset_info); const key_range *ranges[2]= { start_key, end_key }; + Time_zone *saved_time_zone= table->in_use->variables.time_zone; my_bitmap_map *old_map; DBUG_ENTER("ha_federatedx::create_where_from_key"); @@ -1220,6 +1227,7 @@ bool ha_federatedx::create_where_from_key(String *to, if (start_key == NULL && end_key == NULL) DBUG_RETURN(1); + table->in_use->variables.time_zone= UTC; old_map= dbug_tmp_use_all_columns(table, table->write_set); for (uint i= 0; i <= 1; i++) { @@ -1397,6 +1405,7 @@ prepare_for_next_key_part: } } dbug_tmp_restore_column_map(table->write_set, old_map); + table->in_use->variables.time_zone= saved_time_zone; if (both_not_null) if (tmp.append(STRING_WITH_LEN(") "))) @@ -1412,6 +1421,7 @@ prepare_for_next_key_part: err: dbug_tmp_restore_column_map(table->write_set, old_map); + table->in_use->variables.time_zone= saved_time_zone; DBUG_RETURN(1); } @@ -1582,6 +1592,12 @@ static FEDERATEDX_SHARE *get_share(const char *table_name, TABLE *table) mysql_mutex_lock(&federatedx_mutex); + if (unlikely(!UTC)) + { + String tz_00_name(STRING_WITH_LEN("+00:00"), &my_charset_bin); + UTC= my_tz_find(current_thd, &tz_00_name); + } + tmp_share.share_key= table_name; tmp_share.share_key_length= (int)strlen(table_name); if (parse_url(&mem_root, &tmp_share, table->s, 0)) @@ -1978,9 +1994,11 @@ int ha_federatedx::write_row(uchar *buf) String insert_field_value_string(insert_field_value_buffer, sizeof(insert_field_value_buffer), &my_charset_bin); + Time_zone *saved_time_zone= table->in_use->variables.time_zone; my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set); DBUG_ENTER("ha_federatedx::write_row"); + table->in_use->variables.time_zone= UTC; values_string.length(0); insert_field_value_string.length(0); @@ -2033,6 +2051,7 @@ int ha_federatedx::write_row(uchar *buf) } } dbug_tmp_restore_column_map(table->read_set, old_map); + table->in_use->variables.time_zone= saved_time_zone; /* if there were no fields, we don't want to add a closing paren @@ -2340,6 +2359,8 @@ int ha_federatedx::update_row(const uchar *old_data, const uchar *new_data) field=oldvalue */ + Time_zone *saved_time_zone= table->in_use->variables.time_zone; + table->in_use->variables.time_zone= UTC; for (Field **field= table->field; *field; field++) { if (bitmap_is_set(table->write_set, (*field)->field_index)) @@ -2391,6 +2412,7 @@ int ha_federatedx::update_row(const uchar *old_data, const uchar *new_data) where_string.append(STRING_WITH_LEN(" AND ")); } } + table->in_use->variables.time_zone= saved_time_zone; /* Remove last ', '. This works as there must be at least on updated field */ update_string.length(update_string.length() - sizeof_trailing_comma); @@ -2451,6 +2473,8 @@ int ha_federatedx::delete_row(const uchar *buf) share->table_name_length, ident_quote_char); delete_string.append(STRING_WITH_LEN(" WHERE ")); + Time_zone *saved_time_zone= table->in_use->variables.time_zone; + table->in_use->variables.time_zone= UTC; for (Field **field= table->field; *field; field++) { Field *cur_field= *field; @@ -2478,6 +2502,7 @@ int ha_federatedx::delete_row(const uchar *buf) delete_string.append(STRING_WITH_LEN(" AND ")); } } + table->in_use->variables.time_zone= saved_time_zone; // Remove trailing AND delete_string.length(delete_string.length() - sizeof_trailing_and); |