diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-07-31 18:09:08 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-07-31 18:09:08 +0300 |
commit | 9216114ce729733e6b0c4ce952bfdf57595ff387 (patch) | |
tree | 7a541ed87a6a8174d3d94c5f780724a34e08dc1c /sql | |
parent | dc513dff911d72eaaf9f752f390fef8d1ef9a4b0 (diff) | |
parent | 66ec3a770f7854f500ece66c78f3c87c9cd6da15 (diff) | |
download | mariadb-git-9216114ce729733e6b0c4ce952bfdf57595ff387.tar.gz |
Merge 10.3 into 10.4
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 8 | ||||
-rw-r--r-- | sql/item.cc | 35 | ||||
-rw-r--r-- | sql/item_create.cc | 2 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 5 | ||||
-rw-r--r-- | sql/item_windowfunc.cc | 6 | ||||
-rw-r--r-- | sql/item_windowfunc.h | 10 | ||||
-rw-r--r-- | sql/log_event.cc | 22 | ||||
-rw-r--r-- | sql/net_serv.cc | 14 | ||||
-rw-r--r-- | sql/partition_info.cc | 1 | ||||
-rw-r--r-- | sql/session_tracker.cc | 8 | ||||
-rw-r--r-- | sql/slave.cc | 3 | ||||
-rw-r--r-- | sql/sql_base.cc | 43 | ||||
-rw-r--r-- | sql/sql_class.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.h | 21 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 | ||||
-rw-r--r-- | sql/sql_plugin.cc | 47 | ||||
-rw-r--r-- | sql/sql_table.cc | 5 | ||||
-rw-r--r-- | sql/sql_time.cc | 22 | ||||
-rw-r--r-- | sql/sql_time.h | 4 | ||||
-rw-r--r-- | sql/sql_type.cc | 21 | ||||
-rw-r--r-- | sql/sql_type.h | 32 | ||||
-rw-r--r-- | sql/sys_vars.cc | 6 | ||||
-rw-r--r-- | sql/sys_vars.ic | 13 | ||||
-rw-r--r-- | sql/table.cc | 16 | ||||
-rw-r--r-- | sql/table.h | 1 | ||||
-rw-r--r-- | sql/threadpool.h | 1 | ||||
-rw-r--r-- | sql/threadpool_common.cc | 22 | ||||
-rw-r--r-- | sql/threadpool_generic.cc | 22 |
28 files changed, 249 insertions, 144 deletions
diff --git a/sql/field.cc b/sql/field.cc index ea752d33a20..18c38d59297 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2322,7 +2322,7 @@ uint Field::fill_cache_field(CACHE_FIELD *copy) bool Field::get_date(MYSQL_TIME *to, date_mode_t mode) { StringBuffer<40> tmp; - Temporal::Warn_push warn(get_thd(), NULL, NullS, to, mode); + Temporal::Warn_push warn(get_thd(), nullptr, nullptr, nullptr, to, mode); Temporal_hybrid *t= new(to) Temporal_hybrid(get_thd(), &warn, val_str(&tmp), mode); return !t->is_valid_temporal(); @@ -11190,14 +11190,16 @@ void Field::set_datetime_warning(Sql_condition::enum_warning_level level, if (thd->really_abort_on_warning() && level >= Sql_condition::WARN_LEVEL_WARN) { /* - field_str.name can be NULL when field is not in the select list: + field_name.str can be NULL when field is not in the select list: SET SESSION SQL_MODE= 'STRICT_ALL_TABLES,NO_ZERO_DATE'; CREATE OR REPLACE TABLE t2 SELECT 1 AS f FROM t1 GROUP BY FROM_DAYS(d); Can't call push_warning_truncated_value_for_field() directly here, as it expect a non-NULL name. */ thd->push_warning_wrong_or_truncated_value(level, false, typestr, - str->ptr(), table->s, + str->ptr(), + table->s->db.str, + table->s->table_name.str, field_name.str); } else diff --git a/sql/item.cc b/sql/item.cc index 4b64d76905a..4c2c03cb3b2 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1372,8 +1372,10 @@ bool Item::get_date_from_real(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate bool Item::get_date_from_string(THD *thd, MYSQL_TIME *to, date_mode_t mode) { StringBuffer<40> tmp; - Temporal::Warn_push warn(thd, field_table_or_null(), field_name_or_null(), - to, mode); + const TABLE_SHARE *s = field_table_or_null(); + Temporal::Warn_push warn(thd, s ? s->db.str : nullptr, + s ? s->table_name.str : nullptr, + field_name_or_null(), to, mode); Temporal_hybrid *t= new(to) Temporal_hybrid(thd, &warn, val_str(&tmp), mode); return !t->is_valid_temporal(); } @@ -2509,14 +2511,7 @@ bool Type_std_attributes::agg_item_set_converter(const DTCollation &coll, bool res= FALSE; uint i; - /* - In case we're in statement prepare, create conversion item - in its memory: it will be reused on each execute. - */ - Query_arena backup; - Query_arena *arena= thd->stmt_arena->is_stmt_prepare() ? - thd->activate_stmt_arena_if_needed(&backup) : - NULL; + DBUG_ASSERT(!thd->stmt_arena->is_stmt_prepare()); for (i= 0, arg= args; i < nargs; i++, arg+= item_sep) { @@ -2538,20 +2533,8 @@ bool Type_std_attributes::agg_item_set_converter(const DTCollation &coll, res= TRUE; break; // we cannot return here, we need to restore "arena". } - /* - If in statement prepare, then we create a converter for two - constant items, do it once and then reuse it. - If we're in execution of a prepared statement, arena is NULL, - and the conv was created in runtime memory. This can be - the case only if the argument is a parameter marker ('?'), - because for all true constants the charset converter has already - been created in prepare. In this case register the change for - rollback. - */ - if (thd->stmt_arena->is_stmt_prepare()) - *arg= conv; - else - thd->change_item_tree(arg, conv); + + thd->change_item_tree(arg, conv); if (conv->fix_fields_if_needed(thd, arg)) { @@ -2559,8 +2542,6 @@ bool Type_std_attributes::agg_item_set_converter(const DTCollation &coll, break; // we cannot return here, we need to restore "arena". } } - if (arena) - thd->restore_active_arena(arena, &backup); return res; } @@ -4079,7 +4060,7 @@ void Item_param::set_time(MYSQL_TIME *tm, timestamp_type time_type, { ErrConvTime str(&value.time); make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, - &str, time_type, 0, 0); + &str, time_type, NULL, NULL, NULL); set_zero_time(&value.time, time_type); } maybe_null= 0; diff --git a/sql/item_create.cc b/sql/item_create.cc index 9b949835e27..5f6e7b29d5c 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2008-2011 Monty Program Ab + Copyright (c) 2008, 2020, 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_timefunc.cc b/sql/item_timefunc.cc index d10c00aa325..c740d1e227f 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2012, Oracle and/or its affiliates. - Copyright (c) 2009, 2016, MariaDB + Copyright (c) 2009, 2020, 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 @@ -453,7 +453,8 @@ static bool extract_date_time(THD *thd, DATE_TIME_FORMAT *format, { ErrConvString err(val_begin, length, &my_charset_bin); make_truncated_value_warning(thd, Sql_condition::WARN_LEVEL_WARN, - &err, cached_timestamp_type, 0, NullS); + &err, cached_timestamp_type, + nullptr, nullptr, nullptr); break; } } while (++val != val_end); diff --git a/sql/item_windowfunc.cc b/sql/item_windowfunc.cc index 1724174343f..5a114b7a193 100644 --- a/sql/item_windowfunc.cc +++ b/sql/item_windowfunc.cc @@ -562,12 +562,10 @@ void Item_window_func::print(String *str, enum_query_type query_type) } window_func()->print(str, query_type); str->append(" over "); -#ifndef DBUG_OFF - if (!window_spec) // one can call dbug_print_item() anytime in gdb + if (!window_spec) str->append(window_name); else -#endif - window_spec->print(str, query_type); + window_spec->print(str, query_type); } void Item_window_func::print_for_percentile_functions(String *str, enum_query_type query_type) { diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h index 846acd74b29..c038cb8d15f 100644 --- a/sql/item_windowfunc.h +++ b/sql/item_windowfunc.h @@ -646,7 +646,7 @@ class Item_sum_ntile : public Item_sum_int, { public: Item_sum_ntile(THD* thd, Item* num_quantiles_expr) : - Item_sum_int(thd, num_quantiles_expr) + Item_sum_int(thd, num_quantiles_expr), n_old_val_(0) { } longlong val_int() @@ -659,11 +659,13 @@ class Item_sum_ntile : public Item_sum_int, longlong num_quantiles= get_num_quantiles(); - if (num_quantiles <= 0) { + if (num_quantiles <= 0 || + (static_cast<ulonglong>(num_quantiles) != n_old_val_ && n_old_val_ > 0)) + { my_error(ER_INVALID_NTILE_ARGUMENT, MYF(0)); return true; } - + n_old_val_= static_cast<ulonglong>(num_quantiles); null_value= false; ulonglong quantile_size = get_row_count() / num_quantiles; ulonglong extra_rows = get_row_count() - quantile_size * num_quantiles; @@ -689,6 +691,7 @@ class Item_sum_ntile : public Item_sum_int, { current_row_count_= 0; partition_row_count_= 0; + n_old_val_= 0; } const char*func_name() const @@ -710,6 +713,7 @@ class Item_sum_ntile : public Item_sum_int, private: longlong get_num_quantiles() { return args[0]->val_int(); } + ulonglong n_old_val_; }; class Item_sum_percentile_disc : public Item_sum_num, diff --git a/sql/log_event.cc b/sql/log_event.cc index 3707f73a716..58f0d77e80b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -5393,8 +5393,7 @@ bool Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info) } else if (strcmp("COMMIT", query) == 0) { - if (my_b_write(&cache, (uchar*) "BEGIN", 5) || - my_b_printf(&cache, "\n%s\n", print_event_info->delimiter)) + if (my_b_printf(&cache, "START TRANSACTION\n%s\n", print_event_info->delimiter)) goto err; } } @@ -8293,7 +8292,8 @@ Gtid_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info) goto err; } if (!(flags2 & FL_STANDALONE)) - if (my_b_printf(&cache, is_flashback ? "COMMIT\n%s\n" : "BEGIN\n%s\n", print_event_info->delimiter)) + if (my_b_printf(&cache, is_flashback ? "COMMIT\n%s\n" : + "START TRANSACTION\n%s\n", print_event_info->delimiter)) goto err; return cache.flush_data(); @@ -8976,7 +8976,7 @@ bool Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info) my_b_printf(&cache, "\tXid = %s\n", buf)) goto err; } - if (my_b_printf(&cache, is_flashback ? "BEGIN%s\n" : "COMMIT%s\n", + if (my_b_printf(&cache, is_flashback ? "START TRANSACTION%s\n" : "COMMIT%s\n", print_event_info->delimiter)) goto err; @@ -14343,7 +14343,6 @@ end: if (is_table_scan || is_index_scan) issue_long_find_row_warning(get_general_type_code(), m_table->alias.c_ptr(), is_index_scan, rgi); - table->default_column_bitmaps(); DBUG_RETURN(error); } @@ -14674,7 +14673,13 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi) #endif /* WSREP_PROC_INFO */ thd_proc_info(thd, message); - int error= find_row(rgi); + // Temporary fix to find out why it fails [/Matz] + memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8); + memcpy(m_table->write_set->bitmap, m_cols_ai.bitmap, (m_table->write_set->n_bits + 7) / 8); + + m_table->mark_columns_per_binlog_row_image(); + + int error= find_row(rgi); if (unlikely(error)) { /* @@ -14744,11 +14749,6 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi) goto err; } - // Temporary fix to find out why it fails [/Matz] - memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8); - memcpy(m_table->write_set->bitmap, m_cols_ai.bitmap, (m_table->write_set->n_bits + 7) / 8); - - m_table->mark_columns_per_binlog_row_image(); if (m_vers_from_plain && m_table->versioned(VERS_TIMESTAMP)) m_table->vers_update_fields(); error= m_table->file->ha_update_row(m_table->record[1], m_table->record[0]); diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 4fecf8bffd0..5d2ad6d17a6 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2012, 2018, MariaDB Corporation. + Copyright (c) 2012, 2020, 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 @@ -45,6 +45,7 @@ #include <violite.h> #include <signal.h> #include "probes_mysql.h" +#include <debug_sync.h> #include "proxy_protocol.h" #ifdef EMBEDDED_LIBRARY @@ -489,6 +490,17 @@ net_write_command(NET *net,uchar command, DBUG_ENTER("net_write_command"); DBUG_PRINT("enter",("length: %lu", (ulong) len)); + DBUG_EXECUTE_IF("simulate_error_on_packet_write", + { + if (command == COM_BINLOG_DUMP) + { + net->last_errno = ER_NET_ERROR_ON_WRITE; + DBUG_ASSERT(!debug_sync_set_action( + (THD *)net->thd, + STRING_WITH_LEN("now SIGNAL parked WAIT_FOR continue"))); + DBUG_RETURN(true); + } + };); MYSQL_NET_WRITE_START(length); buff[4]=command; /* For first packet */ diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 8989a918c0c..9f08964e62c 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -875,7 +875,6 @@ void partition_info::vers_set_hist_part(THD *thd) if (next->range_value > thd->query_start()) return; } - goto warn; } return; warn: diff --git a/sql/session_tracker.cc b/sql/session_tracker.cc index c37cdb46fc9..91b529f72d5 100644 --- a/sql/session_tracker.cc +++ b/sql/session_tracker.cc @@ -189,7 +189,13 @@ bool sysvartrack_validate_value(THD *thd, const char *str, size_t len) char *token, *lasts= NULL; size_t rest= var_list.length; - if (!var_list.str || var_list.length == 0 || + if (!var_list.str) + { + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), + "session_track_system_variables", "NULL"); + return false; + } + if (var_list.length == 0 || !strcmp(var_list.str, "*")) { return false; diff --git a/sql/slave.cc b/sql/slave.cc index 1fa83bd6bfa..f2e38c02ab5 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -3684,7 +3684,8 @@ static int request_dump(THD *thd, MYSQL* mysql, Master_info* mi, in the future, we should do a better error analysis, but for now we just fill up the error log :-) */ - if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED) + if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED || + mysql_errno(mysql) == ER_NET_ERROR_ON_WRITE) *suppress_warnings= TRUE; // Suppress reconnect warning else sql_print_error("Error on COM_BINLOG_DUMP: %d %s, will retry in %d secs", diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 551e4286d8b..10bc6ccab6c 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5430,6 +5430,24 @@ static void mark_real_tables_as_free_for_reuse(TABLE_LIST *table_list) } } +int TABLE::fix_vcol_exprs(THD *thd) +{ + for (Field **vf= vfield; vf && *vf; vf++) + if (fix_session_vcol_expr(thd, (*vf)->vcol_info)) + return 1; + + for (Field **df= default_field; df && *df; df++) + if ((*df)->default_value && + fix_session_vcol_expr(thd, (*df)->default_value)) + return 1; + + for (Virtual_column_info **cc= check_constraints; cc && *cc; cc++) + if (fix_session_vcol_expr(thd, (*cc))) + return 1; + + return 0; +} + static bool fix_all_session_vcol_exprs(THD *thd, TABLE_LIST *tables) { @@ -5437,36 +5455,27 @@ static bool fix_all_session_vcol_exprs(THD *thd, TABLE_LIST *tables) TABLE_LIST *first_not_own= thd->lex->first_not_own_table(); DBUG_ENTER("fix_session_vcol_expr"); - for (TABLE_LIST *table= tables; table && table != first_not_own; + int error= 0; + for (TABLE_LIST *table= tables; table && table != first_not_own && !error; table= table->next_global) { TABLE *t= table->table; if (!table->placeholder() && t->s->vcols_need_refixing && table->lock_type >= TL_WRITE_ALLOW_WRITE) { + Query_arena *stmt_backup= thd->stmt_arena; + if (thd->stmt_arena->is_conventional()) + thd->stmt_arena= t->expr_arena; if (table->security_ctx) thd->security_ctx= table->security_ctx; - for (Field **vf= t->vfield; vf && *vf; vf++) - if (fix_session_vcol_expr(thd, (*vf)->vcol_info)) - goto err; - - for (Field **df= t->default_field; df && *df; df++) - if ((*df)->default_value && - fix_session_vcol_expr(thd, (*df)->default_value)) - goto err; - - for (Virtual_column_info **cc= t->check_constraints; cc && *cc; cc++) - if (fix_session_vcol_expr(thd, (*cc))) - goto err; + error= t->fix_vcol_exprs(thd); thd->security_ctx= save_security_ctx; + thd->stmt_arena= stmt_backup; } } - DBUG_RETURN(0); -err: - thd->security_ctx= save_security_ctx; - DBUG_RETURN(1); + DBUG_RETURN(error); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 15088148e02..19180c85a2a 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3775,7 +3775,6 @@ void select_dumpvar::cleanup() Query_arena::Type Query_arena::type() const { - DBUG_ASSERT(0); /* Should never be called */ return STATEMENT; } diff --git a/sql/sql_class.h b/sql/sql_class.h index ad7631a66bb..22637872cfc 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1021,7 +1021,7 @@ public: /* We build without RTTI, so dynamic_cast can't be used. */ enum Type { - STATEMENT, PREPARED_STATEMENT, STORED_PROCEDURE + STATEMENT, PREPARED_STATEMENT, STORED_PROCEDURE, TABLE_ARENA }; Query_arena(MEM_ROOT *mem_root_arg, enum enum_state state_arg) : @@ -3938,13 +3938,20 @@ public: return 0; } + + bool is_item_tree_change_register_required() + { + return !stmt_arena->is_conventional() + || stmt_arena->type() == Query_arena::TABLE_ARENA; + } + void change_item_tree(Item **place, Item *new_value) { DBUG_ENTER("THD::change_item_tree"); DBUG_PRINT("enter", ("Register: %p (%p) <- %p", *place, place, new_value)); /* TODO: check for OOM condition here */ - if (!stmt_arena->is_conventional()) + if (is_item_tree_change_register_required()) nocheck_register_item_tree_change(place, *place, mem_root); *place= new_value; DBUG_VOID_RETURN; @@ -4440,14 +4447,13 @@ public: void push_warning_truncated_value_for_field(Sql_condition::enum_warning_level level, const char *type_str, const char *val, - const TABLE_SHARE *s, + const char *db_name, + const char *table_name, const char *name) { DBUG_ASSERT(name); char buff[MYSQL_ERRMSG_SIZE]; CHARSET_INFO *cs= &my_charset_latin1; - const char *db_name= s ? s->db.str : NULL; - const char *table_name= s ? s->table_name.str : NULL; if (!db_name) db_name= ""; @@ -4464,12 +4470,13 @@ public: bool totally_useless_value, const char *type_str, const char *val, - const TABLE_SHARE *s, + const char *db_name, + const char *table_name, const char *field_name) { if (field_name) push_warning_truncated_value_for_field(level, type_str, val, - s, field_name); + db_name, table_name, field_name); else if (totally_useless_value) push_warning_wrong_value(level, type_str, val); else diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 9f7cf514ac3..fbfb0449989 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7916,8 +7916,8 @@ void mysql_parse(THD *thd, char *rawbuf, uint length, sp_cache_enforce_limit(thd->sp_package_spec_cache, stored_program_cache_size); sp_cache_enforce_limit(thd->sp_package_body_cache, stored_program_cache_size); thd->end_statement(); + thd->Item_change_list::rollback_item_tree_changes(); thd->cleanup_after_query(); - DBUG_ASSERT(thd->Item_change_list::is_empty()); } else { diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 2afd82b2b46..981420f03ae 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2005, 2018, Oracle and/or its affiliates. - Copyright (c) 2010, 2018, MariaDB Corporation + Copyright (c) 2010, 2020, 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 @@ -2276,27 +2276,30 @@ static bool do_uninstall(THD *thd, TABLE *table, const LEX_CSTRING *name) if (!(plugin= plugin_find_internal(name, MYSQL_ANY_PLUGIN)) || plugin->state & (PLUGIN_IS_UNINITIALIZED | PLUGIN_IS_DYING)) { - myf MyFlags= thd->lex->if_exists() ? ME_NOTE : 0; - my_error(ER_SP_DOES_NOT_EXIST, MyFlags, "PLUGIN", name->str); - return !MyFlags; - } - if (!plugin->plugin_dl) - { - my_error(ER_PLUGIN_DELETE_BUILTIN, MYF(0)); - return 1; + // maybe plugin is present in mysql.plugin; postpone the error + plugin= nullptr; } - if (plugin->load_option == PLUGIN_FORCE_PLUS_PERMANENT) + + if (plugin) { - my_error(ER_PLUGIN_IS_PERMANENT, MYF(0), name->str); - return 1; - } + if (!plugin->plugin_dl) + { + my_error(ER_PLUGIN_DELETE_BUILTIN, MYF(0)); + return 1; + } + if (plugin->load_option == PLUGIN_FORCE_PLUS_PERMANENT) + { + my_error(ER_PLUGIN_IS_PERMANENT, MYF(0), name->str); + return 1; + } - plugin->state= PLUGIN_IS_DELETED; - if (plugin->ref_count) - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, - WARN_PLUGIN_BUSY, ER_THD(thd, WARN_PLUGIN_BUSY)); - else - reap_needed= true; + plugin->state= PLUGIN_IS_DELETED; + if (plugin->ref_count) + push_warning(thd, Sql_condition::WARN_LEVEL_WARN, + WARN_PLUGIN_BUSY, ER_THD(thd, WARN_PLUGIN_BUSY)); + else + reap_needed= true; + } uchar user_key[MAX_KEY_LENGTH]; table->use_all_columns(); @@ -2321,6 +2324,12 @@ static bool do_uninstall(THD *thd, TABLE *table, const LEX_CSTRING *name) return 1; } } + else if (!plugin) + { + const myf MyFlags= thd->lex->if_exists() ? ME_NOTE : 0; + my_error(ER_SP_DOES_NOT_EXIST, MyFlags, "PLUGIN", name->str); + return !MyFlags; + } return 0; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 2a3cdedd717..3831bd03802 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -10495,8 +10495,9 @@ err_new_table_cleanup: bool save_abort_on_warning= thd->abort_on_warning; thd->abort_on_warning= true; thd->push_warning_truncated_value_for_field(Sql_condition::WARN_LEVEL_WARN, - f_type, f_val, new_table - ? new_table->s : table->s, + f_type, f_val, + alter_ctx.new_db.str, + alter_ctx.new_name.str, alter_ctx.datetime_field-> field_name.str); thd->abort_on_warning= save_abort_on_warning; diff --git a/sql/sql_time.cc b/sql/sql_time.cc index 9584dfd5f63..abc91907a55 100644 --- a/sql/sql_time.cc +++ b/sql/sql_time.cc @@ -18,7 +18,6 @@ /* Functions to handle date and time */ #include "mariadb.h" -#include "sql_priv.h" #include "sql_time.h" #include "tztime.h" // struct Time_zone #include "sql_class.h" // THD @@ -297,7 +296,7 @@ check_date_with_warn(THD *thd, const MYSQL_TIME *ltime, { ErrConvTime str(ltime); make_truncated_value_warning(thd, Sql_condition::WARN_LEVEL_WARN, - &str, ts_type, 0, 0); + &str, ts_type, nullptr, nullptr, nullptr); return true; } return false; @@ -431,7 +430,7 @@ str_to_datetime_with_warn(THD *thd, CHARSET_INFO *cs, const char *str, size_t length, MYSQL_TIME *to, date_mode_t mode) { - Temporal::Warn_push warn(thd, NULL, NullS, to, mode); + Temporal::Warn_push warn(thd, nullptr, nullptr, nullptr, to, mode); Temporal_hybrid *t= new(to) Temporal_hybrid(thd, &warn, str, length, cs, mode); return !t->is_valid_temporal(); } @@ -441,7 +440,9 @@ bool double_to_datetime_with_warn(THD *thd, double value, MYSQL_TIME *ltime, date_mode_t fuzzydate, const TABLE_SHARE *s, const char *field_name) { - Temporal::Warn_push warn(thd, s, field_name, ltime, fuzzydate); + Temporal::Warn_push warn(thd, s ? s->db.str : nullptr, + s ? s->table_name.str : nullptr, + field_name, ltime, fuzzydate); Temporal_hybrid *t= new (ltime) Temporal_hybrid(thd, &warn, value, fuzzydate); return !t->is_valid_temporal(); } @@ -452,7 +453,9 @@ bool decimal_to_datetime_with_warn(THD *thd, const my_decimal *value, date_mode_t fuzzydate, const TABLE_SHARE *s, const char *field_name) { - Temporal::Warn_push warn(thd, s, field_name, ltime, fuzzydate); + Temporal::Warn_push warn(thd, s ? s->db.str : nullptr, + s ? s->table_name.str : nullptr, + field_name, ltime, fuzzydate); Temporal_hybrid *t= new (ltime) Temporal_hybrid(thd, &warn, value, fuzzydate); return !t->is_valid_temporal(); } @@ -467,7 +470,9 @@ bool int_to_datetime_with_warn(THD *thd, const Longlong_hybrid &nr, Note: conversion from an integer to TIME can overflow to '838:59:59.999999', so the conversion result can have fractional digits. */ - Temporal::Warn_push warn(thd, s, field_name, ltime, fuzzydate); + Temporal::Warn_push warn(thd, s ? s->db.str : nullptr, + s ? s->table_name.str : nullptr, + field_name, ltime, fuzzydate); Temporal_hybrid *t= new (ltime) Temporal_hybrid(thd, &warn, nr, fuzzydate); return !t->is_valid_temporal(); } @@ -897,12 +902,13 @@ void make_truncated_value_warning(THD *thd, Sql_condition::enum_warning_level level, const ErrConv *sval, timestamp_type time_type, - const TABLE_SHARE *s, const char *field_name) + const char *db_name, const char *table_name, + const char *field_name) { const char *type_str= Temporal::type_name_by_timestamp_type(time_type); return thd->push_warning_wrong_or_truncated_value (level, time_type <= MYSQL_TIMESTAMP_ERROR, type_str, sval->ptr(), - s, field_name); + db_name, table_name, field_name); } diff --git a/sql/sql_time.h b/sql/sql_time.h index fe9697adf67..c918eb6d807 100644 --- a/sql/sql_time.h +++ b/sql/sql_time.h @@ -1,5 +1,5 @@ /* Copyright (c) 2006, 2010, Oracle and/or its affiliates. - Copyright (c) 2011, 2016, MariaDB + Copyright (c) 2011, 2020, 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 @@ -78,7 +78,7 @@ void make_truncated_value_warning(THD *thd, Sql_condition::enum_warning_level level, const ErrConv *str_val, timestamp_type time_type, - const TABLE_SHARE *s, + const char *db_name, const char *table_name, const char *field_name); extern DATE_TIME_FORMAT *date_time_format_make(timestamp_type format_type, diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 8757d2fef59..3e762affe2f 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -401,17 +401,21 @@ bool Sec6::convert_to_mysql_time(THD *thd, int *warn, MYSQL_TIME *ltime, void Temporal::push_conversion_warnings(THD *thd, bool totally_useless_value, int warn, const char *typestr, - const TABLE_SHARE *s, + const char *db_name, + const char *table_name, const char *field_name, const char *value) { if (MYSQL_TIME_WARN_HAVE_WARNINGS(warn)) thd->push_warning_wrong_or_truncated_value(Sql_condition::WARN_LEVEL_WARN, totally_useless_value, - typestr, value, s, field_name); + typestr, value, + db_name, table_name, + field_name); else if (MYSQL_TIME_WARN_HAVE_NOTES(warn)) thd->push_warning_wrong_or_truncated_value(Sql_condition::WARN_LEVEL_NOTE, - false, typestr, value, s, + false, typestr, value, + db_name, table_name, field_name); } @@ -4454,7 +4458,9 @@ bool Type_handler::Item_get_date_with_warn(THD *thd, Item *item, MYSQL_TIME *ltime, date_mode_t fuzzydate) const { - Temporal::Warn_push warn(thd, item->field_table_or_null(), + const TABLE_SHARE *s= item->field_table_or_null(); + Temporal::Warn_push warn(thd, s ? s->db.str : nullptr, + s ? s->table_name.str : nullptr, item->field_name_or_null(), ltime, fuzzydate); Item_get_date(thd, item, &warn, ltime, fuzzydate); return ltime->time_type < 0; @@ -4466,7 +4472,9 @@ bool Type_handler::Item_func_hybrid_field_type_get_date_with_warn(THD *thd, MYSQL_TIME *ltime, date_mode_t mode) const { - Temporal::Warn_push warn(thd, item->field_table_or_null(), + const TABLE_SHARE *s= item->field_table_or_null(); + Temporal::Warn_push warn(thd, s ? s->db.str : nullptr, + s ? s->table_name.str : nullptr, item->field_name_or_null(), ltime, mode); Item_func_hybrid_field_type_get_date(thd, item, &warn, ltime, mode); return ltime->time_type < 0; @@ -8284,7 +8292,8 @@ static void literal_warn(THD *thd, const Item *item, ErrConvString err(str, length, cs); thd->push_warning_wrong_or_truncated_value( Sql_condition::time_warn_level(st->warnings), - false, typestr, err.ptr(), NULL, NullS); + false, typestr, err.ptr(), + nullptr, nullptr, nullptr); } } else if (send_error) diff --git a/sql/sql_type.h b/sql/sql_type.h index 65935c1bd66..badd8d2f7f5 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -1,7 +1,7 @@ #ifndef SQL_TYPE_H_INCLUDED #define SQL_TYPE_H_INCLUDED /* - Copyright (c) 2015 MariaDB Foundation. + Copyright (c) 2015, 2020, 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 @@ -663,34 +663,39 @@ public: public: void push_conversion_warnings(THD *thd, bool totally_useless_value, date_mode_t mode, timestamp_type tstype, - const TABLE_SHARE* s, const char *name) + const char *db_name, const char *table_name, + const char *name) { const char *typestr= tstype >= 0 ? type_name_by_timestamp_type(tstype) : mode & (TIME_INTERVAL_hhmmssff | TIME_INTERVAL_DAY) ? "interval" : mode & TIME_TIME_ONLY ? "time" : "datetime"; Temporal::push_conversion_warnings(thd, totally_useless_value, warnings, - typestr, s, name, ptr()); + typestr, db_name, table_name, name, + ptr()); } }; class Warn_push: public Warn { - THD *m_thd; - const TABLE_SHARE *m_s; - const char *m_name; - const MYSQL_TIME *m_ltime; - date_mode_t m_mode; + THD * const m_thd; + const char * const m_db_name; + const char * const m_table_name; + const char * const m_name; + const MYSQL_TIME * const m_ltime; + const date_mode_t m_mode; public: - Warn_push(THD *thd, const TABLE_SHARE *s, const char *name, - const MYSQL_TIME *ltime, date_mode_t mode) - :m_thd(thd), m_s(s), m_name(name), m_ltime(ltime), m_mode(mode) + Warn_push(THD *thd, const char *db_name, const char *table_name, + const char *name, const MYSQL_TIME *ltime, date_mode_t mode) + : m_thd(thd), m_db_name(db_name), m_table_name(table_name), m_name(name), + m_ltime(ltime), m_mode(mode) { } ~Warn_push() { if (warnings) push_conversion_warnings(m_thd, m_ltime->time_type < 0, - m_mode, m_ltime->time_type, m_s, m_name); + m_mode, m_ltime->time_type, + m_db_name, m_table_name, m_name); } }; @@ -731,7 +736,8 @@ public: } static void push_conversion_warnings(THD *thd, bool totally_useless_value, int warn, const char *type_name, - const TABLE_SHARE *s, + const char *db_name, + const char *table_name, const char *field_name, const char *value); /* diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index e46925f5ee0..1c84f308a81 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3695,6 +3695,12 @@ static bool fix_tp_min_threads(sys_var *, THD *, enum_var_type) static bool check_threadpool_size(sys_var *self, THD *thd, set_var *var) { + +#ifdef _WIN32 + if (threadpool_mode != TP_MODE_GENERIC) + return false; +#endif + ulonglong v= var->save_result.ulonglong_value; if (v > threadpool_max_size) { diff --git a/sql/sys_vars.ic b/sql/sys_vars.ic index f33f469b160..8e8ec4f00bc 100644 --- a/sql/sys_vars.ic +++ b/sql/sys_vars.ic @@ -501,7 +501,10 @@ public: String str2(buff2, sizeof(buff2), charset), *res; if (!(res=var->value->val_str(&str))) + { var->save_result.string_value.str= 0; + var->save_result.string_value.length= 0; // safety + } else { uint32 unused; @@ -895,9 +898,16 @@ public: String str(buff, sizeof(buff), system_charset_info), *res; if (!(res=var->value->val_str(&str))) + { var->save_result.string_value.str= const_cast<char*>(""); + var->save_result.string_value.length= 0; + } else - var->save_result.string_value.str= thd->strmake(res->ptr(), res->length()); + { + size_t len= res->length(); + var->save_result.string_value.str= thd->strmake(res->ptr(), len); + var->save_result.string_value.length= len; + } return false; } bool session_update(THD *thd, set_var *var) @@ -921,6 +931,7 @@ public: { char *ptr= (char*)(intptr)option.def_value; var->save_result.string_value.str= ptr; + var->save_result.string_value.length= safe_strlen(ptr); } uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) { diff --git a/sql/table.cc b/sql/table.cc index c8594d25851..ca0af28a79d 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -50,6 +50,17 @@ #define MYSQL57_GENERATED_FIELD 128 #define MYSQL57_GCOL_HEADER_SIZE 4 +class Table_arena: public Query_arena +{ +public: + Table_arena(MEM_ROOT *mem_root, enum enum_state state_arg) : + Query_arena(mem_root, state_arg){} + virtual Type type() const + { + return TABLE_ARENA; + } +}; + struct extra2_fields { LEX_CUSTRING version; @@ -1106,8 +1117,9 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, We need to use CONVENTIONAL_EXECUTION here to ensure that any new items created by fix_fields() are not reverted. */ - table->expr_arena= new (alloc_root(mem_root, sizeof(Query_arena))) - Query_arena(mem_root, Query_arena::STMT_CONVENTIONAL_EXECUTION); + table->expr_arena= new (alloc_root(mem_root, sizeof(Table_arena))) + Table_arena(mem_root, + Query_arena::STMT_CONVENTIONAL_EXECUTION); if (!table->expr_arena) DBUG_RETURN(1); diff --git a/sql/table.h b/sql/table.h index ea9f87b65ed..8db9fd735fb 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1637,6 +1637,7 @@ public: TABLE *tmp_table, TMP_TABLE_PARAM *tmp_table_param, bool with_cleanup); + int fix_vcol_exprs(THD *thd); Field *find_field_by_name(LEX_CSTRING *str) const; bool export_structure(THD *thd, class Row_definition_list *defs); bool is_splittable() { return spl_opt_info != NULL; } diff --git a/sql/threadpool.h b/sql/threadpool.h index 9145098be3f..817681e174f 100644 --- a/sql/threadpool.h +++ b/sql/threadpool.h @@ -78,6 +78,7 @@ enum TP_STATE { TP_STATE_IDLE, TP_STATE_RUNNING, + TP_STATE_PENDING }; /* diff --git a/sql/threadpool_common.cc b/sql/threadpool_common.cc index 3a0c7a8514c..00c28be6f9b 100644 --- a/sql/threadpool_common.cc +++ b/sql/threadpool_common.cc @@ -475,11 +475,25 @@ void tp_timeout_handler(TP_connection *c) { if (c->state != TP_STATE_IDLE) return; - THD *thd=c->thd; + THD *thd= c->thd; mysql_mutex_lock(&thd->LOCK_thd_kill); - thd->set_killed_no_mutex(KILL_WAIT_TIMEOUT); - c->priority= TP_PRIORITY_HIGH; - post_kill_notification(thd); + Vio *vio= thd->net.vio; + if (vio && (vio_pending(vio) > 0 || vio->has_data(vio)) && + c->state == TP_STATE_IDLE) + { + /* + There is some data on that connection, i.e + i.e there was no inactivity timeout. + Don't kill. + */ + c->state= TP_STATE_PENDING; + } + else if (c->state == TP_STATE_IDLE) + { + thd->set_killed_no_mutex(KILL_WAIT_TIMEOUT); + c->priority= TP_PRIORITY_HIGH; + post_kill_notification(thd); + } mysql_mutex_unlock(&thd->LOCK_thd_kill); } diff --git a/sql/threadpool_generic.cc b/sql/threadpool_generic.cc index f128661ec60..6d6b22d5900 100644 --- a/sql/threadpool_generic.cc +++ b/sql/threadpool_generic.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2012 Monty Program Ab +/* Copyright (C) 2012, 2020, 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 @@ -583,11 +583,21 @@ static my_bool timeout_check(THD *thd, pool_timer_t *timer) DBUG_ENTER("timeout_check"); if (thd->net.reading_or_writing == 1) { - /* - Check if connection does not have scheduler data. This happens for example - if THD belongs to a different scheduler, that is listening to extra_port. - */ - if (auto connection= (TP_connection_generic *) thd->event_scheduler.data) + TP_connection_generic *connection= (TP_connection_generic *)thd->event_scheduler.data; + if (!connection || connection->state != TP_STATE_IDLE) + { + /* + Connection does not have scheduler data. This happens for example + if THD belongs to a different scheduler, that is listening to extra_port. + */ + DBUG_RETURN(0); + } + + if(connection->abs_wait_timeout < timer->current_microtime) + { + tp_timeout_handler(connection); + } + else { if (connection->abs_wait_timeout < timer->current_microtime) tp_timeout_handler(connection); |