diff options
author | Sergei Golubchik <serg@mariadb.org> | 2018-09-23 20:26:35 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2018-09-24 11:46:08 +0200 |
commit | 5ae8fce50bb5cbd7916acd6b03bd699f79c10616 (patch) | |
tree | 6291ec25e408ea225531e8b79a4f4fd7f3a81329 /sql | |
parent | 76098f45b8b1f2224eb25cf5d94450c6f4a1414c (diff) | |
parent | 1fc5a6f30c3a9c047dcf9a36b00026d98f286f6b (diff) | |
download | mariadb-git-5ae8fce50bb5cbd7916acd6b03bd699f79c10616.tar.gz |
Merge branch '10.1' into 10.2
Diffstat (limited to 'sql')
-rw-r--r-- | sql/contributors.h | 4 | ||||
-rw-r--r-- | sql/field.cc | 2 | ||||
-rw-r--r-- | sql/item.cc | 180 | ||||
-rw-r--r-- | sql/item.h | 100 | ||||
-rw-r--r-- | sql/item_func.cc | 2 | ||||
-rw-r--r-- | sql/item_func.h | 8 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 29 | ||||
-rw-r--r-- | sql/sql_acl.cc | 5 | ||||
-rw-r--r-- | sql/sql_base.cc | 7 | ||||
-rw-r--r-- | sql/sql_delete.cc | 1 | ||||
-rw-r--r-- | sql/sql_error.h | 7 | ||||
-rw-r--r-- | sql/sql_select.cc | 19 | ||||
-rw-r--r-- | sql/sql_type_int.h | 44 | ||||
-rw-r--r-- | sql/sql_update.cc | 2 | ||||
-rw-r--r-- | sql/table_cache.cc | 1 |
15 files changed, 101 insertions, 310 deletions
diff --git a/sql/contributors.h b/sql/contributors.h index a0d05af3fa6..69f8fa6bd4c 100644 --- a/sql/contributors.h +++ b/sql/contributors.h @@ -45,12 +45,14 @@ struct show_table_contributors_st show_table_contributors[]= { {"Visma", "https://visma.com", "Gold Sponsor of the MariaDB Foundation"}, {"DBS", "https://dbs.com", "Gold Sponsor of the MariaDB Foundation"}, {"IBM", "https://www.ibm.com", "Gold Sponsor of the MariaDB Foundation"}, + {"Tencent Games", "http://game.qq.com/", "Gold Sponsor of the MariaDB Foundation"}, {"Nexedi", "https://www.nexedi.com", "Silver Sponsor of the MariaDB Foundation"}, - {"Acronis", "http://www.acronis.com", "Silver Sponsor of the MariaDB Foundation"}, + {"Acronis", "https://www.acronis.com", "Silver Sponsor of the MariaDB Foundation"}, {"Verkkokauppa.com", "https://www.verkkokauppa.com", "Bronze Sponsor of the MariaDB Foundation"}, {"Virtuozzo", "https://virtuozzo.com", "Bronze Sponsor of the MariaDB Foundation"}, {"Tencent Game DBA", "http://tencentdba.com/about", "Bronze Sponsor of the MariaDB Foundation"}, {"Tencent TDSQL", "http://tdsql.org", "Bronze Sponsor of the MariaDB Foundation"}, + {"Percona", "https://www.percona.com/", "Bronze Sponsor of the MariaDB Foundation"}, /* Sponsors of important features */ {"Google", "USA", "Sponsoring encryption, parallel replication and GTID"}, diff --git a/sql/field.cc b/sql/field.cc index a1a8ca41698..caa84dc9932 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4526,7 +4526,7 @@ longlong Field_float::val_int(void) { float j; float4get(j,ptr); - return (longlong) rint(j); + return Converter_double_to_longlong(j, false).result(); } diff --git a/sql/item.cc b/sql/item.cc index 45382c0a6f1..35de01b1186 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3949,7 +3949,7 @@ longlong Item_param::val_int() // There's no "default". See comments in Item_param::save_in_field(). switch (state) { case REAL_VALUE: - return (longlong) rint(value.real); + return Converter_double_to_longlong(value.real, unsigned_flag).result(); case INT_VALUE: return value.integer; case DECIMAL_VALUE: @@ -4490,32 +4490,6 @@ bool Item_param::append_for_log(THD *thd, String *str) return str->append(*val); } -/**************************************************************************** - Item_copy -****************************************************************************/ - -Item_copy *Item_copy::create(THD *thd, Item *item) -{ - MEM_ROOT *mem_root= thd->mem_root; - switch (item->result_type()) - { - case STRING_RESULT: - return new (mem_root) Item_copy_string(thd, item); - case REAL_RESULT: - return new (mem_root) Item_copy_float(thd, item); - case INT_RESULT: - return item->unsigned_flag ? - new (mem_root) Item_copy_uint(thd, item) : - new (mem_root) Item_copy_int(thd, item); - case DECIMAL_RESULT: - return new (mem_root) Item_copy_decimal(thd, item); - case TIME_RESULT: - case ROW_RESULT: - DBUG_ASSERT (0); - } - /* should not happen */ - return NULL; -} /**************************************************************************** Item_copy_string @@ -4573,156 +4547,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) */ @@ -9983,7 +9807,7 @@ longlong Item_cache_real::val_int() DBUG_ASSERT(fixed == 1); if (!has_value()) return 0; - return (longlong) rint(value); + return Converter_double_to_longlong(value, unsigned_flag).result(); } diff --git a/sql/item.h b/sql/item.h index 1a280e3091f..8d02d981d38 100644 --- a/sql/item.h +++ b/sql/item.h @@ -4970,7 +4970,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, @@ -5017,13 +5017,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(THD *thd, Item *item); /** Update the cache with the value of the original item @@ -5092,97 +5085,6 @@ public: }; -class Item_copy_int : public Item_copy -{ -protected: - longlong cached_value; -public: - Item_copy_int(THD *thd, Item *i): Item_copy(thd, 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(); - Item *get_copy(THD *thd, MEM_ROOT *mem_root) - { return get_item_copy<Item_copy_int>(thd, mem_root, this); } -}; - - -class Item_copy_uint : public Item_copy_int -{ -public: - Item_copy_uint(THD *thd, Item *item_arg): Item_copy_int(thd, item_arg) - { - unsigned_flag= 1; - } - - String *val_str(String*); - double val_real() - { - return null_value ? 0.0 : (double) (ulonglong) cached_value; - } - Item *get_copy(THD *thd, MEM_ROOT *mem_root) - { return get_item_copy<Item_copy_uint>(thd, mem_root, this); } -}; - - -class Item_copy_float : public Item_copy -{ -protected: - double cached_value; -public: - Item_copy_float(THD *thd, Item *i): Item_copy(thd, 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; - } - Item *get_copy(THD *thd, MEM_ROOT *mem_root) - { return get_item_copy<Item_copy_float>(thd, mem_root, this); } -}; - - -class Item_copy_decimal : public Item_copy -{ -protected: - my_decimal cached_value; -public: - Item_copy_decimal(THD *thd, Item *i): Item_copy(thd, 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(); - Item *get_copy(THD *thd, MEM_ROOT *mem_root) - { return get_item_copy<Item_copy_decimal>(thd, mem_root, this); } -}; - - /* Cached_item_XXX objects are not exactly caches. They do the following: diff --git a/sql/item_func.cc b/sql/item_func.cc index 4bdb18ad95a..dcf3a6f3c29 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -945,7 +945,7 @@ longlong Item_func_hybrid_field_type::val_int() case INT_RESULT: return int_op(); case REAL_RESULT: - return (longlong) rint(real_op()); + return Converter_double_to_longlong(real_op(), unsigned_flag).result(); case TIME_RESULT: { MYSQL_TIME ltime; diff --git a/sql/item_func.h b/sql/item_func.h index 4652f2c2d31..4f1ece45183 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -396,7 +396,10 @@ 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); + return Converter_double_to_longlong(val_real(), unsigned_flag).result(); + } enum Item_result result_type () const { return REAL_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } bool fix_length_and_dec() @@ -1643,7 +1646,8 @@ 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()); + return Converter_double_to_longlong(Item_func_udf_float::val_real(), + unsigned_flag).result(); } my_decimal *val_decimal(my_decimal *dec_buf) { diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index bb75ad7c28c..dc5a0891538 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, @@ -2861,8 +2862,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; @@ -2874,32 +2874,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/sql_acl.cc b/sql/sql_acl.cc index 75186bb502c..03456b93bea 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -10942,9 +10942,8 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, combo->user.str= (char *) sctx->priv_user; 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 52474116fa6..e1db8bc48be 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -646,6 +646,7 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share, uint key_length= share->table_cache_key.length; const char *db= key; const char *table_name= db + share->db.length + 1; + bool remove_from_locked_tables= extra != HA_EXTRA_NOT_USED; memcpy(key, share->table_cache_key.str, key_length); @@ -659,7 +660,7 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share, { thd->locked_tables_list.unlink_from_list(thd, table->pos_in_locked_tables, - extra != HA_EXTRA_NOT_USED); + remove_from_locked_tables); /* Inform handler that there is a drop table or a rename going on */ if (extra != HA_EXTRA_NOT_USED && table->db_stat) { @@ -3745,6 +3746,10 @@ lock_table_names(THD *thd, const DDL_options_st &options, mdl_requests.push_front(&global_request); if (create_table) + #ifdef WITH_WSREP + if (thd->lex->sql_command != SQLCOM_CREATE_TABLE && + thd->wsrep_exec_mode != REPL_RECV) + #endif lock_wait_timeout= 0; // Don't wait for timeout } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 93c7b0580bb..c0deb33410d 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -1025,6 +1025,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 0a1e7d38e01..3ac06657323 100644 --- a/sql/sql_error.h +++ b/sql/sql_error.h @@ -19,6 +19,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 */ @@ -577,13 +578,11 @@ public: } }; -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_select.cc b/sql/sql_select.cc index 3ec1a1b6e04..a27053314bd 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -21561,11 +21561,30 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, tmp_map.clear_all(); // Force the creation of quick select tmp_map.set_bit(best_key); // only best_key. select->quick= 0; + + bool cond_saved= false; + Item *saved_cond; + + /* + Index Condition Pushdown may have removed parts of the condition for + this table. Temporarily put them back because we want the whole + condition for the range analysis. + */ + if (select->pre_idx_push_select_cond) + { + saved_cond= select->cond; + select->cond= select->pre_idx_push_select_cond; + cond_saved= true; + } + select->test_quick_select(join->thd, tmp_map, 0, join->select_options & OPTION_FOUND_ROWS ? HA_POS_ERROR : join->unit->select_limit_cnt, TRUE, FALSE, FALSE); + + if (cond_saved) + select->cond= saved_cond; } order_direction= best_key_direction; /* 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 a2cfcbabc95..98fc91ee2e1 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -2049,7 +2049,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/table_cache.cc b/sql/table_cache.cc index eeb100a5319..8682662e924 100644 --- a/sql/table_cache.cc +++ b/sql/table_cache.cc @@ -450,6 +450,7 @@ void tc_release_table(TABLE *table) uint32 i= table->instance; DBUG_ASSERT(table->in_use); DBUG_ASSERT(table->file); + DBUG_ASSERT(!table->pos_in_locked_tables); mysql_mutex_lock(&tc[i].LOCK_table_cache); if (table->needs_reopen() || table->s->tdc->flushed || |