diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2018-10-30 13:22:52 +0200 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2018-10-30 13:22:52 +0200 |
commit | b0fe082b365d989fcf905e5c40c3fe60fd756858 (patch) | |
tree | 46aa5d206fd37adfce09bff6bbc95bf458167128 /sql | |
parent | 93ff64ebd7a7b2a534acc3ee8bf14cbfd8658d0f (diff) | |
parent | 2ee9343c873ad31c2dd0d2175dec2ef3b48ca5ba (diff) | |
download | mariadb-git-b0fe082b365d989fcf905e5c40c3fe60fd756858.tar.gz |
Merge remote-tracking branch 'origin/5.5-galera' into 10.0-galera
Diffstat (limited to 'sql')
-rw-r--r-- | sql/CMakeLists.txt | 4 | ||||
-rw-r--r-- | sql/field.cc | 3 | ||||
-rw-r--r-- | sql/field_conv.cc | 2 | ||||
-rw-r--r-- | sql/item.cc | 195 | ||||
-rw-r--r-- | sql/item.h | 92 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 13 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 1 | ||||
-rw-r--r-- | sql/item_func.cc | 5 | ||||
-rw-r--r-- | sql/item_func.h | 10 | ||||
-rw-r--r-- | sql/item_sum.cc | 6 | ||||
-rw-r--r-- | sql/item_sum.h | 19 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 29 | ||||
-rw-r--r-- | sql/key.cc | 3 | ||||
-rw-r--r-- | sql/log_event.cc | 70 | ||||
-rw-r--r-- | sql/mysqld.cc | 22 | ||||
-rw-r--r-- | sql/protocol.cc | 8 | ||||
-rw-r--r-- | sql/sql_acl.cc | 4 | ||||
-rw-r--r-- | sql/sql_base.cc | 14 | ||||
-rw-r--r-- | sql/sql_delete.cc | 1 | ||||
-rw-r--r-- | sql/sql_error.h | 7 | ||||
-rw-r--r-- | sql/sql_lex.cc | 2 | ||||
-rw-r--r-- | sql/sql_list.h | 5 | ||||
-rw-r--r-- | sql/sql_select.cc | 8 | ||||
-rw-r--r-- | sql/sql_show.cc | 2 | ||||
-rw-r--r-- | sql/sql_time.cc | 2 | ||||
-rw-r--r-- | sql/sql_type_int.h | 44 | ||||
-rw-r--r-- | sql/sql_update.cc | 2 | ||||
-rw-r--r-- | sql/sys_vars.cc | 13 | ||||
-rw-r--r-- | sql/table.h | 10 | ||||
-rw-r--r-- | sql/wsrep_mysqld.cc | 1 | ||||
-rw-r--r-- | sql/wsrep_mysqld.h | 2 | ||||
-rw-r--r-- | sql/wsrep_mysqld_c.h | 26 |
32 files changed, 278 insertions, 347 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 2bb68c7ec46..8187484408f 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (c) 2006, 2014, Oracle and/or its affiliates. -# Copyright (c) 2010, 2018, MariaDB +# Copyright (c) 2010, 2018, MariaDB Corporation # # 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 @@ -289,7 +289,7 @@ DTRACE_INSTRUMENT_STATIC_LIBS(mysqld SET(WITH_MYSQLD_LDFLAGS "" CACHE STRING "Additional linker flags for mysqld") MARK_AS_ADVANCED(WITH_MYSQLD_LDFLAGS) IF(WITH_MYSQLD_LDFLAGS) - GET_TARGET_PROPERTY(mysqld LINK_FLAGS MYSQLD_LINK_FLAGS) + GET_TARGET_PROPERTY(MYSQLD_LINK_FLAGS mysqld LINK_FLAGS) IF(NOT MYSQLD_LINK_FLAGS) SET(MYSQLD_LINK_FLAGS) ENDIF() diff --git a/sql/field.cc b/sql/field.cc index a9a7d54929b..2bc090e8942 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4083,7 +4083,8 @@ longlong Field_float::val_int(void) { float j; float4get(j,ptr); - return (longlong) rint(j); + bool error; + return double_to_longlong(j, false, &error); } diff --git a/sql/field_conv.cc b/sql/field_conv.cc index ec3e6c3aaaf..ae70dfd408e 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2010, 2016, MariaDB + Copyright (c) 2010, 2018, MariaDB Corporation 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 diff --git a/sql/item.cc b/sql/item.cc index 70f3e387b57..adf0335b844 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3667,7 +3667,10 @@ longlong Item_param::val_int() { switch (state) { case REAL_VALUE: - return (longlong) rint(value.real); + { + bool error; + return double_to_longlong(value.real, unsigned_flag, &error); + } case INT_VALUE: return value.integer; case DECIMAL_VALUE: @@ -4128,31 +4131,6 @@ void Item_param::make_field(Send_field *field) field->type= m_out_param_info->type; } -/**************************************************************************** - Item_copy -****************************************************************************/ - -Item_copy *Item_copy::create (Item *item) -{ - switch (item->result_type()) - { - case STRING_RESULT: - return new Item_copy_string (item); - case REAL_RESULT: - return new Item_copy_float (item); - case INT_RESULT: - return item->unsigned_flag ? - new Item_copy_uint (item) : new Item_copy_int (item); - case DECIMAL_RESULT: - return new Item_copy_decimal (item); - case TIME_RESULT: - case ROW_RESULT: - case IMPOSSIBLE_RESULT: - DBUG_ASSERT (0); - } - /* should not happen */ - return NULL; -} /**************************************************************************** Item_copy_string @@ -4210,156 +4188,6 @@ my_decimal *Item_copy_string::val_decimal(my_decimal *decimal_value) } -/**************************************************************************** - Item_copy_int -****************************************************************************/ - -void Item_copy_int::copy() -{ - cached_value= item->val_int(); - null_value=item->null_value; -} - -static int save_int_value_in_field (Field *, longlong, bool, bool); - -int Item_copy_int::save_in_field(Field *field, bool no_conversions) -{ - return save_int_value_in_field(field, cached_value, - null_value, unsigned_flag); -} - - -String *Item_copy_int::val_str(String *str) -{ - if (null_value) - return (String *) 0; - - str->set(cached_value, &my_charset_bin); - return str; -} - - -my_decimal *Item_copy_int::val_decimal(my_decimal *decimal_value) -{ - if (null_value) - return (my_decimal *) 0; - - int2my_decimal(E_DEC_FATAL_ERROR, cached_value, unsigned_flag, decimal_value); - return decimal_value; -} - - -/**************************************************************************** - Item_copy_uint -****************************************************************************/ - -String *Item_copy_uint::val_str(String *str) -{ - if (null_value) - return (String *) 0; - - str->set((ulonglong) cached_value, &my_charset_bin); - return str; -} - - -/**************************************************************************** - Item_copy_float -****************************************************************************/ - -String *Item_copy_float::val_str(String *str) -{ - if (null_value) - return (String *) 0; - else - { - double nr= val_real(); - str->set_real(nr,decimals, &my_charset_bin); - return str; - } -} - - -my_decimal *Item_copy_float::val_decimal(my_decimal *decimal_value) -{ - if (null_value) - return (my_decimal *) 0; - else - { - double nr= val_real(); - double2my_decimal(E_DEC_FATAL_ERROR, nr, decimal_value); - return decimal_value; - } -} - - -int Item_copy_float::save_in_field(Field *field, bool no_conversions) -{ - if (null_value) - return set_field_to_null(field); - field->set_notnull(); - return field->store(cached_value); -} - - -/**************************************************************************** - Item_copy_decimal -****************************************************************************/ - -int Item_copy_decimal::save_in_field(Field *field, bool no_conversions) -{ - if (null_value) - return set_field_to_null(field); - field->set_notnull(); - return field->store_decimal(&cached_value); -} - - -String *Item_copy_decimal::val_str(String *result) -{ - if (null_value) - return (String *) 0; - result->set_charset(&my_charset_bin); - my_decimal2string(E_DEC_FATAL_ERROR, &cached_value, 0, 0, 0, result); - return result; -} - - -double Item_copy_decimal::val_real() -{ - if (null_value) - return 0.0; - else - { - double result; - my_decimal2double(E_DEC_FATAL_ERROR, &cached_value, &result); - return result; - } -} - - -longlong Item_copy_decimal::val_int() -{ - if (null_value) - return 0; - else - { - longlong result; - my_decimal2int(E_DEC_FATAL_ERROR, &cached_value, unsigned_flag, &result); - return result; - } -} - - -void Item_copy_decimal::copy() -{ - my_decimal *nr= item->val_decimal(&cached_value); - if (nr && nr != &cached_value) - my_decimal2decimal (nr, &cached_value); - null_value= item->null_value; -} - - /* Functions to convert item to field (for send_result_set_metadata) */ @@ -6844,7 +6672,7 @@ Item *Item_field::update_value_transformer(uchar *select_arg) void Item_field::print(String *str, enum_query_type query_type) { if (field && field->table->const_table && - !(query_type & QT_NO_DATA_EXPANSION)) + !(query_type & (QT_NO_DATA_EXPANSION | QT_VIEW_INTERNAL))) { print_value(str); return; @@ -8707,13 +8535,11 @@ void Item_trigger_field::cleanup() Item_result item_cmp_type(Item_result a,Item_result b) { - if (a == STRING_RESULT && b == STRING_RESULT) - return STRING_RESULT; - if (a == INT_RESULT && b == INT_RESULT) - return INT_RESULT; - else if (a == ROW_RESULT || b == ROW_RESULT) + if (a == b) + return a; + if (a == ROW_RESULT || b == ROW_RESULT) return ROW_RESULT; - else if (a == TIME_RESULT || b == TIME_RESULT) + if (a == TIME_RESULT || b == TIME_RESULT) return TIME_RESULT; if ((a == INT_RESULT || a == DECIMAL_RESULT) && (b == INT_RESULT || b == DECIMAL_RESULT)) @@ -9224,7 +9050,8 @@ longlong Item_cache_real::val_int() DBUG_ASSERT(fixed == 1); if (!has_value()) return 0; - return (longlong) rint(value); + bool error; + return double_to_longlong(value, unsigned_flag, &error); } diff --git a/sql/item.h b/sql/item.h index 7c95239b242..5bcdc45ce23 100644 --- a/sql/item.h +++ b/sql/item.h @@ -4027,7 +4027,7 @@ public: Base class to implement typed value caching Item classes Item_copy_ classes are very similar to the corresponding Item_ - classes (e.g. Item_copy_int is similar to Item_int) but they add + classes (e.g. Item_copy_string is similar to Item_string) but they add the following additional functionality to Item_ : 1. Nullability 2. Possibility to store the value not only on instantiation time, @@ -4083,13 +4083,6 @@ protected: } public: - /** - Factory method to create the appropriate subclass dependent on the type of - the original item. - - @param item the original item. - */ - static Item_copy *create (Item *item); /** Update the cache with the value of the original item @@ -4151,89 +4144,6 @@ public: }; -class Item_copy_int : public Item_copy -{ -protected: - longlong cached_value; -public: - Item_copy_int (Item *i) : Item_copy(i) {} - int save_in_field(Field *field, bool no_conversions); - - virtual String *val_str(String*); - virtual my_decimal *val_decimal(my_decimal *); - virtual double val_real() - { - return null_value ? 0.0 : (double) cached_value; - } - virtual longlong val_int() - { - return null_value ? 0 : cached_value; - } - virtual void copy(); -}; - - -class Item_copy_uint : public Item_copy_int -{ -public: - Item_copy_uint (Item *item) : Item_copy_int(item) - { - unsigned_flag= 1; - } - - String *val_str(String*); - double val_real() - { - return null_value ? 0.0 : (double) (ulonglong) cached_value; - } -}; - - -class Item_copy_float : public Item_copy -{ -protected: - double cached_value; -public: - Item_copy_float (Item *i) : Item_copy(i) {} - int save_in_field(Field *field, bool no_conversions); - - String *val_str(String*); - my_decimal *val_decimal(my_decimal *); - double val_real() - { - return null_value ? 0.0 : cached_value; - } - longlong val_int() - { - return (longlong) rint(val_real()); - } - void copy() - { - cached_value= item->val_real(); - null_value= item->null_value; - } -}; - - -class Item_copy_decimal : public Item_copy -{ -protected: - my_decimal cached_value; -public: - Item_copy_decimal (Item *i) : Item_copy(i) {} - int save_in_field(Field *field, bool no_conversions); - - String *val_str(String*); - my_decimal *val_decimal(my_decimal *) - { - return null_value ? NULL: &cached_value; - } - double val_real(); - longlong val_int(); - void copy(); -}; - - /* Cached_item_XXX objects are not exactly caches. They do the following: diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 410d58bdc29..49bbee9edd2 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -4927,6 +4927,19 @@ Item *and_expressions(Item *a, Item *b, Item **org_item) } +void Item_func_isnull::print(String *str, enum_query_type query_type) +{ + str->append(func_name()); + str->append('('); + if (const_item() && !args[0]->maybe_null && + !(query_type & (QT_NO_DATA_EXPANSION | QT_VIEW_INTERNAL))) + str->append("/*always not null*/ 1"); + else + args[0]->print(str, query_type); + str->append(')'); +} + + longlong Item_func_isnull::val_int() { DBUG_ASSERT(fixed == 1); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 6cd7e0e3e78..fdefcc86c64 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1422,6 +1422,7 @@ public: const_item_cache= args[0]->const_item(); } } + virtual void print(String *str, enum_query_type query_type); table_map not_null_tables() const { return 0; } optimize_type select_optimize() const { return OPTIMIZE_NULL; } Item *neg_transformer(THD *thd); diff --git a/sql/item_func.cc b/sql/item_func.cc index 914bfa47652..3b3950e1662 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -998,7 +998,10 @@ longlong Item_func_hybrid_result_type::val_int() case INT_RESULT: return int_op(); case REAL_RESULT: - return (longlong) rint(real_op()); + { + bool error; + return double_to_longlong(real_op(), unsigned_flag, &error); + } case STRING_RESULT: { if (is_temporal_type(field_type())) diff --git a/sql/item_func.h b/sql/item_func.h index 813bcf0d023..65c10c8bad5 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -418,7 +418,11 @@ public: String *val_str(String*str); my_decimal *val_decimal(my_decimal *decimal_value); longlong val_int() - { DBUG_ASSERT(fixed == 1); return (longlong) rint(val_real()); } + { + DBUG_ASSERT(fixed == 1); + bool error; + return double_to_longlong(val_real(), unsigned_flag, &error); + } enum Item_result result_type () const { return REAL_RESULT; } void fix_length_and_dec() { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); } @@ -1477,7 +1481,9 @@ class Item_func_udf_float :public Item_udf_func longlong val_int() { DBUG_ASSERT(fixed == 1); - return (longlong) rint(Item_func_udf_float::val_real()); + bool error; + return double_to_longlong(Item_func_udf_float::val_real(), + unsigned_flag, &error); } my_decimal *val_decimal(my_decimal *dec_buf) { diff --git a/sql/item_sum.cc b/sql/item_sum.cc index fae3f2344df..1262f85c8c7 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1451,7 +1451,8 @@ longlong Item_sum_sum::val_int() &result); return result; } - return (longlong) rint(val_real()); + bool error; + return double_to_longlong(val_real(), unsigned_flag, &error); } @@ -2665,7 +2666,8 @@ double Item_avg_field::val_real() longlong Item_avg_field::val_int() { - return (longlong) rint(val_real()); + bool error; + return double_to_longlong(val_real(), unsigned_flag, &error); } diff --git a/sql/item_sum.h b/sql/item_sum.h index f4be2108e1b..47511910146 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -699,7 +699,9 @@ public: longlong val_int() { DBUG_ASSERT(fixed == 1); - return (longlong) rint(val_real()); /* Real as default */ + // Real as default + bool error; + return double_to_longlong(val_real(), unsigned_flag, &error); } String *val_str(String*str); my_decimal *val_decimal(my_decimal *); @@ -867,7 +869,11 @@ public: bool add(); double val_real(); // In SPs we might force the "wrong" type with select into a declare variable - longlong val_int() { return (longlong) rint(val_real()); } + longlong val_int() + { + bool error; + return double_to_longlong(val_real(), unsigned_flag, &error); + } my_decimal *val_decimal(my_decimal *); String *val_str(String *str); void reset_field(); @@ -904,7 +910,10 @@ public: enum Type type() const {return FIELD_VARIANCE_ITEM; } double val_real(); longlong val_int() - { /* can't be fix_fields()ed */ return (longlong) rint(val_real()); } + { /* can't be fix_fields()ed */ + bool error; + return double_to_longlong(val_real(), unsigned_flag, &error); + } String *val_str(String *str) { return val_string_from_real(str); } my_decimal *val_decimal(my_decimal *dec_buf) @@ -1215,7 +1224,9 @@ class Item_sum_udf_float :public Item_udf_sum longlong val_int() { DBUG_ASSERT(fixed == 1); - return (longlong) rint(Item_sum_udf_float::val_real()); + bool error; + return double_to_longlong(Item_sum_udf_float::val_real(), + unsigned_flag, &error); } double val_real(); String *val_str(String*str); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index c7a14049f37..cc600c8252a 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -41,6 +41,7 @@ #include "set_var.h" #include "sql_locale.h" // MY_LOCALE my_locale_en_US #include "strfunc.h" // check_word +#include "sql_type_int.h" // Longlong_hybrid #include "sql_time.h" // make_truncated_value_warning, // get_date_from_daynr, // calc_weekday, calc_week, @@ -2801,8 +2802,7 @@ bool Item_func_timediff::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) bool Item_func_maketime::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) { DBUG_ASSERT(fixed == 1); - bool overflow= 0; - longlong hour= args[0]->val_int(); + Longlong_hybrid hour(args[0]->val_int(), args[0]->unsigned_flag); longlong minute= args[1]->val_int(); ulonglong second; ulong microsecond; @@ -2814,32 +2814,23 @@ bool Item_func_maketime::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) bzero(ltime, sizeof(*ltime)); ltime->time_type= MYSQL_TIMESTAMP_TIME; + ltime->neg= hour.neg(); - /* Check for integer overflows */ - if (hour < 0) + if (hour.abs() <= TIME_MAX_HOUR) { - if (args[0]->unsigned_flag) - overflow= 1; - else - ltime->neg= 1; - } - if (-hour > TIME_MAX_HOUR || hour > TIME_MAX_HOUR) - overflow= 1; - - if (!overflow) - { - ltime->hour= (uint) ((hour < 0 ? -hour : hour)); + ltime->hour= (uint) hour.abs(); ltime->minute= (uint) minute; ltime->second= (uint) second; ltime->second_part= microsecond; } else { - ltime->hour= TIME_MAX_HOUR; - ltime->minute= TIME_MAX_MINUTE; - ltime->second= TIME_MAX_SECOND; + // use check_time_range() to set ltime to the max value depending on dec + int unused; + ltime->hour= TIME_MAX_HOUR + 1; + check_time_range(ltime, decimals, &unused); char buf[28]; - char *ptr= longlong10_to_str(hour, buf, args[0]->unsigned_flag ? 10 : -10); + char *ptr= longlong10_to_str(hour.value(), buf, hour.is_unsigned() ? 10 : -10); int len = (int)(ptr - buf) + sprintf(ptr, ":%02u:%02u", (uint)minute, (uint)second); make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, buf, len, MYSQL_TIMESTAMP_TIME, diff --git a/sql/key.cc b/sql/key.cc index 414c3392cff..f900a1b4527 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -148,7 +148,8 @@ void key_copy(uchar *to_key, uchar *from_record, KEY *key_info, { key_length-= HA_KEY_BLOB_LENGTH; length= min<uint>(key_length, key_part->length); - uint bytes= key_part->field->get_key_image(to_key, length, Field::itRAW); + uint bytes= key_part->field->get_key_image(to_key, length, + key_info->flags & HA_SPATIAL ? Field::itMBR : Field::itRAW); if (with_zerofill && bytes < length) bzero((char*) to_key + bytes, length - bytes); to_key+= HA_KEY_BLOB_LENGTH; diff --git a/sql/log_event.cc b/sql/log_event.cc index e8c1115eafb..da4e63f02e1 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -263,6 +263,27 @@ static void inline slave_rows_error_report(enum loglevel level, int ha_error, } #endif +#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) +static void set_thd_db(THD *thd, Rpl_filter *rpl_filter, + const char *db, uint32 db_len) +{ + char lcase_db_buf[NAME_LEN +1]; + LEX_STRING new_db; + new_db.length= db_len; + if (lower_case_table_names == 1) + { + strmov(lcase_db_buf, db); + my_casedn_str(system_charset_info, lcase_db_buf); + new_db.str= lcase_db_buf; + } + else + new_db.str= (char*) db; + /* TODO WARNING this makes rewrite_db respect lower_case_table_names values + * for more info look MDEV-17446 */ + new_db.str= (char*) rpl_filter->get_rewrite_db(new_db.str, &new_db.length); + thd->set_db(new_db.str, new_db.length); +} +#endif /* Cache that will automatically be written to a dedicated file on destruction. @@ -4141,7 +4162,6 @@ bool test_if_equal_repl_errors(int expected_error, int actual_error) int Query_log_event::do_apply_event(rpl_group_info *rgi, const char *query_arg, uint32 q_len_arg) { - LEX_STRING new_db; int expected_error,actual_error= 0; HA_CREATE_INFO db_options; uint64 sub_id= 0; @@ -4177,9 +4197,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, goto end; } - new_db.length= db_len; - new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length); - thd->set_db(new_db.str, new_db.length); /* allocates a copy of 'db' */ + set_thd_db(thd, rpl_filter, db, db_len); /* Setting the character set and collation of the current database thd->db. @@ -4348,6 +4366,22 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, else thd->variables.collation_database= thd->db_charset; + { + const CHARSET_INFO *cs= thd->charset(); + /* + We cannot ask for parsing a statement using a character set + without state_maps (parser internal data). + */ + if (!cs->state_map) + { + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "character_set cannot be parsed"); + thd->is_slave_error= true; + goto end; + } + } + /* Record any GTID in the same transaction, so slave state is transactionally consistent. @@ -5924,15 +5958,12 @@ void Load_log_event::set_fields(const char* affected_db, int Load_log_event::do_apply_event(NET* net, rpl_group_info *rgi, bool use_rli_only_for_errors) { - LEX_STRING new_db; Relay_log_info const *rli= rgi->rli; Rpl_filter *rpl_filter= rli->mi->rpl_filter; DBUG_ENTER("Load_log_event::do_apply_event"); - new_db.length= db_len; - new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length); - thd->set_db(new_db.str, new_db.length); DBUG_ASSERT(thd->query() == 0); + set_thd_db(thd, rpl_filter, db, db_len); thd->reset_query_inner(); // Should not be needed thd->is_slave_error= 0; clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); @@ -5977,6 +6008,8 @@ int Load_log_event::do_apply_event(NET* net, rpl_group_info *rgi, thd->get_stmt_da()->opt_clear_warning_info(thd->query_id); TABLE_LIST tables; + if (lower_case_table_names) + my_casedn_str(system_charset_info, (char *)table_name); tables.init_one_table(thd->strmake(thd->db, thd->db_length), thd->db_length, table_name, strlen(table_name), @@ -7753,6 +7786,11 @@ User_var_log_event(const char* buf, uint event_len, we keep the flags set to UNDEF_F. */ uint bytes_read= ((val + val_len) - buf_start); + if (bytes_read > event_len) + { + error= true; + goto err; + } if ((data_written - bytes_read) > 0) { flags= (uint) *(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + @@ -11125,7 +11163,7 @@ check_table_map(rpl_group_info *rgi, RPL_TABLE_LIST *table_list) int Table_map_log_event::do_apply_event(rpl_group_info *rgi) { RPL_TABLE_LIST *table_list; - char *db_mem, *tname_mem; + char *db_mem, *tname_mem, *ptr; size_t dummy_len; void *memory; Rpl_filter *filter; @@ -11142,10 +11180,20 @@ int Table_map_log_event::do_apply_event(rpl_group_info *rgi) NullS))) DBUG_RETURN(HA_ERR_OUT_OF_MEM); + strmov(db_mem, m_dbnam); + strmov(tname_mem, m_tblnam); + if (lower_case_table_names) + { + my_casedn_str(files_charset_info, (char*)tname_mem); + my_casedn_str(files_charset_info, (char*)db_mem); + } + /* call from mysql_client_binlog_statement() will not set rli->mi */ filter= rgi->thd->slave_thread ? rli->mi->rpl_filter : global_rpl_filter; - strmov(db_mem, filter->get_rewrite_db(m_dbnam, &dummy_len)); - strmov(tname_mem, m_tblnam); + + /* rewrite rules changed the database */ + if (((ptr= (char*) filter->get_rewrite_db(db_mem, &dummy_len)) != db_mem)) + strmov(db_mem, ptr); table_list->init_one_table(db_mem, strlen(db_mem), tname_mem, strlen(tname_mem), diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3cc87b02a4d..ab58928273a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1459,9 +1459,9 @@ static NTService Service; ///< Service object for WinNT #endif /* __WIN__ */ #ifdef _WIN32 +#include <sddl.h> /* ConvertStringSecurityDescriptorToSecurityDescriptor */ static char pipe_name[512]; static SECURITY_ATTRIBUTES saPipeSecurity; -static SECURITY_DESCRIPTOR sdPipeDescriptor; static HANDLE hPipe = INVALID_HANDLE_VALUE; #endif @@ -2634,21 +2634,20 @@ static void network_init(void) strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\", mysqld_unix_port, NullS); - bzero((char*) &saPipeSecurity, sizeof(saPipeSecurity)); - bzero((char*) &sdPipeDescriptor, sizeof(sdPipeDescriptor)); - if (!InitializeSecurityDescriptor(&sdPipeDescriptor, - SECURITY_DESCRIPTOR_REVISION)) + /* + Create a security descriptor for pipe. + - Use low integrity level, so that it is possible to connect + from any process. + - Give Everyone read/write access to pipe. + */ + if (!ConvertStringSecurityDescriptorToSecurityDescriptor( + "S:(ML;; NW;;; LW) D:(A;; FRFW;;; WD)", + SDDL_REVISION_1, &saPipeSecurity.lpSecurityDescriptor, NULL)) { sql_perror("Can't start server : Initialize security descriptor"); unireg_abort(1); } - if (!SetSecurityDescriptorDacl(&sdPipeDescriptor, TRUE, NULL, FALSE)) - { - sql_perror("Can't start server : Set security descriptor"); - unireg_abort(1); - } saPipeSecurity.nLength = sizeof(SECURITY_ATTRIBUTES); - saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor; saPipeSecurity.bInheritHandle = FALSE; if ((hPipe= CreateNamedPipe(pipe_name, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE, @@ -7194,6 +7193,7 @@ pthread_handler_t handle_connections_namedpipes(void *arg) create_new_thread(thd); set_current_thd(0); } + LocalFree(saPipeSecurity.lpSecurityDescriptor); CloseHandle(connectOverlapped.hEvent); DBUG_LEAVE; decrement_handler_count(); diff --git a/sql/protocol.cc b/sql/protocol.cc index 67fb8924764..1d64681cdbd 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -660,7 +660,7 @@ uchar *net_store_data(uchar *to, const uchar *from, size_t length) uchar *net_store_data(uchar *to,int32 from) { - char buff[20]; + char buff[22]; uint length=(uint) (int10_to_str(from,buff,10)-buff); to=net_store_length_fast(to,length); memcpy(to,buff,length); @@ -1077,7 +1077,7 @@ bool Protocol_text::store_tiny(longlong from) DBUG_ASSERT(field_types == 0 || field_types[field_pos] == MYSQL_TYPE_TINY); field_pos++; #endif - char buff[20]; + char buff[22]; return net_store_data((uchar*) buff, (size_t) (int10_to_str((int) from, buff, -10) - buff)); } @@ -1091,7 +1091,7 @@ bool Protocol_text::store_short(longlong from) field_types[field_pos] == MYSQL_TYPE_SHORT); field_pos++; #endif - char buff[20]; + char buff[22]; return net_store_data((uchar*) buff, (size_t) (int10_to_str((int) from, buff, -10) - buff)); @@ -1106,7 +1106,7 @@ bool Protocol_text::store_long(longlong from) field_types[field_pos] == MYSQL_TYPE_LONG); field_pos++; #endif - char buff[20]; + char buff[22]; return net_store_data((uchar*) buff, (size_t) (int10_to_str((long int)from, buff, (from <0)?-10:10)-buff)); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index cbca413a93d..ecce9ad2b39 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -9991,8 +9991,8 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, mysql_mutex_lock(&acl_cache->lock); - if ((au= find_user_wild(combo->host.str= (char *) sctx->priv_host, - combo->user.str))) + if ((au= find_user_exact(combo->host.str= (char *) sctx->priv_host, + combo->user.str))) goto found_acl; mysql_mutex_unlock(&acl_cache->lock); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 07540d3c96d..36c5b06c378 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7509,10 +7509,22 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join, result= FALSE; -err: if (arena) thd->restore_active_arena(arena, &backup); DBUG_RETURN(result); + +err: + /* + Actually we failed to build join columns list, so we have to + clear it to avoid problems with half-build join on next run. + The list was created in mark_common_columns(). + */ + table_ref_1->remove_join_columns(); + table_ref_2->remove_join_columns(); + + if (arena) + thd->restore_active_arena(arena, &backup); + DBUG_RETURN(TRUE); } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index bc87e69a606..1277bc99549 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -983,6 +983,7 @@ multi_delete::~multi_delete() { TABLE *table= table_being_deleted->table; table->no_keyread=0; + table->no_cache= 0; } for (uint counter= 0; counter < num_of_tables; counter++) diff --git a/sql/sql_error.h b/sql/sql_error.h index a993e9203c9..da077627c88 100644 --- a/sql/sql_error.h +++ b/sql/sql_error.h @@ -18,6 +18,7 @@ #include "sql_list.h" /* Sql_alloc, MEM_ROOT */ #include "m_string.h" /* LEX_STRING */ +#include "sql_type_int.h" // Longlong_hybrid #include "sql_string.h" /* String */ #include "sql_plist.h" /* I_P_List */ #include "mysql_com.h" /* MYSQL_ERRMSG_SIZE */ @@ -573,13 +574,11 @@ public: { return err_conv(err_buffer, sizeof(err_buffer), str, len, cs); } }; -class ErrConvInteger : public ErrConv +class ErrConvInteger : public ErrConv, public Longlong_hybrid { - longlong m_value; - bool m_unsigned; public: ErrConvInteger(longlong num_arg, bool unsigned_flag= false) : - ErrConv(), m_value(num_arg), m_unsigned(unsigned_flag) {} + ErrConv(), Longlong_hybrid(num_arg, unsigned_flag) {} const char *ptr() const { return m_unsigned ? ullstr(m_value, err_buffer) : diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index e0b14e536c0..21fbda29244 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2421,7 +2421,7 @@ void st_select_lex::print_order(String *str, { if (order->counter_used) { - if (query_type != QT_VIEW_INTERNAL) + if (!(query_type & QT_VIEW_INTERNAL)) { char buffer[20]; size_t length= my_snprintf(buffer, 20, "%d", order->counter); diff --git a/sql/sql_list.h b/sql/sql_list.h index 08667bed02a..8956a786715 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -306,10 +306,13 @@ public: */ inline void swap(base_list &rhs) { + list_node **rhs_last=rhs.last; swap_variables(list_node *, first, rhs.first); - swap_variables(list_node **, last, rhs.last); swap_variables(uint, elements, rhs.elements); + rhs.last= last == &first ? &rhs.first : last; + last = rhs_last == &rhs.first ? &first : rhs_last; } + inline list_node* last_node() { return *last; } inline list_node* first_node() { return first;} inline void *head() { return first->info; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0461b9725c5..f7f34e3048f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10785,7 +10785,15 @@ uint check_join_cache_usage(JOIN_TAB *tab, effort now. */ if (tab->table->pos_in_table_list->is_materialized_derived()) + { no_bka_cache= true; + /* + Don't use hash join algorithm if the temporary table for the rows + of the derived table will be created with an equi-join key. + */ + if (tab->table->s->keys) + no_hashed_cache= true; + } /* Don't use join buffering if we're dictated not to by no_jbuf_after diff --git a/sql/sql_show.cc b/sql/sql_show.cc index f107028104f..badeda50597 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2238,7 +2238,7 @@ static int show_create_view(THD *thd, TABLE_LIST *table, String *buff) We can't just use table->query, because our SQL_MODE may trigger a different syntax, like when ANSI_QUOTES is defined. */ - table->view->unit.print(buff, QT_ORDINARY); + table->view->unit.print(buff, QT_VIEW_INTERNAL); if (table->with_check != VIEW_CHECK_NONE) { diff --git a/sql/sql_time.cc b/sql/sql_time.cc index a618f751e65..2a2b8fefe74 100644 --- a/sql/sql_time.cc +++ b/sql/sql_time.cc @@ -190,7 +190,7 @@ bool get_date_from_daynr(long daynr,uint *ret_year,uint *ret_month, ulong convert_period_to_month(ulong period) { ulong a,b; - if (period == 0) + if (period == 0 || period > 999912) return 0L; if ((a=period/100) < YY_PART_YEAR) a+=2000; diff --git a/sql/sql_type_int.h b/sql/sql_type_int.h new file mode 100644 index 00000000000..1eda5651df5 --- /dev/null +++ b/sql/sql_type_int.h @@ -0,0 +1,44 @@ +/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. + Copyright (c) 2011, 2016, MariaDB + + 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 */ + +#ifndef SQL_TYPE_INT_INCLUDED +#define SQL_TYPE_INT_INCLUDED + + +// A longlong/ulonglong hybrid. Good to store results of val_int(). +class Longlong_hybrid +{ +protected: + longlong m_value; + bool m_unsigned; +public: + Longlong_hybrid(longlong nr, bool unsigned_flag) + :m_value(nr), m_unsigned(unsigned_flag) + { } + longlong value() const { return m_value; } + bool is_unsigned() const { return m_unsigned; } + bool neg() const { return m_value < 0 && !m_unsigned; } + ulonglong abs() const + { + if (m_unsigned) + return (ulonglong) m_value; + if (m_value == LONGLONG_MIN) // avoid undefined behavior + return ((ulonglong) LONGLONG_MAX) + 1; + return m_value < 0 ? -m_value : m_value; + } +}; + +#endif // SQL_TYPE_INT_INCLUDED diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 4a1d72d0ed7..b48f42056f0 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -2035,7 +2035,7 @@ multi_update::~multi_update() TABLE_LIST *table; for (table= update_tables ; table; table= table->next_local) { - table->table->no_keyread= table->table->no_cache= 0; + table->table->no_keyread= 0; if (ignore) table->table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); } diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 2348cb4d45d..75b1f809d73 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -4680,6 +4680,19 @@ static Sys_var_mybool Sys_wsrep_certify_nonPK( GLOBAL_VAR(wsrep_certify_nonPK), CMD_LINE(OPT_ARG), DEFAULT(TRUE)); +static const char *wsrep_certification_rules_names[]= { "strict", "optimized", NullS }; +static Sys_var_enum Sys_wsrep_certification_rules( + "wsrep_certification_rules", + "Certification rules to use in the cluster. Possible values are: " + "\"strict\": stricter rules that could result in more certification " + "failures. " + "\"optimized\": relaxed rules that allow more concurrency and " + "cause less certification failures.", + GLOBAL_VAR(wsrep_certification_rules), CMD_LINE(REQUIRED_ARG), + wsrep_certification_rules_names, DEFAULT(WSREP_CERTIFICATION_RULES_STRICT), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), + ON_UPDATE(0)); + static Sys_var_mybool Sys_wsrep_causal_reads( "wsrep_causal_reads", "(DEPRECATED) Setting this variable is equivalent " "to setting wsrep_sync_wait READ flag", diff --git a/sql/table.h b/sql/table.h index 73c40992751..05596b605a5 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2283,6 +2283,16 @@ struct TABLE_LIST } void set_lock_type(THD* thd, enum thr_lock_type lock); + void remove_join_columns() + { + if (join_columns) + { + join_columns->empty(); + join_columns= NULL; + is_join_columns_complete= FALSE; + } + } + private: bool prep_check_option(THD *thd, uint8 check_opt_type); bool prep_where(THD *thd, Item **conds, bool no_where_clause); diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index bfd22ff1900..16241a9f41f 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -58,6 +58,7 @@ ulong wsrep_max_ws_size = 1073741824UL;//max ws (RBR buffer) size ulong wsrep_max_ws_rows = 65536; // max number of rows in ws int wsrep_to_isolation = 0; // # of active TO isolation threads my_bool wsrep_certify_nonPK = 1; // certify, even when no primary key +ulong wsrep_certification_rules = WSREP_CERTIFICATION_RULES_STRICT; long wsrep_max_protocol_version = 3; // maximum protocol version to use ulong wsrep_forced_binlog_format = BINLOG_FORMAT_UNSPEC; my_bool wsrep_recovery = 0; // recovery diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 49845a8fafb..4c98b9a624b 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -21,6 +21,7 @@ typedef struct st_mysql_show_var SHOW_VAR; #include <sql_priv.h> //#include "rpl_gtid.h" #include "../wsrep/wsrep_api.h" +#include "wsrep_mysqld_c.h" #define WSREP_UNDEFINED_TRX_ID ULONGLONG_MAX @@ -66,7 +67,6 @@ enum wsrep_consistency_check_mode { CONSISTENCY_CHECK_RUNNING, }; - // Global wsrep parameters extern wsrep_t* wsrep; diff --git a/sql/wsrep_mysqld_c.h b/sql/wsrep_mysqld_c.h new file mode 100644 index 00000000000..15ca0ae2a6d --- /dev/null +++ b/sql/wsrep_mysqld_c.h @@ -0,0 +1,26 @@ +/* Copyright 2018-2018 Codership Oy <http://www.codership.com> + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef WSREP_MYSQLD_C_H +#define WSREP_MYSQLD_C_H + +enum enum_wsrep_certification_rules { + WSREP_CERTIFICATION_RULES_STRICT, + WSREP_CERTIFICATION_RULES_OPTIMIZED +}; + +extern ulong wsrep_certification_rules; + +#endif /* WSREP_MYSQLD_C_H */ |