diff options
author | Sergei Golubchik <serg@mariadb.org> | 2017-08-25 10:25:48 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2017-08-25 10:25:48 +0200 |
commit | 27412877dbcf601676f4515a99b2abee1f19623b (patch) | |
tree | 2cb1a2e1a58ba10f2a96fcdec43f5ed77c326fd0 /sql | |
parent | f2033df6ac0f64664d9aad2d56fdd74f4bf9d666 (diff) | |
parent | a544225d0a772bd4b67c96f5861ecc0ef7e69bba (diff) | |
download | mariadb-git-27412877dbcf601676f4515a99b2abee1f19623b.tar.gz |
Merge branch '10.2' into bb-10.2-ext
Diffstat (limited to 'sql')
47 files changed, 595 insertions, 296 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 88a4e40e373..e5aacdc2092 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -486,7 +486,7 @@ IF(WIN32) TARGET_LINK_LIBRARIES(mysql_upgrade_service mysys winservice) ENDIF(WIN32) -INSTALL(DIRECTORY . DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT Development +INSTALL(DIRECTORY . DESTINATION ${INSTALL_INCLUDEDIR}/server/private COMPONENT Development FILES_MATCHING PATTERN "*.h" PATTERN share EXCLUDE PATTERN CMakeFiles EXCLUDE) diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc index b2a187b07cb..ab022c770b8 100644 --- a/sql/debug_sync.cc +++ b/sql/debug_sync.cc @@ -1505,7 +1505,7 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action) { if (!--action->hit_limit) { - thd->killed= KILL_QUERY; + thd->set_killed(KILL_QUERY); my_error(ER_DEBUG_SYNC_HIT_LIMIT, MYF(0)); } DBUG_PRINT("debug_sync_exec", ("hit_limit: %lu at: '%s'", diff --git a/sql/encryption.cc b/sql/encryption.cc index a92296e8b66..52eab262570 100644 --- a/sql/encryption.cc +++ b/sql/encryption.cc @@ -98,19 +98,27 @@ int initialize_encryption_plugin(st_plugin_int *plugin) int finalize_encryption_plugin(st_plugin_int *plugin) { - encryption_handler.encryption_key_get_func= - (uint (*)(uint, uint, uchar*, uint*))no_key; - encryption_handler.encryption_key_get_latest_version_func= no_key; - encryption_handler.encryption_ctx_size_func= zero_size; + bool used= plugin_ref_to_int(encryption_manager) == plugin; + + if (used) + { + encryption_handler.encryption_key_get_func= + (uint (*)(uint, uint, uchar*, uint*))no_key; + encryption_handler.encryption_key_get_latest_version_func= no_key; + encryption_handler.encryption_ctx_size_func= zero_size; + } if (plugin && plugin->plugin->deinit && plugin->plugin->deinit(NULL)) { DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.", plugin->name.str)); } - if (encryption_manager) + + if (used) + { plugin_unlock(NULL, encryption_manager); - encryption_manager= 0; + encryption_manager= 0; + } return 0; } diff --git a/sql/item.cc b/sql/item.cc index f84c2aff0a3..4468a01cc6f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2010, 2017, MariaDB + Copyright (c) 2010, 2017, 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 @@ -5028,7 +5028,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) int cur_match_degree= 0; /* SELECT list element with explicit alias */ - if ((*(cur_group->item))->name.str && + if ((*(cur_group->item))->name.str && !table_name && !(*(cur_group->item))->is_autogenerated_name && !my_strcasecmp(system_charset_info, (*(cur_group->item))->name.str, field_name->str)) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index fc076b766c2..46e5fb04a85 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5309,7 +5309,7 @@ void Regexp_processor_pcre::set_recursion_limit(THD *thd) DBUG_ASSERT(thd == current_thd); stack_used= available_stack_size(thd->thread_stack, &stack_used); m_pcre_extra.match_limit_recursion= - (my_thread_stack_size - stack_used)/my_pcre_frame_size; + (my_thread_stack_size - STACK_MIN_SIZE - stack_used)/my_pcre_frame_size; } @@ -5572,6 +5572,12 @@ void Regexp_processor_pcre::fix_owner(Item_func *owner, } +bool Item_func_regex::fix_fields(THD *thd, Item **ref) +{ + re.set_recursion_limit(thd); + return Item_bool_func::fix_fields(thd, ref); +} + void Item_func_regex::fix_length_and_dec() { @@ -5598,6 +5604,13 @@ longlong Item_func_regex::val_int() } +bool Item_func_regexp_instr::fix_fields(THD *thd, Item **ref) +{ + re.set_recursion_limit(thd); + return Item_int_func::fix_fields(thd, ref); +} + + void Item_func_regexp_instr::fix_length_and_dec() { diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 08e47d3df8f..c7272f1f2cc 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -2655,6 +2655,7 @@ public: DBUG_VOID_RETURN; } longlong val_int(); + bool fix_fields(THD *thd, Item **ref); void fix_length_and_dec(); const char *func_name() const { return "regexp"; } enum precedence precedence() const { return CMP_PRECEDENCE; } @@ -2699,6 +2700,7 @@ public: DBUG_VOID_RETURN; } longlong val_int(); + bool fix_fields(THD *thd, Item **ref); void fix_length_and_dec(); const char *func_name() const { return "regexp_instr"; } Item *get_copy(THD *thd, MEM_ROOT *mem_root) diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index 3d24c8137c9..dbaf2c6f6a3 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -643,17 +643,21 @@ error: static int alloc_tmp_paths(THD *thd, uint n_paths, - json_path_with_flags **paths,String **tmp_paths) + json_path_with_flags **paths, String **tmp_paths) { if (n_paths > 0) { - *paths= (json_path_with_flags *) alloc_root(thd->mem_root, - sizeof(json_path_with_flags) * n_paths); - *tmp_paths= (String *) alloc_root(thd->mem_root, sizeof(String) * n_paths); - if (*paths == 0 || *tmp_paths == 0) - return 1; + if (*tmp_paths == 0) + { + MEM_ROOT *root= thd->stmt_arena->mem_root; + *paths= (json_path_with_flags *) alloc_root(root, + sizeof(json_path_with_flags) * n_paths); + *tmp_paths= (String *) alloc_root(root, sizeof(String) * n_paths); + if (*paths == 0 || *tmp_paths == 0) + return 1; - bzero(*tmp_paths, sizeof(String) * n_paths); + bzero(*tmp_paths, sizeof(String) * n_paths); + } return 0; } @@ -687,7 +691,6 @@ void Item_json_str_multipath::cleanup() { for (uint i= get_n_paths(); i>0; i--) tmp_paths[i-1].free(); - tmp_paths= 0; } Item_str_func::cleanup(); } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 6138b67c02e..8de07f7cda5 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1363,6 +1363,13 @@ void Item_func_replace::fix_length_and_dec() /*********************************************************************/ +bool Item_func_regexp_replace::fix_fields(THD *thd, Item **ref) +{ + re.set_recursion_limit(thd); + return Item_str_func::fix_fields(thd, ref); +} + + void Item_func_regexp_replace::fix_length_and_dec() { if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 3)) @@ -1498,6 +1505,13 @@ err: } +bool Item_func_regexp_substr::fix_fields(THD *thd, Item **ref) +{ + re.set_recursion_limit(thd); + return Item_str_func::fix_fields(thd, ref); +} + + void Item_func_regexp_substr::fix_length_and_dec() { if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 2)) diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index c022282ab30..f9b6f96fb9a 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -399,6 +399,7 @@ public: DBUG_VOID_RETURN; } String *val_str(String *str); + bool fix_fields(THD *thd, Item **ref); void fix_length_and_dec(); const char *func_name() const { return "regexp_replace"; } Item *get_copy(THD *thd, MEM_ROOT *mem_root) @@ -421,6 +422,7 @@ public: DBUG_VOID_RETURN; } String *val_str(String *str); + bool fix_fields(THD *thd, Item **ref); void fix_length_and_dec(); const char *func_name() const { return "regexp_substr"; } Item *get_copy(THD *thd, MEM_ROOT *mem_root) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 36ce86fca29..d596d87b703 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -335,7 +335,8 @@ bool Item_subselect::enumerate_field_refs_processor(void *arg) while ((upper= it++)) { - if (upper->item->walk(&Item::enumerate_field_refs_processor, FALSE, arg)) + if (upper->item && + upper->item->walk(&Item::enumerate_field_refs_processor, FALSE, arg)) return TRUE; } return FALSE; @@ -3416,7 +3417,8 @@ bool Item_in_subselect::init_cond_guards() { DBUG_ASSERT(thd); uint cols_num= left_expr->cols(); - if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards) + if (!abort_on_null && !pushed_cond_guards && + (left_expr->maybe_null || cols_num > 1)) { if (!(pushed_cond_guards= (bool*)thd->alloc(sizeof(bool) * cols_num))) return TRUE; diff --git a/sql/log.cc b/sql/log.cc index 166180e08a4..766f45182a5 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -9800,8 +9800,8 @@ int TC_LOG_BINLOG::recover(LOG_INFO *linfo, const char *last_log_name, sizeof(xev->xid)); if (!x || my_hash_insert(&xids, x)) goto err2; - break; } + break; } case BINLOG_CHECKPOINT_EVENT: if (first_round && do_xa) diff --git a/sql/log_event.cc b/sql/log_event.cc index 8f2a61f12a4..7edcaf1c015 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -390,12 +390,6 @@ static void pretty_print_str(IO_CACHE* cache, const char* str, int len) #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -static void clear_all_errors(THD *thd, Relay_log_info *rli) -{ - thd->is_slave_error = 0; - thd->clear_error(); -} - inline int idempotent_error_code(int err_code) { int ret= 0; @@ -5058,7 +5052,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos)); - clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); + thd->clear_error(1); current_stmt_is_commit= is_commit(); DBUG_ASSERT(!current_stmt_is_commit || !rgi->tables_to_lock); @@ -5279,7 +5273,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, to check/fix it. */ if (mysql_test_parse_for_slave(thd, thd->query(), thd->query_length())) - clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */ + thd->clear_error(1); else { rli->report(ERROR_LEVEL, expected_error, rgi->gtid_info(), @@ -5361,7 +5355,7 @@ compare_errors: ignored_error_code(actual_error)) { DBUG_PRINT("info",("error ignored")); - clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); + thd->clear_error(1); if (actual_error == ER_QUERY_INTERRUPTED || actual_error == ER_CONNECTION_KILLED) thd->reset_killed(); @@ -6840,8 +6834,7 @@ int Load_log_event::do_apply_event(NET* net, rpl_group_info *rgi, 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); - thd->is_slave_error= 0; - clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); + thd->clear_error(1); /* see Query_log_event::do_apply_event() and BUG#13360 */ DBUG_ASSERT(!rgi->m_table_map.count()); @@ -6851,7 +6844,7 @@ int Load_log_event::do_apply_event(NET* net, rpl_group_info *rgi, */ lex_start(thd); thd->lex->local_file= local_fname; - thd->reset_for_next_command(); + thd->reset_for_next_command(0); // Errors are cleared above /* We test replicate_*_db rules. Note that we have already prepared @@ -10952,7 +10945,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) slave_rows_error_report(WARNING_LEVEL, error, rgi, thd, table, get_type_str(), RPL_LOG_NAME, (ulong) log_pos); - clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); + thd->clear_error(1); error= 0; if (idempotent_error == 0) break; @@ -11004,7 +10997,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) slave_rows_error_report(WARNING_LEVEL, error, rgi, thd, table, get_type_str(), RPL_LOG_NAME, (ulong) log_pos); - clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); + thd->clear_error(1); error= 0; } } // if (table) diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc index 53d0c3204a1..50918d8dcf2 100644 --- a/sql/multi_range_read.cc +++ b/sql/multi_range_read.cc @@ -1224,28 +1224,18 @@ bool DsMrr_impl::setup_buffer_sharing(uint key_size_in_keybuf, ptrdiff_t bytes_for_keys= (full_buf_end - full_buf) - bytes_for_rowids; - if (bytes_for_keys < key_buff_elem_size + 1) - { - ptrdiff_t add= key_buff_elem_size + 1 - bytes_for_keys; - bytes_for_keys= key_buff_elem_size + 1; - bytes_for_rowids -= add; - } - - if (bytes_for_rowids < (ptrdiff_t)rowid_buf_elem_size + 1) - { - ptrdiff_t add= (ptrdiff_t)(rowid_buf_elem_size + 1 - bytes_for_rowids); - bytes_for_rowids= (ptrdiff_t)rowid_buf_elem_size + 1; - bytes_for_keys -= add; - } + if (bytes_for_keys < key_buff_elem_size + 1 || + bytes_for_rowids < (ptrdiff_t)rowid_buf_elem_size + 1) + return TRUE; /* Failed to provide minimum space for one of the buffers */ rowid_buffer_end= full_buf + bytes_for_rowids; rowid_buffer.set_buffer_space(full_buf, rowid_buffer_end); key_buffer= &backward_key_buf; key_buffer->set_buffer_space(rowid_buffer_end, full_buf_end); - if (!key_buffer->have_space_for(key_buff_elem_size) || - !rowid_buffer.have_space_for((size_t)rowid_buf_elem_size)) - return TRUE; /* Failed to provide minimum space for one of the buffers */ + /* The above code guarantees that the buffers are big enough */ + DBUG_ASSERT(key_buffer->have_space_for(key_buff_elem_size) && + rowid_buffer.have_space_for((size_t)rowid_buf_elem_size)); return FALSE; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index eb7bf088442..6f9490826a7 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -913,7 +913,7 @@ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list, key_LOCK_prepared_stmt_count, key_LOCK_rpl_status, key_LOCK_server_started, key_LOCK_status, key_LOCK_show_status, - key_LOCK_system_variables_hash, key_LOCK_thd_data, + key_LOCK_system_variables_hash, key_LOCK_thd_data, key_LOCK_thd_kill, key_LOCK_user_conn, key_LOCK_uuid_short_generator, key_LOG_LOCK_log, key_master_info_data_lock, key_master_info_run_lock, key_master_info_sleep_lock, key_master_info_start_stop_lock, @@ -985,6 +985,7 @@ static PSI_mutex_info all_server_mutexes[]= { &key_LOCK_wait_commit, "wait_for_commit::LOCK_wait_commit", 0}, { &key_LOCK_gtid_waiting, "gtid_waiting::LOCK_gtid_waiting", 0}, { &key_LOCK_thd_data, "THD::LOCK_thd_data", 0}, + { &key_LOCK_thd_kill, "THD::LOCK_thd_kill", 0}, { &key_LOCK_user_conn, "LOCK_user_conn", PSI_FLAG_GLOBAL}, { &key_LOCK_uuid_short_generator, "LOCK_uuid_short_generator", PSI_FLAG_GLOBAL}, { &key_LOG_LOCK_log, "LOG::LOCK_log", 0}, @@ -1687,16 +1688,20 @@ static void close_connections(void) { DBUG_PRINT("quit",("Informing thread %ld that it's time to die", (ulong) tmp->thread_id)); - /* We skip slave threads & scheduler on this first loop through. */ + /* We skip slave threads on this first loop through. */ if (tmp->slave_thread) continue; + /* cannot use 'continue' inside DBUG_EXECUTE_IF()... */ + if (DBUG_EVALUATE_IF("only_kill_system_threads", !tmp->system_thread, 0)) + continue; + #ifdef WITH_WSREP /* skip wsrep system threads as well */ if (WSREP(tmp) && (tmp->wsrep_exec_mode==REPL_RECV || tmp->wsrep_applier)) continue; #endif - tmp->killed= KILL_SERVER_HARD; + tmp->set_killed(KILL_SERVER_HARD); MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (tmp)); mysql_mutex_lock(&tmp->LOCK_thd_data); if (tmp->mysys_var) @@ -1786,7 +1791,7 @@ static void close_connections(void) if (WSREP(tmp) && tmp->wsrep_exec_mode==REPL_RECV) { sql_print_information("closing wsrep system thread"); - tmp->killed= KILL_CONNECTION; + tmp->set_killed(KILL_CONNECTION); MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (tmp)); if (tmp->mysys_var) { @@ -3677,7 +3682,6 @@ sizeof(load_default_groups)/sizeof(load_default_groups[0]); #endif -#ifndef EMBEDDED_LIBRARY /** This function is used to check for stack overrun for pathological cases of regular expressions and 'like' expressions. @@ -3706,8 +3710,6 @@ check_enough_stack_size(int recurse_level) return 0; return check_enough_stack_size_slow(); } -#endif - /* @@ -3729,11 +3731,12 @@ static void init_pcre() { pcre_malloc= pcre_stack_malloc= my_str_malloc_mysqld; pcre_free= pcre_stack_free= my_str_free_mysqld; -#ifndef EMBEDDED_LIBRARY pcre_stack_guard= check_enough_stack_size_slow; /* See http://pcre.org/original/doc/html/pcrestack.html */ - my_pcre_frame_size= -pcre_exec(NULL, NULL, NULL, -999, -999, 0, NULL, 0) + 16; -#endif + my_pcre_frame_size= -pcre_exec(NULL, NULL, NULL, -999, -999, 0, NULL, 0); + // pcre can underestimate its stack usage. Use a safe value, as in the manual + set_if_bigger(my_pcre_frame_size, 500); + my_pcre_frame_size += 16; // Again, safety margin, see the manual } @@ -4041,11 +4044,16 @@ static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific) thd->status_var.local_memory_used > (int64)thd->variables.max_mem_used && !thd->killed && !thd->get_stmt_da()->is_set()) { - char buf[1024]; - thd->killed= KILL_QUERY; + /* Ensure we don't get called here again */ + char buf[50], *buf2; + thd->set_killed(KILL_QUERY); my_snprintf(buf, sizeof(buf), "--max-thread-mem-used=%llu", thd->variables.max_mem_used); - my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), buf); + if ((buf2= (char*) thd->alloc(256))) + { + my_snprintf(buf2, 256, ER_THD(thd, ER_OPTION_PREVENTS_STATEMENT), buf); + thd->set_killed(KILL_QUERY, ER_OPTION_PREVENTS_STATEMENT, buf2); + } } DBUG_ASSERT((longlong) thd->status_var.local_memory_used >= 0 || !debug_assert_on_not_freed_memory); @@ -4412,12 +4420,7 @@ static int init_common_variables() /* Fix back_log (back_log == 0 added for MySQL compatibility) */ if (back_log == 0 || IS_SYSVAR_AUTOSIZE(&back_log)) - { - if ((900 - 50) * 5 >= max_connections) - SYSVAR_AUTOSIZE(back_log, (50 + max_connections / 5)); - else - SYSVAR_AUTOSIZE(back_log, 900); - } + SYSVAR_AUTOSIZE(back_log, MY_MIN(900, (50 + max_connections / 5))); /* connections and databases needs lots of files */ { @@ -9676,8 +9679,6 @@ static int get_options(int *argc_ptr, char ***argv_ptr) #endif /* Ensure that some variables are not set higher than needed */ - if (back_log > max_connections) - SYSVAR_AUTOSIZE(back_log, max_connections); if (thread_cache_size > max_connections) SYSVAR_AUTOSIZE(thread_cache_size, max_connections); diff --git a/sql/mysqld.h b/sql/mysqld.h index 38e42dd61f1..98fc58e07c5 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -293,7 +293,7 @@ extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list, key_LOCK_prepared_stmt_count, key_LOCK_rpl_status, key_LOCK_server_started, key_LOCK_status, key_LOCK_show_status, - key_LOCK_thd_data, + key_LOCK_thd_data, key_LOCK_thd_kill, key_LOCK_user_conn, key_LOG_LOCK_log, key_master_info_data_lock, key_master_info_run_lock, key_master_info_sleep_lock, key_master_info_start_stop_lock, diff --git a/sql/net_serv.cc b/sql/net_serv.cc index f9635689e63..d9d35c5ed3f 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, 2016, MariaDB + Copyright (c) 2012, 2017, 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/opt_range.cc b/sql/opt_range.cc index 9161dee7836..843f66b5097 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -10911,13 +10911,13 @@ int read_keys_and_merge_scans(THD *thd, DBUG_ENTER("read_keys_and_merge"); /* We're going to just read rowids. */ - head->file->ha_start_keyread(head->s->primary_key); head->prepare_for_position(); cur_quick_it.rewind(); cur_quick= cur_quick_it++; bool first_quick= TRUE; DBUG_ASSERT(cur_quick != 0); + head->file->ha_start_keyread(cur_quick->index); /* We reuse the same instance of handler so we need to call both init and diff --git a/sql/records.cc b/sql/records.cc index 3ec9ea814cc..f16bdcff6e6 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -1,5 +1,6 @@ /* Copyright (c) 2000, 2010, Oracle and/or its affiliates. + Copyright (c) 2009, 2017, 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/rpl_handler.cc b/sql/rpl_handler.cc index 733af6c61c8..520fb61d8c4 100644 --- a/sql/rpl_handler.cc +++ b/sql/rpl_handler.cc @@ -267,7 +267,7 @@ int Binlog_storage_delegate::after_flush(THD *thd, thd->semisync_info= log_info; } - strcpy(log_info->log_file, log_file+dirname_length(log_file)); + strmake_buf(log_info->log_file, log_file+dirname_length(log_file)); log_info->log_pos = log_pos; FOREACH_OBSERVER(ret, after_flush, false, diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index e90557efd0d..96d9ee4a1b4 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2006, 2012, Oracle and/or its affiliates. - Copyright (c) 2010, 2011, Monty Program Ab +/* Copyright (c) 2006, 2017, Oracle and/or its affiliates. + Copyright (c) 2010, 2017, 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 @@ -843,7 +843,6 @@ void end_master_info(Master_info* mi) if (!mi->inited) DBUG_VOID_RETURN; - end_relay_log_info(&mi->rli); if (mi->fd >= 0) { end_io_cache(&mi->file); @@ -882,6 +881,7 @@ void free_key_master_info(Master_info *mi) /* We use 2 here instead of 1 just to make it easier when debugging */ mi->killed= 2; end_master_info(mi); + end_relay_log_info(&mi->rli); mi->unlock_slave_threads(); delete mi; diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc index aaa72da29db..433e7ea03c8 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -720,9 +720,7 @@ do_retry: DBUG_EXECUTE_IF("inject_mdev8031", { /* Simulate that we get deadlock killed at this exact point. */ rgi->killed_for_retry= rpl_group_info::RETRY_KILL_KILLED; - mysql_mutex_lock(&thd->LOCK_thd_data); - thd->killed= KILL_CONNECTION; - mysql_mutex_unlock(&thd->LOCK_thd_data); + thd->set_killed(KILL_CONNECTION); }); rgi->cleanup_context(thd, 1); wait_for_pending_deadlock_kill(thd, rgi); @@ -868,9 +866,7 @@ do_retry: /* Simulate that we get deadlock killed during open_binlog(). */ thd->reset_for_next_command(); rgi->killed_for_retry= rpl_group_info::RETRY_KILL_KILLED; - mysql_mutex_lock(&thd->LOCK_thd_data); - thd->killed= KILL_CONNECTION; - mysql_mutex_unlock(&thd->LOCK_thd_data); + thd->set_killed(KILL_CONNECTION); thd->send_kill_message(); fd= (File)-1; err= 1; diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 9bdb096a116..f5069682223 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -1,6 +1,5 @@ -/* Copyright (c) 2006, 2013, Oracle and/or its affiliates. - Copyright (c) 2010, 2013, Monty Program Ab - Copyright (c) 2016, MariaDB Corporation +/* Copyright (c) 2006, 2017, Oracle and/or its affiliates. + Copyright (c) 2010, 2017, 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 @@ -52,8 +51,8 @@ Relay_log_info::Relay_log_info(bool is_slave_recovery) sync_counter(0), is_relay_log_recovery(is_slave_recovery), save_temporary_tables(0), mi(0), inuse_relaylog_list(0), last_inuse_relaylog(0), - cur_log_old_open_count(0), group_relay_log_pos(0), - event_relay_log_pos(0), + cur_log_old_open_count(0), error_on_rli_init_info(false), + group_relay_log_pos(0), event_relay_log_pos(0), group_master_log_pos(0), log_space_total(0), ignore_log_space_limit(0), last_master_timestamp(0), sql_thread_caught_up(true), slave_skip_counter(0), abort_pos_wait(0), slave_run_id(0), sql_driver_thd(), @@ -139,6 +138,9 @@ int Relay_log_info::init(const char* info_fname) log_space_limit= relay_log_space_limit; log_space_total= 0; + if (error_on_rli_init_info) + goto err; + char pattern[FN_REFLEN]; (void) my_realpath(pattern, slave_load_tmpdir, 0); if (fn_format(pattern, PREFIX_SQL_LOAD, pattern, "", @@ -254,8 +256,8 @@ a file name for --relay-log-index option", opt_relaylog_index_name); if ((info_fd= mysql_file_open(key_file_relay_log_info, fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0) { - sql_print_error("Failed to create a new relay log info file (\ -file '%s', errno %d)", fname, my_errno); + sql_print_error("Failed to create a new relay log info file (" + "file '%s', errno %d)", fname, my_errno); msg= current_thd->get_stmt_da()->message(); goto err; } @@ -420,11 +422,14 @@ Failed to open the existing relay log info file '%s' (errno %d)", goto err; } inited= 1; + error_on_rli_init_info= false; mysql_mutex_unlock(&data_lock); DBUG_RETURN(0); err: - sql_print_error("%s", msg); + error_on_rli_init_info= true; + if (msg) + sql_print_error("%s", msg); end_io_cache(&info_file); if (info_fd >= 0) mysql_file_close(info_fd, MYF(0)); @@ -1129,6 +1134,8 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset, const char** errmsg) { int error=0; + const char *ln; + char name_buf[FN_REFLEN]; DBUG_ENTER("purge_relay_logs"); /* @@ -1155,12 +1162,37 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset, if (!rli->inited) { DBUG_PRINT("info", ("rli->inited == 0")); - DBUG_RETURN(0); - } - - DBUG_ASSERT(rli->slave_running == 0); - DBUG_ASSERT(rli->mi->slave_running == 0); + if (rli->error_on_rli_init_info) + { + ln= rli->relay_log.generate_name(opt_relay_logname, "-relay-bin", + 1, name_buf); + if (rli->relay_log.open_index_file(opt_relaylog_index_name, ln, TRUE)) + { + sql_print_error("Unable to purge relay log files. Failed to open relay " + "log index file:%s.", rli->relay_log.get_index_fname()); + DBUG_RETURN(1); + } + mysql_mutex_lock(rli->relay_log.get_log_lock()); + if (rli->relay_log.open(ln, LOG_BIN, 0, 0, SEQ_READ_APPEND, + (rli->max_relay_log_size ? rli->max_relay_log_size : + max_binlog_size), 1, TRUE)) + { + sql_print_error("Unable to purge relay log files. Failed to open relay " + "log file:%s.", rli->relay_log.get_log_fname()); + mysql_mutex_unlock(rli->relay_log.get_log_lock()); + DBUG_RETURN(1); + } + mysql_mutex_unlock(rli->relay_log.get_log_lock()); + } + else + DBUG_RETURN(0); + } + else + { + DBUG_ASSERT(rli->slave_running == 0); + DBUG_ASSERT(rli->mi->slave_running == 0); + } mysql_mutex_lock(&rli->data_lock); /* @@ -1207,6 +1239,12 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset, rli->group_relay_log_name[0]= rli->event_relay_log_name[0]= 0; } + if (!rli->inited && rli->error_on_rli_init_info) + { + mysql_mutex_lock(rli->relay_log.get_log_lock()); + rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT); + mysql_mutex_unlock(rli->relay_log.get_log_lock()); + } err: DBUG_PRINT("info",("log_space_total: %llu",rli->log_space_total)); mysql_mutex_unlock(&rli->data_lock); diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index 448fc231b2b..d88bc9f6ecd 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -1,4 +1,5 @@ -/* Copyright (c) 2005, 2012, Oracle and/or its affiliates. +/* Copyright (c) 2005, 2017, Oracle and/or its affiliates. + Copyright (c) 2009, 2017, 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 @@ -177,7 +178,14 @@ public: a different log under our feet */ uint32 cur_log_old_open_count; - + + /* + If on init_info() call error_on_rli_init_info is true that means + that previous call to init_info() terminated with an error, RESET + SLAVE must be executed and the problem fixed manually. + */ + bool error_on_rli_init_info; + /* Let's call a group (of events) : - a transaction diff --git a/sql/slave.cc b/sql/slave.cc index 746d7c12ef1..00dc02a6f48 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2009, 2017, MariaDB +/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. + Copyright (c) 2009, 2017, 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 @@ -481,6 +481,7 @@ int init_slave() { delete active_mi; active_mi= 0; + sql_print_error("Failed to allocate memory for the Master Info structure"); goto err; } @@ -543,7 +544,6 @@ end: DBUG_RETURN(error); err: - sql_print_error("Failed to allocate memory for the Master Info structure"); error= 1; goto end; } @@ -6556,6 +6556,7 @@ void end_relay_log_info(Relay_log_info* rli) mysql_mutex_t *log_lock; DBUG_ENTER("end_relay_log_info"); + rli->error_on_rli_init_info= false; if (!rli->inited) DBUG_VOID_RETURN; if (rli->info_fd >= 0) diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 3ceba42b0e4..a684265ee66 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -534,8 +534,7 @@ bool sp_rcontext::handle_sql_condition(THD *thd, /* Reset error state. */ thd->clear_error(); - thd->killed= NOT_KILLED; // Some errors set thd->killed - // (e.g. "bad data"). + thd->reset_killed(); // Some errors set thd->killed, (e.g. "bad data"). /* Add a frame to handler-call-stack. */ Sql_condition_info *cond_info= diff --git a/sql/spatial.cc b/sql/spatial.cc index 1ba754b6b13..8817e82d6c4 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -1663,8 +1663,8 @@ int Gis_polygon::centroid_xy(double *x, double *y) const uint32 n_points, org_n_points; double prev_x, prev_y; double cur_area= 0; - double cur_cx= 0; - double cur_cy= 0; + double cur_cx= 0, cur_cy= 0; + double sum_cx= 0, sum_cy= 0; if (no_data(data, 4)) return 1; @@ -1678,17 +1678,32 @@ int Gis_polygon::centroid_xy(double *x, double *y) const while (--n_points) // One point is already read { double tmp_x, tmp_y; + double loc_area; get_point(&tmp_x, &tmp_y, data); data+= POINT_DATA_SIZE; - cur_area+= (prev_x + tmp_x) * (prev_y - tmp_y); + loc_area= prev_x * tmp_y - tmp_x * prev_y; + cur_area+= loc_area; cur_cx+= tmp_x; cur_cy+= tmp_y; + sum_cx+= (prev_x + tmp_x) * loc_area; + sum_cy+= (prev_y + tmp_y) * loc_area; + prev_x= tmp_x; prev_y= tmp_y; } - cur_area= fabs(cur_area) / 2; - cur_cx= cur_cx / (org_n_points - 1); - cur_cy= cur_cy / (org_n_points - 1); + + if (fabs(cur_area) > 1e-10) + { + cur_cx= sum_cx / cur_area / 3.0; + cur_cy= sum_cy / cur_area / 3.0; + } + else + { + cur_cx= cur_cx / (org_n_points - 1); + cur_cy= cur_cy / (org_n_points - 1); + } + + cur_area= fabs(cur_area); if (!first_loop) { diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 60247c83a08..8c724ee8561 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -8379,7 +8379,7 @@ bool mysql_notify_thread_having_shared_lock(THD *thd, THD *in_use, if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) && !in_use->killed) { - in_use->killed= KILL_SYSTEM_THREAD; + in_use->set_killed(KILL_SYSTEM_THREAD); mysql_mutex_lock(&in_use->mysys_var->mutex); if (in_use->mysys_var->current_cond) { diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 96a64697390..3db6e6a68c1 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -2189,8 +2189,7 @@ lookup: response, we can't handle it anyway. */ (void) trans_commit_stmt(thd); - if (!thd->get_stmt_da()->is_set()) - thd->get_stmt_da()->disable_status(); + thd->get_stmt_da()->disable_status(); BLOCK_UNLOCK_RD(query_block); MYSQL_QUERY_CACHE_HIT(thd->query(), (ulong) thd->limit_found_rows); @@ -4644,7 +4643,7 @@ void Query_cache::wreck(uint line, const char *message) DBUG_PRINT("warning", ("%5d QUERY CACHE WRECK => DISABLED",line)); DBUG_PRINT("warning", ("==================================")); if (thd) - thd->killed= KILL_CONNECTION; + thd->set_killed(KILL_CONNECTION); cache_dump(); /* check_integrity(0); */ /* Can't call it here because of locks */ bins_dump(); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 2e3c5bd4b41..d196b072705 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -554,6 +554,9 @@ char *thd_get_error_context_description(THD *thd, char *buffer, const Security_context *sctx= &thd->main_security_ctx; char header[256]; int len; + + mysql_mutex_lock(&LOCK_thread_count); + /* The pointers thd->query and thd->proc_info might change since they are being modified concurrently. This is acceptable for proc_info since its @@ -609,6 +612,7 @@ char *thd_get_error_context_description(THD *thd, char *buffer, } mysql_mutex_unlock(&thd->LOCK_thd_data); } + mysql_mutex_unlock(&LOCK_thread_count); if (str.c_ptr_safe() == buffer) return buffer; @@ -800,6 +804,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) query_start_used= query_start_sec_part_used= 0; count_cuted_fields= CHECK_FIELD_IGNORE; killed= NOT_KILLED; + killed_err= 0; col_access=0; is_slave_error= thread_specific_used= FALSE; my_hash_clear(&handler_tables_hash); @@ -855,6 +860,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) #endif mysql_mutex_init(key_LOCK_thd_data, &LOCK_thd_data, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_wakeup_ready, &LOCK_wakeup_ready, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_LOCK_thd_kill, &LOCK_thd_kill, MY_MUTEX_INIT_FAST); mysql_cond_init(key_COND_wakeup_ready, &COND_wakeup_ready, 0); /* LOCK_thread_count goes before LOCK_thd_data - the former is called around @@ -1475,7 +1481,7 @@ void THD::cleanup(void) DBUG_ENTER("THD::cleanup"); DBUG_ASSERT(cleanup_done == 0); - killed= KILL_CONNECTION; + set_killed(KILL_CONNECTION); #ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE if (transaction.xid_state.xa_state == XA_PREPARED) { @@ -1635,6 +1641,7 @@ THD::~THD() mysql_cond_destroy(&COND_wakeup_ready); mysql_mutex_destroy(&LOCK_wakeup_ready); mysql_mutex_destroy(&LOCK_thd_data); + mysql_mutex_destroy(&LOCK_thd_kill); #ifndef DBUG_OFF dbug_sentry= THD_SENTRY_GONE; #endif @@ -1812,7 +1819,8 @@ void THD::awake(killed_state state_to_set) state_to_set= killed; /* Set the 'killed' flag of 'this', which is the target THD object. */ - killed= state_to_set; + mysql_mutex_lock(&LOCK_thd_kill); + set_killed_no_mutex(state_to_set); if (state_to_set >= KILL_CONNECTION || state_to_set == NOT_KILLED) { @@ -1898,6 +1906,7 @@ void THD::awake(killed_state state_to_set) } mysql_mutex_unlock(&mysys_var->mutex); } + mysql_mutex_unlock(&LOCK_thd_kill); DBUG_VOID_RETURN; } @@ -1915,7 +1924,7 @@ void THD::disconnect() mysql_mutex_lock(&LOCK_thd_data); - killed= KILL_CONNECTION; + set_killed(KILL_CONNECTION); #ifdef SIGNAL_WITH_VIO_CLOSE /* @@ -1951,7 +1960,7 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use, DBUG_PRINT("info", ("kill delayed thread")); mysql_mutex_lock(&in_use->LOCK_thd_data); if (in_use->killed < KILL_CONNECTION) - in_use->killed= KILL_CONNECTION; + in_use->set_killed(KILL_CONNECTION); if (in_use->mysys_var) { mysql_mutex_lock(&in_use->mysys_var->mutex); @@ -2004,13 +2013,21 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use, /* Get error number for killed state Note that the error message can't have any parameters. + If one needs parameters, one should use THD::killed_err_msg See thd::kill_message() */ -int killed_errno(killed_state killed) +int THD::killed_errno() { DBUG_ENTER("killed_errno"); - DBUG_PRINT("enter", ("killed: %d", killed)); + DBUG_PRINT("enter", ("killed: %d killed_errno: %d", + killed, killed_err ? killed_err->no: 0)); + + /* Ensure that killed_err is not set if we are not killed */ + DBUG_ASSERT(!killed_err || killed != NOT_KILLED); + + if (killed_err) + DBUG_RETURN(killed_err->no); switch (killed) { case NOT_KILLED: @@ -2486,7 +2503,7 @@ CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length) { my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_FATALERROR), ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1); - killed= KILL_CONNECTION; + set_killed(KILL_CONNECTION); return 0; } diff --git a/sql/sql_class.h b/sql/sql_class.h index f30b4426fbc..1872cd9c1a8 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -480,7 +480,6 @@ enum killed_state }; -extern int killed_errno(killed_state killed); #define killed_mask_hard(killed) ((killed_state) ((killed) & ~KILL_HARD_BIT)) enum killed_type @@ -2043,7 +2042,7 @@ public: rpl_sql_thread_info *rpl_sql_info; } system_thread_info; - void reset_for_next_command(); + void reset_for_next_command(bool do_clear_errors= 1); /* Constant for THD::where initialization in the beginning of every query. @@ -2099,6 +2098,8 @@ public: Is locked when THD is deleted. */ mysql_mutex_t LOCK_thd_data; + /* Protect kill information */ + mysql_mutex_t LOCK_thd_kill; /* all prepared statements and cursors of this connection */ Statement_map stmt_map; @@ -2747,7 +2748,7 @@ public: void check_limit_rows_examined() { if (++accessed_rows_and_keys > lex->limit_rows_examined_cnt) - killed= ABORT_QUERY; + set_killed(ABORT_QUERY); } USER_CONN *user_connect; @@ -2848,6 +2849,16 @@ public: */ killed_state volatile killed; + /* + The following is used if one wants to have a specific error number and + text for the kill + */ + struct err_info + { + int no; + const char msg[256]; + } *killed_err; + /* See also thd_killed() */ inline bool check_killed() { @@ -3455,18 +3466,18 @@ public: @todo: To silence an error, one should use Internal_error_handler mechanism. Issuing an error that can be possibly later "cleared" is not compatible with other installed error handlers and audit plugins. - In future this function will be removed. */ - inline void clear_error() + inline void clear_error(bool clear_diagnostics= 0) { DBUG_ENTER("clear_error"); - if (get_stmt_da()->is_error()) + if (get_stmt_da()->is_error() || clear_diagnostics) get_stmt_da()->reset_diagnostics_area(); is_slave_error= 0; if (killed == KILL_BAD_DATA) - killed= NOT_KILLED; // KILL_BAD_DATA can be reset w/o a mutex + reset_killed(); DBUG_VOID_RETURN; } + #ifndef EMBEDDED_LIBRARY inline bool vio_ok() const { return net.vio != 0; } /** Return FALSE if connection to client is broken. */ @@ -3598,10 +3609,54 @@ public: state after execution of a non-prepared SQL statement. */ void end_statement(); - inline int killed_errno() const + + /* + Mark thread to be killed, with optional error number and string. + string is not released, so it has to be allocted on thd mem_root + or be a global string + + Ensure that we don't replace a kill with a lesser one. For example + if user has done 'kill_connection' we shouldn't replace it with + KILL_QUERY. + */ + inline void set_killed(killed_state killed_arg, + int killed_errno_arg= 0, + const char *killed_err_msg_arg= 0) { - return ::killed_errno(killed); + mysql_mutex_lock(&LOCK_thd_kill); + set_killed_no_mutex(killed_arg, killed_errno_arg, killed_err_msg_arg); + mysql_mutex_unlock(&LOCK_thd_kill); } + /* + This is only used by THD::awake where we need to keep the lock mutex + locked over some time. + It's ok to have this inline, as in most cases killed_errno_arg will + be a constant 0 and most of the function will disappear. + */ + inline void set_killed_no_mutex(killed_state killed_arg, + int killed_errno_arg= 0, + const char *killed_err_msg_arg= 0) + { + if (killed <= killed_arg) + { + killed= killed_arg; + if (killed_errno_arg) + { + /* + If alloc fails, we only remember the killed flag. + The worst things that can happen is that we get + a suboptimal error message. + */ + if ((killed_err= (err_info*) alloc(sizeof(*killed_err)))) + { + killed_err->no= killed_errno_arg; + ::strmake((char*) killed_err->msg, killed_err_msg_arg, + sizeof(killed_err->msg)-1); + } + } + } + } + int killed_errno(); inline void reset_killed() { /* @@ -3610,9 +3665,10 @@ public: */ if (killed != NOT_KILLED) { - mysql_mutex_lock(&LOCK_thd_data); + mysql_mutex_lock(&LOCK_thd_kill); killed= NOT_KILLED; - mysql_mutex_unlock(&LOCK_thd_data); + killed_err= 0; + mysql_mutex_unlock(&LOCK_thd_kill); } } inline void reset_kill_query() @@ -3623,11 +3679,14 @@ public: mysys_var->abort= 0; } } - inline void send_kill_message() const + inline void send_kill_message() { + mysql_mutex_lock(&LOCK_thd_kill); int err= killed_errno(); if (err) - my_message(err, ER_THD(this, err), MYF(0)); + my_message(err, killed_err ? killed_err->msg : ER_THD(this, err), + MYF(0)); + mysql_mutex_unlock(&LOCK_thd_kill); } /* return TRUE if we will abort query if we make a warning now */ inline bool really_abort_on_warning() diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 168814bcc81..0e5d8d43c0c 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1196,7 +1196,7 @@ void prepare_new_connection_state(THD* thd) if (thd->is_error()) { Host_errors errors; - thd->killed= KILL_CONNECTION; + thd->set_killed(KILL_CONNECTION); thd->print_aborted_warning(0, "init_connect command failed"); sql_print_warning("%s", thd->get_stmt_da()->message()); diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index bf1a777f50c..adcba993345 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -520,6 +520,8 @@ bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived) derived->merge_underlying_list != 0)); if (derived->merged_for_insert) DBUG_RETURN(FALSE); + if (derived->init_derived(thd, FALSE)) + DBUG_RETURN(TRUE); if (derived->is_materialized_derived()) DBUG_RETURN(mysql_derived_prepare(thd, lex, derived)); if ((thd->lex->sql_command == SQLCOM_UPDATE_MULTI || diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 6e6a3228d80..1bfde721a34 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2702,7 +2702,7 @@ void kill_delayed_threads(void) { mysql_mutex_lock(&di->thd.LOCK_thd_data); if (di->thd.killed < KILL_CONNECTION) - di->thd.killed= KILL_CONNECTION; + di->thd.set_killed(KILL_CONNECTION); if (di->thd.mysys_var) { mysql_mutex_lock(&di->thd.mysys_var->mutex); @@ -2846,7 +2846,7 @@ pthread_handler_t handle_delayed_insert(void *arg) thd->set_current_time(); add_to_active_threads(thd); if (abort_loop) - thd->killed= KILL_CONNECTION; + thd->set_killed(KILL_CONNECTION); else thd->reset_killed(); @@ -2992,7 +2992,7 @@ pthread_handler_t handle_delayed_insert(void *arg) } #endif if (error == ETIMEDOUT || error == ETIME) - thd->killed= KILL_CONNECTION; + thd->set_killed(KILL_CONNECTION); } /* We can't lock di->mutex and mysys_var->mutex at the same time */ mysql_mutex_unlock(&di->mutex); @@ -3021,7 +3021,7 @@ pthread_handler_t handle_delayed_insert(void *arg) if (! (thd->lock= mysql_lock_tables(thd, &di->table, 1, 0))) { /* Fatal error */ - thd->killed= KILL_CONNECTION; + thd->set_killed(KILL_CONNECTION); } mysql_cond_broadcast(&di->cond_client); } @@ -3030,7 +3030,7 @@ pthread_handler_t handle_delayed_insert(void *arg) if (di->handle_inserts()) { /* Some fatal error */ - thd->killed= KILL_CONNECTION; + thd->set_killed(KILL_CONNECTION); } } di->status=0; @@ -3074,7 +3074,7 @@ pthread_handler_t handle_delayed_insert(void *arg) this. */ mysql_mutex_lock(&thd->LOCK_thd_data); - thd->killed= KILL_CONNECTION_HARD; // If error + thd->set_killed(KILL_CONNECTION_HARD); // If error thd->mdl_context.set_needs_thr_lock_abort(0); mysql_mutex_unlock(&thd->LOCK_thd_data); @@ -3175,7 +3175,7 @@ bool Delayed_insert::handle_inserts(void) max_rows= delayed_insert_limit; if (thd.killed || table->s->tdc->flushed) { - thd.killed= KILL_SYSTEM_THREAD; + thd.set_killed(KILL_SYSTEM_THREAD); max_rows= ULONG_MAX; // Do as much as possible } diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 132da4dff65..4d5d1a4d943 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2010, 2016, MariaDB + Copyright (c) 2010, 2017, 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 @@ -634,7 +634,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, DBUG_EXECUTE_IF("simulate_kill_bug27571", { error=1; - thd->killed= KILL_QUERY; + thd->set_killed(KILL_QUERY); };); #ifndef EMBEDDED_LIBRARY diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 84bc7a4e4ed..48d8df2c6d6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -923,6 +923,7 @@ void execute_init_command(THD *thd, LEX_STRING *init_command, */ save_vio= thd->net.vio; thd->net.vio= 0; + thd->clear_error(1); dispatch_command(COM_QUERY, thd, buf, len, FALSE, FALSE); thd->client_capabilities= save_client_capabilities; thd->net.vio= save_vio; @@ -1054,6 +1055,7 @@ static void handle_bootstrap_impl(THD *thd) if (bootstrap_error) break; + thd->reset_kill_query(); /* Ensure that killed_errmsg is released */ free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); free_root(&thd->transaction.mem_root,MYF(MY_KEEP_PREALLOC)); thd->lex->restore_set_statement_var(); @@ -1223,12 +1225,8 @@ bool do_command(THD *thd) if(!thd->skip_wait_timeout) my_net_set_read_timeout(net, thd->variables.net_wait_timeout); - /* - XXX: this code is here only to clear possible errors of init_connect. - Consider moving to init_connect() instead. - */ - thd->clear_error(); // Clear error message - thd->get_stmt_da()->reset_diagnostics_area(); + /* Errors and diagnostics are cleared once here before query */ + thd->clear_error(1); net_new_transaction(net); @@ -1386,6 +1384,7 @@ bool do_command(THD *thd) WSREP_WARN("For retry temporally setting character set to : %s", my_charset_latin1.csname); } + thd->clear_error(); return_value= dispatch_command(command, thd, thd->wsrep_retry_query, thd->wsrep_retry_query_len, FALSE, FALSE); thd->variables.character_set_client = current_charset; @@ -1448,10 +1447,9 @@ static my_bool deny_updates_if_read_only_option(THD *thd, if (lex->sql_command == SQLCOM_UPDATE_MULTI) DBUG_RETURN(FALSE); - /* Check if we created or dropped temporary tables */ - if ((sql_command_flags[lex->sql_command] & CF_SCHEMA_CHANGE) && - lex->tmp_table()) - DBUG_RETURN(FALSE); + /* a table-to-create is not in the temp table list, needs a special check */ + if (lex->sql_command == SQLCOM_CREATE_TABLE) + DBUG_RETURN(!lex->tmp_table()); /* Check if we created or dropped databases */ if ((sql_command_flags[lex->sql_command] & CF_DB_CHANGE)) @@ -1574,7 +1572,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, my_message(ER_LOCK_DEADLOCK, "wsrep aborted transaction", MYF(0)); WSREP_DEBUG("Deadlock error for: %s", thd->query()); mysql_mutex_unlock(&thd->LOCK_wsrep_thd); - thd->killed = NOT_KILLED; + thd->reset_killed(); thd->mysys_var->abort = 0; thd->wsrep_conflict_state = NO_CONFLICT; thd->wsrep_retry_counter = 0; @@ -1952,7 +1950,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; } packet= arg_end + 1; - thd->reset_for_next_command(); + thd->reset_for_next_command(0); // Don't clear errors // thd->reset_for_next_command reset state => restore it if (is_next_command) { @@ -2029,7 +2027,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } #endif case COM_QUIT: - /* We don't calculate statistics for this command */ + /* Note: We don't calculate statistics for this command */ + + /* Ensure that quit works even if max_mem_used is set */ + thd->variables.max_mem_used= LONGLONG_MAX; general_log_print(thd, command, NullS); net->error=0; // Don't give 'abort' message thd->get_stmt_da()->disable_status(); // Don't send anything back @@ -2057,9 +2058,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd, kill_zombie_dump_threads(slave_server_id); thd->variables.server_id = slave_server_id; - general_log_print(thd, command, "Log: '%s' Pos: %ld", packet+10, - (long) pos); - mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags); + const char *name= packet + 10; + size_t nlen= strlen(name); + + general_log_print(thd, command, "Log: '%s' Pos: %lu", name, pos); + if (nlen < FN_REFLEN) + mysql_binlog_send(thd, thd->strmake(name, nlen), (my_off_t)pos, flags); unregister_slave(thd,1,1); /* fake COM_QUIT -- if we get here, the thread needs to terminate */ error = TRUE; @@ -2396,6 +2400,7 @@ com_multi_end: dec_thread_running(); thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory } + thd->reset_kill_query(); /* Ensure that killed_errmsg is released */ free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); #if defined(ENABLED_PROFILING) @@ -5731,7 +5736,7 @@ end_with_restore_list: /* Disconnect the current client connection. */ if (tx_release) { - thd->killed= KILL_CONNECTION; + thd->set_killed(KILL_CONNECTION); thd->print_aborted_warning(3, "RELEASE"); } #ifdef WITH_WSREP @@ -5777,7 +5782,7 @@ end_with_restore_list: } /* Disconnect the current client connection. */ if (tx_release) - thd->killed= KILL_CONNECTION; + thd->set_killed(KILL_CONNECTION); #ifdef WITH_WSREP if (WSREP(thd) && thd->wsrep_conflict_state != NO_CONFLICT) { @@ -7412,6 +7417,8 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize) Reset the part of THD responsible for the state of command processing. + @param do_clear_error Set if we should clear errors + This needs to be called before execution of every statement (prepared or conventional). It is not called by substatements of routines. @@ -7419,12 +7426,16 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize) @todo Call it after we use THD for queries, not before. */ -void THD::reset_for_next_command() +void THD::reset_for_next_command(bool do_clear_error) { THD *thd= this; DBUG_ENTER("THD::reset_for_next_command"); DBUG_ASSERT(!thd->spcont); /* not for substatements of routines */ DBUG_ASSERT(! thd->in_sub_stmt); + + if (do_clear_error) + clear_error(1); + thd->free_list= 0; thd->select_number= 1; /* @@ -7480,8 +7491,6 @@ void THD::reset_for_next_command() reset_dynamic(&thd->user_var_events); thd->user_var_events_alloc= thd->mem_root; } - thd->clear_error(); - thd->get_stmt_da()->reset_diagnostics_area(); thd->get_stmt_da()->reset_for_next_command(); thd->rand_used= 0; thd->m_sent_row_count= thd->m_examined_row_count= 0; @@ -7728,7 +7737,7 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, thd->wsrep_conflict_state == CERT_FAILURE) { thd->reset_for_next_command(); - thd->killed= NOT_KILLED; + thd->reset_killed(); if (is_autocommit && thd->lex->sql_command != SQLCOM_SELECT && (thd->wsrep_retry_counter < thd->variables.wsrep_retry_autocommit)) @@ -7757,7 +7766,7 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, thd->wsrep_retry_counter, thd->variables.wsrep_retry_autocommit, thd->query()); my_message(ER_LOCK_DEADLOCK, "wsrep aborted transaction", MYF(0)); - thd->killed= NOT_KILLED; + thd->reset_killed(); thd->wsrep_conflict_state= NO_CONFLICT; if (thd->wsrep_conflict_state != REPLAYING) thd->wsrep_retry_counter= 0; // reset @@ -8894,10 +8903,10 @@ void sql_kill(THD *thd, longlong id, killed_state state, killed_type type) uint error; if (!(error= kill_one_thread(thd, id, state, type))) { - if ((!thd->killed)) + if (!thd->killed) my_ok(thd); else - my_error(killed_errno(thd->killed), MYF(0), id); + thd->send_kill_message(); } else my_error(error, MYF(0), id); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index c5fd142f620..1f802b7de83 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2008, 2014, SkySQL Ab. +/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. + Copyright (c) 2008, 2017, 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 @@ -3341,6 +3341,7 @@ int reset_slave(THD *thd, Master_info* mi) // close master_info_file, relay_log_info_file, set mi->inited=rli->inited=0 end_master_info(mi); + end_relay_log_info(&mi->rli); // and delete these two files create_logfile_name_with_suffix(master_info_file_tmp, sizeof(master_info_file_tmp), diff --git a/sql/sql_select.cc b/sql/sql_select.cc index da2862654b5..bdf85d0b2fc 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3879,7 +3879,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, #endif DBUG_EXECUTE_IF("bug11747970_raise_error", - { join->thd->killed= KILL_QUERY_HARD; }); + { join->thd->set_killed(KILL_QUERY_HARD); }); if (error) { table->file->print_error(error, MYF(0)); @@ -16866,7 +16866,12 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, Field **tmp_from_field=from_field; while ((item=li++)) { - Item::Type type=item->type(); + Item::Type type= item->type(); + if (type == Item::COPY_STR_ITEM) + { + item= ((Item_copy *)item)->get_item(); + type= item->type(); + } if (not_all_columns) { if (item->with_sum_func && type != Item::SUM_FUNC_ITEM) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index beac24ed1c4..e70331d9f24 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4652,7 +4652,7 @@ int create_table_impl(THD *thd, thd->variables.option_bits|= OPTION_KEEP_LOG; thd->log_current_statement= 1; create_info->table_was_deleted= 1; - DBUG_EXECUTE_IF("send_kill_after_delete", thd->killed= KILL_QUERY; ); + DBUG_EXECUTE_IF("send_kill_after_delete", thd->set_killed(KILL_QUERY); ); /* Restart statement transactions for the case of CREATE ... SELECT. @@ -7038,6 +7038,7 @@ static bool mysql_inplace_alter_table(THD *thd, HA_CREATE_INFO *create_info= ha_alter_info->create_info; Alter_info *alter_info= ha_alter_info->alter_info; bool reopen_tables= false; + bool res; DBUG_ENTER("mysql_inplace_alter_table"); @@ -7172,11 +7173,12 @@ static bool mysql_inplace_alter_table(THD *thd, DEBUG_SYNC(thd, "alter_table_inplace_after_lock_downgrade"); THD_STAGE_INFO(thd, stage_alter_inplace); - if (table->file->ha_inplace_alter_table(altered_table, - ha_alter_info)) - { + /* We can abort alter table for any table type */ + thd->abort_on_warning= !ha_alter_info->ignore && thd->is_strict_mode(); + res= table->file->ha_inplace_alter_table(altered_table, ha_alter_info); + thd->abort_on_warning= false; + if (res) goto rollback; - } // Upgrade to EXCLUSIVE before commit. if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME)) @@ -7408,6 +7410,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, bool modified_primary_key= FALSE; Create_field *def; Field **f_ptr,*field; + MY_BITMAP *dropped_fields= NULL; // if it's NULL - no dropped fields DBUG_ENTER("mysql_prepare_alter_table"); /* @@ -7467,6 +7470,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, /* First collect all fields from table which isn't in drop_list */ + bitmap_clear_all(&table->tmp_set); for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++) { Alter_drop *drop; @@ -7477,24 +7481,23 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, while ((drop=drop_it++)) { if (drop->type == Alter_drop::COLUMN && - !my_strcasecmp(system_charset_info,field->field_name.str, - drop->name)) - { - /* Reset auto_increment value if it was dropped */ - if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER && - !(used_fields & HA_CREATE_USED_AUTO)) - { - create_info->auto_increment_value=0; - create_info->used_fields|=HA_CREATE_USED_AUTO; - } - break; - } + !my_strcasecmp(system_charset_info,field->field_name.str, drop->name)) + break; } if (drop) { + /* Reset auto_increment value if it was dropped */ + if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER && + !(used_fields & HA_CREATE_USED_AUTO)) + { + create_info->auto_increment_value=0; + create_info->used_fields|=HA_CREATE_USED_AUTO; + } if (table->s->tmp_table == NO_TMP_TABLE) (void) delete_statistics_for_column(thd, table, field); drop_it.remove(); + dropped_fields= &table->tmp_set; + bitmap_set_bit(dropped_fields, field->field_index); continue; } /* Check if field is changed */ @@ -7685,6 +7688,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, continue; } + const char *dropped_key_part= NULL; KEY_PART_INFO *key_part= key_info->key_part; key_parts.empty(); bool delete_index_stat= FALSE; @@ -7714,6 +7718,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, if (table->s->primary_key == i) modified_primary_key= TRUE; delete_index_stat= TRUE; + dropped_key_part= key_part_name; continue; // Field is removed } key_part_length= key_part->length; @@ -7796,6 +7801,11 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, key_type= Key::PRIMARY; else key_type= Key::UNIQUE; + if (dropped_key_part) + { + my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), dropped_key_part); + goto err; + } } else if (key_info->flags & HA_FULLTEXT) key_type= Key::FULLTEXT; @@ -7847,6 +7857,23 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, break; } } + /* see if the constraint depends on *only* on dropped fields */ + if (dropped_fields) + { + table->default_column_bitmaps(); + bitmap_clear_all(table->read_set); + check->expr->walk(&Item::register_field_in_read_map, 1, 0); + if (bitmap_is_subset(table->read_set, dropped_fields)) + drop= (Alter_drop*)1; + else if (bitmap_is_overlapping(dropped_fields, table->read_set)) + { + bitmap_intersect(table->read_set, dropped_fields); + uint field_nr= bitmap_get_first_set(table->read_set); + my_error(ER_BAD_FIELD_ERROR, MYF(0), + table->field[field_nr]->field_name.str, "CHECK"); + goto err; + } + } if (!drop) new_constraint_list.push_back(check, thd->mem_root); } @@ -8843,11 +8870,8 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name, alter_info->requested_algorithm != Alter_info::ALTER_TABLE_ALGORITHM_INPLACE) || is_inplace_alter_impossible(table, create_info, alter_info) -#ifdef WITH_PARTITION_STORAGE_ENGINE - || (partition_changed && - !(table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION)) -#endif - ) + || IF_PARTITIONING((partition_changed && + !(table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION)), 0)) { if (alter_info->requested_algorithm == Alter_info::ALTER_TABLE_ALGORITHM_INPLACE) diff --git a/sql/sql_union.cc b/sql/sql_union.cc index d158e1ed571..6b5c328fd5d 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. - Copyright (c) 2010, 2014, SkySQL Ab. +/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. + Copyright (c) 2010, 2017, 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 @@ -815,7 +815,18 @@ bool st_select_lex_unit::join_union_type_attributes(THD *thd_arg, List_iterator_fast<Item> itx(sl->item_list); for (uint holder_pos= 0 ; (item_tmp= itx++); holder_pos++) { - DBUG_ASSERT(item_tmp->fixed); + /* + If the outer query has a GROUP BY clause, an outer reference to this + query block may have been wrapped in a Item_outer_ref, which has not + been fixed yet. An Item_type_holder must be created based on a fixed + Item, so use the inner Item instead. + */ + DBUG_ASSERT(item_tmp->fixed || + (item_tmp->type() == Item::REF_ITEM && + ((Item_ref *)(item_tmp))->ref_type() == + Item_ref::OUTER_REF)); + if (!item_tmp->fixed) + item_tmp= item_tmp->real_item(); holders[holder_pos].add_argument(item_tmp); } } @@ -1936,4 +1947,3 @@ void st_select_lex_unit::set_unique_exclude() } } } - diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 568dd40df46..ed702e37f57 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -918,7 +918,7 @@ int mysql_update(THD *thd, // simulated killing after the loop must be ineffective for binlogging DBUG_EXECUTE_IF("simulate_kill_bug27571", { - thd->killed= KILL_QUERY; + thd->set_killed(KILL_QUERY); };); error= (killed_status == NOT_KILLED)? error : 1; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index b4aa1b63213..b5acad5a06c 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1861,8 +1861,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); procedure_list procedure_list2 procedure_item field_def handler opt_generated_always opt_ignore opt_column opt_restrict - grant revoke set lock unlock string_list field_options field_option - field_opt_list opt_binary table_lock_list table_lock + grant revoke set lock unlock string_list field_options + opt_binary table_lock_list table_lock ref_list opt_match_clause opt_on_update_delete use opt_delete_options opt_delete_option varchar nchar nvarchar opt_outer table_list table_name table_alias_ref_list table_alias_ref @@ -6495,8 +6495,11 @@ field_type_lob: { $$.set(&type_handler_long_blob); } | LONG_SYM opt_binary { $$.set(&type_handler_medium_blob); } - | JSON_SYM opt_binary - { $$.set(&type_handler_blob); } + | JSON_SYM + { + Lex->charset= &my_charset_utf8mb4_bin; + $$.set(&type_handler_long_blob); + } ; field_type_misc: @@ -6580,18 +6583,11 @@ precision: field_options: /* empty */ {} - | field_opt_list {} - ; - -field_opt_list: - field_opt_list field_option {} - | field_option {} - ; - -field_option: - SIGNED_SYM {} + | SIGNED_SYM {} | UNSIGNED { Lex->last_field->flags|= UNSIGNED_FLAG;} | ZEROFILL { Lex->last_field->flags|= UNSIGNED_FLAG | ZEROFILL_FLAG; } + | UNSIGNED ZEROFILL { Lex->last_field->flags|= UNSIGNED_FLAG | ZEROFILL_FLAG; } + | ZEROFILL UNSIGNED { Lex->last_field->flags|= UNSIGNED_FLAG | ZEROFILL_FLAG; } ; field_length: diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 746d43fdc0f..3c47e6f6a9c 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -1286,8 +1286,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); procedure_list procedure_list2 procedure_item field_def handler opt_generated_always opt_ignore opt_column opt_restrict - grant revoke set lock unlock string_list field_options field_option - field_opt_list opt_binary table_lock_list table_lock + grant revoke set lock unlock string_list field_options + opt_binary table_lock_list table_lock ref_list opt_match_clause opt_on_update_delete use opt_delete_options opt_delete_option varchar nchar nvarchar opt_outer table_list table_name table_alias_ref_list table_alias_ref @@ -6437,8 +6437,11 @@ field_type_lob: { $$.set(&type_handler_long_blob); } | LONG_SYM opt_binary { $$.set(&type_handler_medium_blob); } - | JSON_SYM opt_binary - { $$.set(&type_handler_blob); } + | JSON_SYM + { + Lex->charset= &my_charset_utf8mb4_bin; + $$.set(&type_handler_long_blob); + } ; field_type_misc: @@ -6522,18 +6525,11 @@ precision: field_options: /* empty */ {} - | field_opt_list {} - ; - -field_opt_list: - field_opt_list field_option {} - | field_option {} - ; - -field_option: - SIGNED_SYM {} + | SIGNED_SYM {} | UNSIGNED { Lex->last_field->flags|= UNSIGNED_FLAG;} | ZEROFILL { Lex->last_field->flags|= UNSIGNED_FLAG | ZEROFILL_FLAG; } + | UNSIGNED ZEROFILL { Lex->last_field->flags|= UNSIGNED_FLAG | ZEROFILL_FLAG; } + | ZEROFILL UNSIGNED { Lex->last_field->flags|= UNSIGNED_FLAG | ZEROFILL_FLAG; } ; field_length: diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index feb31f01f41..7181e7ff3b8 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -371,7 +371,7 @@ static Sys_var_mybool Sys_automatic_sp_privileges( static Sys_var_ulong Sys_back_log( "back_log", "The number of outstanding connection requests " - "MariaDB can have. This comes into play when the main MySQL thread " + "MariaDB can have. This comes into play when the main MariaDB thread " "gets very many connection requests in a very short time", AUTO_SET READ_ONLY GLOBAL_VAR(back_log), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 65535), DEFAULT(150), BLOCK_SIZE(1)); @@ -395,7 +395,7 @@ static Sys_var_ulonglong Sys_binlog_stmt_cache_size( "binlog_stmt_cache_size", "The size of the statement cache for " "updates to non-transactional engines for the binary log. " "If you often use statements updating a great number of rows, " - "you can increase this to get more performance", + "you can increase this to get more performance.", GLOBAL_VAR(binlog_stmt_cache_size), CMD_LINE(REQUIRED_ARG), VALID_RANGE(IO_SIZE, SIZE_T_MAX), DEFAULT(32768), BLOCK_SIZE(IO_SIZE)); @@ -823,7 +823,15 @@ export bool fix_delay_key_write(sys_var *self, THD *thd, enum_var_type type) } static const char *delay_key_write_names[]= { "OFF", "ON", "ALL", NullS }; static Sys_var_enum Sys_delay_key_write( - "delay_key_write", "Type of DELAY_KEY_WRITE", + "delay_key_write", "Specifies how MyISAM tables handles CREATE " + "TABLE DELAY_KEY_WRITE. If set to ON, the default, any DELAY KEY " + "WRITEs are honored. The key buffer is then flushed only when the " + "table closes, speeding up writes. MyISAM tables should be " + "automatically checked upon startup in this case, and " + "--external locking should not be used, as it can lead to index " + "corruption. If set to OFF, DELAY KEY WRITEs are ignored, while if " + "set to ALL, all new opened tables are treated as if created with " + "DELAY KEY WRITEs enabled.", GLOBAL_VAR(delay_key_write_options), CMD_LINE(OPT_ARG), delay_key_write_names, DEFAULT(DELAY_KEY_WRITE_ON), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), @@ -833,7 +841,7 @@ static Sys_var_ulong Sys_delayed_insert_limit( "delayed_insert_limit", "After inserting delayed_insert_limit rows, the INSERT DELAYED " "handler will check if there are any SELECT statements pending. " - "If so, it allows these to execute before continuing", + "If so, it allows these to execute before continuing.", GLOBAL_VAR(delayed_insert_limit), CMD_LINE(REQUIRED_ARG), VALID_RANGE(1, UINT_MAX), DEFAULT(DELAYED_LIMIT), BLOCK_SIZE(1)); @@ -2354,7 +2362,7 @@ static Sys_var_ulong Sys_optimizer_search_depth( "query plans, but take longer to compile a query. Values smaller " "than the number of tables in a relation result in faster " "optimization, but may produce very bad query plans. If set to 0, " - "the system will automatically pick a reasonable value", + "the system will automatically pick a reasonable value.", SESSION_VAR(optimizer_search_depth), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, MAX_TABLES+1), DEFAULT(MAX_TABLES+1), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0)); @@ -2437,7 +2445,7 @@ static Sys_var_ulong Sys_preload_buff_size( static Sys_var_uint Sys_protocol_version( "protocol_version", - "The version of the client/server protocol used by the MySQL server", + "The version of the client/server protocol used by the MariaDB server", READ_ONLY GLOBAL_VAR(protocol_version), CMD_LINE_HELP_ONLY, VALID_RANGE(0, ~0U), DEFAULT(PROTOCOL_VERSION), BLOCK_SIZE(1)); @@ -2887,7 +2895,7 @@ static Sys_var_enum Slave_exec_mode( "For example, in row based replication attempts to delete rows that " "doesn't exist will be ignored. " "In STRICT mode, replication will stop on any unexpected difference " - "between the master and the slave", + "between the master and the slave.", GLOBAL_VAR(slave_exec_mode_options), CMD_LINE(REQUIRED_ARG), slave_exec_mode_names, DEFAULT(SLAVE_EXEC_MODE_STRICT)); @@ -3420,14 +3428,17 @@ bool Sys_var_tx_read_only::session_update(THD *thd, set_var *var) static Sys_var_tx_read_only Sys_tx_read_only( - "tx_read_only", "Set default transaction access mode to read only.", + "tx_read_only", "Default transaction access mode. If set to OFF, " + "the default, access is read/write. If set to ON, access is read-only. " + "The SET TRANSACTION statement can also change the value of this variable. " + "See SET TRANSACTION and START TRANSACTION.", SESSION_VAR(tx_read_only), NO_CMD_LINE, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_tx_read_only)); static Sys_var_ulonglong Sys_tmp_table_size( "tmp_table_size", "Alias for tmp_memory_table_size. " - "If an internal in-memory temporary table exceeds this size, MySQL " + "If an internal in-memory temporary table exceeds this size, MariaDB " "will automatically convert it to an on-disk MyISAM or Aria table.", SESSION_VAR(tmp_memory_table_size), CMD_LINE(REQUIRED_ARG), VALID_RANGE(1024, (ulonglong)~(intptr)0), DEFAULT(16*1024*1024), @@ -3435,7 +3446,7 @@ static Sys_var_ulonglong Sys_tmp_table_size( static Sys_var_ulonglong Sys_tmp_memory_table_size( "tmp_memory_table_size", - "If an internal in-memory temporary table exceeds this size, MySQL " + "If an internal in-memory temporary table exceeds this size, MariaDB " "will automatically convert it to an on-disk MyISAM or Aria table. " "Same as tmp_table_size.", SESSION_VAR(tmp_memory_table_size), CMD_LINE(REQUIRED_ARG), @@ -3458,27 +3469,35 @@ static Sys_var_mybool Sys_timed_mutexes( DEPRECATED("")); static Sys_var_charptr Sys_version( - "version", "Server version", + "version", "Server version number. It may also include a suffix " + "with configuration or build information. -debug indicates " + "debugging support was enabled on the server, and -log indicates " + "at least one of the binary log, general log or slow query log are " + "enabled, for example 10.1.1-MariaDB-mariadb1precise-log.", READ_ONLY GLOBAL_VAR(server_version_ptr), CMD_LINE_HELP_ONLY, IN_SYSTEM_CHARSET, DEFAULT(server_version)); static char *server_version_comment_ptr; static Sys_var_charptr Sys_version_comment( - "version_comment", "version_comment", + "version_comment", "Value of the COMPILATION_COMMENT option " + "specified by CMake when building MariaDB, for example " + "mariadb.org binary distribution.", READ_ONLY GLOBAL_VAR(server_version_comment_ptr), CMD_LINE_HELP_ONLY, IN_SYSTEM_CHARSET, DEFAULT(MYSQL_COMPILATION_COMMENT)); static char *server_version_compile_machine_ptr; static Sys_var_charptr Sys_version_compile_machine( - "version_compile_machine", "version_compile_machine", + "version_compile_machine", "The machine type or architecture " + "MariaDB was built on, for example i686.", READ_ONLY GLOBAL_VAR(server_version_compile_machine_ptr), CMD_LINE_HELP_ONLY, IN_SYSTEM_CHARSET, DEFAULT(DEFAULT_MACHINE)); static char *server_version_compile_os_ptr; static Sys_var_charptr Sys_version_compile_os( - "version_compile_os", "version_compile_os", + "version_compile_os", "Operating system that MariaDB was built " + "on, for example debian-linux-gnu.", READ_ONLY GLOBAL_VAR(server_version_compile_os_ptr), CMD_LINE_HELP_ONLY, IN_SYSTEM_CHARSET, DEFAULT(SYSTEM_TYPE)); @@ -3664,24 +3683,34 @@ static bool fix_autocommit(sys_var *self, THD *thd, enum_var_type type) } static Sys_var_bit Sys_autocommit( - "autocommit", "autocommit", + "autocommit", "If set to 1, the default, all queries are committed " + "immediately. If set to 0, they are only committed upon a COMMIT statement" + ", or rolled back with a ROLLBACK statement. If autocommit is set to 0, " + "and then changed to 1, all open transactions are immediately committed.", NO_SET_STMT SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_AUTOCOMMIT, DEFAULT(TRUE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(fix_autocommit)); export sys_var *Sys_autocommit_ptr= &Sys_autocommit; // for sql_yacc.yy static Sys_var_mybool Sys_big_tables( - "big_tables", "Allow big result sets by saving all " - "temporary sets on file (Solves most 'table full' errors)", + "big_tables", "Old variable, which if set to 1, allows large result sets " + "by saving all temporary sets to disk, avoiding 'table full' errors. No " + "longer needed, as the server now handles this automatically. " + "sql_big_tables is a synonym.", SESSION_VAR(big_tables), CMD_LINE(OPT_ARG), DEFAULT(FALSE)); static Sys_var_bit Sys_big_selects( - "sql_big_selects", "sql_big_selects", + "sql_big_selects", "If set to 0, MariaDB will not perform large SELECTs." + " See max_join_size for details. If max_join_size is set to anything but " + "DEFAULT, sql_big_selects is automatically set to 0. If sql_big_selects " + "is again set, max_join_size will be ignored.", SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_BIG_SELECTS, DEFAULT(FALSE)); static Sys_var_bit Sys_log_off( - "sql_log_off", "sql_log_off", + "sql_log_off", "If set to 1 (0 is the default), no logging to the general " + "query log is done for the client. Only clients with the SUPER privilege " + "can update this variable.", NO_SET_STMT SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_LOG_OFF, DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_has_super)); @@ -3738,50 +3767,80 @@ static bool check_sql_log_bin(sys_var *self, THD *thd, set_var *var) return FALSE; } -static Sys_var_mybool Sys_log_binlog( - "sql_log_bin", "Controls whether logging to the binary log is done", +static Sys_var_mybool Sys_log_binlog( + "sql_log_bin", "If set to 0 (1 is the default), no logging to the binary " + "log is done for the client. Only clients with the SUPER privilege can " + "update this variable. Can have unintended consequences if set globally, " + "see SET SQL_LOG_BIN. Starting MariaDB 10.1.7, this variable does not " + "affect the replication of events in a Galera cluster.", SESSION_VAR(sql_log_bin), NO_CMD_LINE, DEFAULT(TRUE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_sql_log_bin), ON_UPDATE(fix_sql_log_bin_after_update)); static Sys_var_bit Sys_sql_warnings( - "sql_warnings", "sql_warnings", + "sql_warnings", "If set to 1, single-row INSERTs will produce a string " + "containing warning information if a warning occurs.", SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_WARNINGS, DEFAULT(FALSE)); static Sys_var_bit Sys_sql_notes( - "sql_notes", "sql_notes", + "sql_notes", "If set to 1, the default, warning_count is incremented each " + "time a Note warning is encountered. If set to 0, Note warnings are not " + "recorded. mysqldump has outputs to set this variable to 0 so that no " + "unnecessary increments occur when data is reloaded.", SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_SQL_NOTES, DEFAULT(TRUE)); static Sys_var_bit Sys_auto_is_null( - "sql_auto_is_null", "sql_auto_is_null", + "sql_auto_is_null", "If set to 1, the query SELECT * FROM table_name WHERE " + "auto_increment_column IS NULL will return an auto-increment that has just " + "been successfully inserted, the same as the LAST_INSERT_ID() function. Some" + " ODBC programs make use of this IS NULL comparison.", SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_AUTO_IS_NULL, DEFAULT(FALSE), NO_MUTEX_GUARD, IN_BINLOG); static Sys_var_bit Sys_safe_updates( - "sql_safe_updates", "sql_safe_updates", + "sql_safe_updates", "If set to 1, UPDATEs and DELETEs need either a key in " + "the WHERE clause, or a LIMIT clause, or else they will aborted. Prevents " + "the common mistake of accidentally deleting or updating every row in a table.", SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_SAFE_UPDATES, DEFAULT(FALSE)); static Sys_var_bit Sys_buffer_results( - "sql_buffer_result", "sql_buffer_result", + "sql_buffer_result", "If set to 1 (0 is default), results from SELECT " + "statements are always placed into temporary tables. This can help the " + "server when it takes a long time to send the results to the client by " + "allowing the table locks to be freed early.", SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_BUFFER_RESULT, DEFAULT(FALSE)); static Sys_var_bit Sys_quote_show_create( - "sql_quote_show_create", "sql_quote_show_create", + "sql_quote_show_create", "If set to 1, the default, the server will " + "quote identifiers for SHOW CREATE DATABASE, SHOW CREATE TABLE and " + "SHOW CREATE VIEW statements. Quoting is disabled if set to 0. Enable " + "to ensure replications works when identifiers require quoting.", SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_QUOTE_SHOW_CREATE, DEFAULT(TRUE)); static Sys_var_bit Sys_foreign_key_checks( - "foreign_key_checks", "foreign_key_checks", + "foreign_key_checks", "If set to 1 (the default) foreign key constraints" + " (including ON UPDATE and ON DELETE behavior) InnoDB tables are checked," + " while if set to 0, they are not checked. 0 is not recommended for normal " + "use, though it can be useful in situations where you know the data is " + "consistent, but want to reload data in a different order from that that " + "specified by parent/child relationships. Setting this variable to 1 does " + "not retrospectively check for inconsistencies introduced while set to 0.", SESSION_VAR(option_bits), NO_CMD_LINE, REVERSE(OPTION_NO_FOREIGN_KEY_CHECKS), DEFAULT(TRUE), NO_MUTEX_GUARD, IN_BINLOG); static Sys_var_bit Sys_unique_checks( - "unique_checks", "unique_checks", + "unique_checks", "If set to 1, the default, secondary indexes in InnoDB " + "tables are performed. If set to 0, storage engines can (but are not " + "required to) assume that duplicate keys are not present in input data. " + "Set to 0 to speed up imports of large tables to InnoDB. The storage " + "engine will still issue a duplicate key error if it detects one, even " + "if set to 0.", SESSION_VAR(option_bits), NO_CMD_LINE, REVERSE(OPTION_RELAXED_UNIQUE_CHECKS), DEFAULT(TRUE), NO_MUTEX_GUARD, IN_BINLOG); @@ -3801,13 +3860,16 @@ static bool update_profiling(sys_var *self, THD *thd, enum_var_type type) } static Sys_var_bit Sys_profiling( - "profiling", "profiling", + "profiling", "If set to 1 (0 is default), statement profiling will be " + "enabled. See SHOW PROFILES and SHOW PROFILE.", NO_SET_STMT SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_PROFILING, DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(update_profiling)); static Sys_var_ulong Sys_profiling_history_size( - "profiling_history_size", "Limit of query profiling memory", + "profiling_history_size", "Number of statements about which profiling " + "information is maintained. If set to 0, no profiles are stored. " + "See SHOW PROFILES.", NO_SET_STMT SESSION_VAR(profiling_history_size), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 100), DEFAULT(15), BLOCK_SIZE(1)); #endif @@ -3841,7 +3903,11 @@ static bool check_skip_replication(sys_var *self, THD *thd, set_var *var) } static Sys_var_bit Sys_skip_replication( - "skip_replication", "skip_replication", + "skip_replication", "Changes are logged into the binary log with the " + "@@skip_replication flag set. Such events will not be replicated by " + "slaves that run with --replicate-events-marked-for-skip set different " + "from its default of REPLICATE. See Selectively skipping replication " + "of binlog events for more information.", NO_SET_STMT SESSION_ONLY(option_bits), NO_CMD_LINE, OPTION_SKIP_REPLICATION, DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, @@ -4184,43 +4250,61 @@ static Sys_var_charptr Sys_slow_log_path( ON_CHECK(check_log_path), ON_UPDATE(fix_slow_log_file)); static Sys_var_have Sys_have_compress( - "have_compress", "have_compress", + "have_compress", "If the zlib compression library is accessible to the " + "server, this will be set to YES, otherwise it will be NO. The COMPRESS() " + "and UNCOMPRESS() functions will only be available if set to YES.", READ_ONLY GLOBAL_VAR(have_compress), NO_CMD_LINE); static Sys_var_have Sys_have_crypt( - "have_crypt", "have_crypt", + "have_crypt", "If the crypt() system call is available this variable will " + "be set to YES, otherwise it will be set to NO. If set to NO, the " + "ENCRYPT() function cannot be used.", READ_ONLY GLOBAL_VAR(have_crypt), NO_CMD_LINE); static Sys_var_have Sys_have_dlopen( - "have_dynamic_loading", "have_dynamic_loading", + "have_dynamic_loading", "If the server supports dynamic loading of plugins, " + "will be set to YES, otherwise will be set to NO.", READ_ONLY GLOBAL_VAR(have_dlopen), NO_CMD_LINE); static Sys_var_have Sys_have_geometry( - "have_geometry", "have_geometry", + "have_geometry", "If the server supports spatial data types, will be set to " + "YES, otherwise will be set to NO.", READ_ONLY GLOBAL_VAR(have_geometry), NO_CMD_LINE); static Sys_var_have Sys_have_openssl( - "have_openssl", "have_openssl", + "have_openssl", "Comparing have_openssl with have_ssl will indicate whether " + "YaSSL or openssl was used. If YaSSL, have_ssl will be YES, but have_openssl " + "will be NO.", READ_ONLY GLOBAL_VAR(have_openssl), NO_CMD_LINE); static Sys_var_have Sys_have_profiling( - "have_profiling", "have_profiling", + "have_profiling", "If statement profiling is available, will be set to YES, " + "otherwise will be set to NO. See SHOW PROFILES and SHOW PROFILE.", READ_ONLY GLOBAL_VAR(have_profiling), NO_CMD_LINE); static Sys_var_have Sys_have_query_cache( - "have_query_cache", "have_query_cache", + "have_query_cache", "If the server supports the query cache, will be set to " + "YES, otherwise will be set to NO.", READ_ONLY GLOBAL_VAR(have_query_cache), NO_CMD_LINE); static Sys_var_have Sys_have_rtree_keys( - "have_rtree_keys", "have_rtree_keys", + "have_rtree_keys", "If RTREE indexes (used for spatial indexes) " + "are available, will be set to YES, otherwise will be set to NO.", READ_ONLY GLOBAL_VAR(have_rtree_keys), NO_CMD_LINE); static Sys_var_have Sys_have_ssl( - "have_ssl", "have_ssl", + "have_ssl", "If the server supports secure connections, will be set to YES, " + "otherwise will be set to NO. If set to DISABLED, the server was compiled with " + "TLS support, but was not started with TLS support (see the mysqld options). " + "See also have_openssl.", READ_ONLY GLOBAL_VAR(have_ssl), NO_CMD_LINE); static Sys_var_have Sys_have_symlink( - "have_symlink", "have_symlink", + "have_symlink", "If symbolic link support is enabled, will be set to YES, " + "otherwise will be set to NO. Required for the INDEX DIRECTORY and DATA " + "DIRECTORY table options (see CREATE TABLE) and Windows symlink support. " + "Will be set to DISABLED if the server is started with the " + "--skip-symbolic-links option.", READ_ONLY GLOBAL_VAR(have_symlink), NO_CMD_LINE); static bool fix_log_state(sys_var *self, THD *thd, enum_var_type type); @@ -4228,7 +4312,7 @@ static bool fix_log_state(sys_var *self, THD *thd, enum_var_type type); static Sys_var_mybool Sys_general_log( "general_log", "Log connections and queries to a table or log file. " "Defaults logging to a file 'hostname'.log or a table mysql.general_log" - "if --log-output=TABLE is used", + "if --log-output=TABLE is used.", GLOBAL_VAR(opt_log), CMD_LINE(OPT_ARG), DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(fix_log_state)); @@ -4237,7 +4321,7 @@ static Sys_var_mybool Sys_slow_query_log( "slow_query_log", "Log slow queries to a table or log file. Defaults logging to a file " "'hostname'-slow.log or a table mysql.slow_log if --log-output=TABLE is " - "used. Must be enabled to activate other slow log options", + "used. Must be enabled to activate other slow log options.", SESSION_VAR(sql_log_slow), CMD_LINE(OPT_ARG), DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(fix_log_state)); @@ -4309,12 +4393,12 @@ static Sys_var_set Sys_log_output( static Sys_var_mybool Sys_log_slave_updates( "log_slave_updates", "Tells the slave to log the updates from " "the slave thread to the binary log. You will need to turn it on if " - "you plan to daisy-chain the slaves", + "you plan to daisy-chain the slaves.", READ_ONLY GLOBAL_VAR(opt_log_slave_updates), CMD_LINE(OPT_ARG), DEFAULT(0)); static Sys_var_charptr Sys_relay_log( - "relay_log", "The location and name to use for relay logs", + "relay_log", "The location and name to use for relay logs.", READ_ONLY GLOBAL_VAR(opt_relay_logname), CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET, DEFAULT(0)); @@ -4325,7 +4409,7 @@ static Sys_var_charptr Sys_relay_log( */ static Sys_var_charptr Sys_relay_log_index( "relay_log_index", "The location and name to use for the file " - "that keeps a list of the last relay logs", + "that keeps a list of the last relay logs.", READ_ONLY GLOBAL_VAR(relay_log_index), NO_CMD_LINE, IN_FS_CHARSET, DEFAULT(0)); @@ -4353,20 +4437,20 @@ static Sys_var_charptr Sys_log_bin_basename( static Sys_var_charptr Sys_relay_log_info_file( "relay_log_info_file", "The location and name of the file that " - "remembers where the SQL replication thread is in the relay logs", + "remembers where the SQL replication thread is in the relay logs.", READ_ONLY GLOBAL_VAR(relay_log_info_file), CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET, DEFAULT(0)); static Sys_var_mybool Sys_relay_log_purge( "relay_log_purge", "if disabled - do not purge relay logs. " - "if enabled - purge them as soon as they are no more needed", + "if enabled - purge them as soon as they are no more needed.", GLOBAL_VAR(relay_log_purge), CMD_LINE(OPT_ARG), DEFAULT(TRUE)); static Sys_var_mybool Sys_relay_log_recovery( "relay_log_recovery", "Enables automatic relay log recovery " "right after the database startup, which means that the IO Thread " "starts re-fetching from the master right after the last transaction " - "processed", + "processed.", GLOBAL_VAR(relay_log_recovery), CMD_LINE(OPT_ARG), DEFAULT(FALSE)); @@ -4775,7 +4859,9 @@ static Sys_var_struct Sys_lc_time_names( NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_locale)); static Sys_var_tz Sys_time_zone( - "time_zone", "time_zone", + "time_zone", "The current time zone, used to initialize the time " + "zone for a client when it connects. Set to SYSTEM by default, in " + "which the client uses the system time zone value.", SESSION_VAR(time_zone), NO_CMD_LINE, DEFAULT(&default_tz), NO_MUTEX_GUARD, IN_BINLOG); @@ -4792,7 +4878,8 @@ static Sys_var_charptr Sys_wsrep_provider( ON_CHECK(wsrep_provider_check), ON_UPDATE(wsrep_provider_update)); static Sys_var_charptr Sys_wsrep_provider_options( - "wsrep_provider_options", "provider specific options", + "wsrep_provider_options", "Semicolon (;) separated list of wsrep " + "options (see wsrep_provider_options documentation).", PREALLOCATED GLOBAL_VAR(wsrep_provider_options), CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET, DEFAULT(""), NO_MUTEX_GUARD, NOT_IN_BINLOG, @@ -4823,13 +4910,17 @@ static Sys_var_charptr Sys_wsrep_cluster_address ( ON_UPDATE(wsrep_cluster_address_update)); static Sys_var_charptr Sys_wsrep_node_name ( - "wsrep_node_name", "Node name", + "wsrep_node_name", "Name of this node. This name can be used in " + "wsrep_sst_donor as a preferred donor. Note that multiple nodes " + "in a cluster can have the same name.", PREALLOCATED GLOBAL_VAR(wsrep_node_name), CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET, DEFAULT(glob_hostname), NO_MUTEX_GUARD, NOT_IN_BINLOG, wsrep_node_name_check, wsrep_node_name_update); static Sys_var_charptr Sys_wsrep_node_address ( - "wsrep_node_address", "Node address", + "wsrep_node_address", "Specifies the node's network address, in " + "the format ip address[:port]. Used in situations where autoguessing " + "is not reliable. As of MariaDB 10.1.8, supports IPv6.", PREALLOCATED GLOBAL_VAR(wsrep_node_address), CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET, DEFAULT(""), NO_MUTEX_GUARD, NOT_IN_BINLOG, @@ -5047,7 +5138,7 @@ static Sys_var_mybool Sys_wsrep_slave_UK_checks( CMD_LINE(OPT_ARG), DEFAULT(FALSE)); static Sys_var_mybool Sys_wsrep_restart_slave( - "wsrep_restart_slave", "Should MySQL slave be restarted automatically, when node joins back to cluster", + "wsrep_restart_slave", "Should MariaDB slave be restarted automatically, when node joins back to cluster", GLOBAL_VAR(wsrep_restart_slave), CMD_LINE(OPT_ARG), DEFAULT(FALSE)); static Sys_var_mybool Sys_wsrep_dirty_reads( @@ -5074,7 +5165,7 @@ static Sys_var_mybool Sys_wsrep_gtid_mode( static char *wsrep_patch_version_ptr; static Sys_var_charptr Sys_wsrep_patch_version( - "wsrep_patch_version", "wsrep patch version", + "wsrep_patch_version", "Wsrep patch version, for example wsrep_25.10.", READ_ONLY GLOBAL_VAR(wsrep_patch_version_ptr), CMD_LINE_HELP_ONLY, IN_SYSTEM_CHARSET, DEFAULT(WSREP_PATCH_VERSION)); diff --git a/sql/table.cc b/sql/table.cc index 7432277f448..614aa909764 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -7480,7 +7480,7 @@ int TABLE::update_virtual_field(Field *vf) vf->vcol_info->expr->walk(&Item::update_vcol_processor, 0, &tmp_set); vf->vcol_info->expr->save_in_field(vf, 0); in_use->restore_active_arena(expr_arena, &backup_arena); - DBUG_RETURN(0); + DBUG_RETURN(in_use->is_error()); } diff --git a/sql/uniques.cc b/sql/uniques.cc index f2fa0bf7b1a..71d2093b828 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -486,7 +486,7 @@ void put_counter_into_merged_element(void *ptr, uint ofs, element_count cnt) <> 0 error */ -static bool merge_walk(uchar *merge_buffer, ulong merge_buffer_size, +static bool merge_walk(uchar *merge_buffer, size_t merge_buffer_size, uint key_length, BUFFPEK *begin, BUFFPEK *end, tree_walk_action walk_action, void *walk_action_arg, qsort_cmp2 compare, void *compare_arg, @@ -495,7 +495,7 @@ static bool merge_walk(uchar *merge_buffer, ulong merge_buffer_size, BUFFPEK_COMPARE_CONTEXT compare_context = { compare, compare_arg }; QUEUE queue; if (end <= begin || - merge_buffer_size < (ulong) (key_length * (end - begin + 1)) || + merge_buffer_size < (size_t) (key_length * (end - begin + 1)) || init_queue(&queue, (uint) (end - begin), offsetof(BUFFPEK, key), 0, buffpek_compare, &compare_context, 0, 0)) return 1; @@ -645,15 +645,19 @@ bool Unique::walk(TABLE *table, tree_walk_action action, void *walk_action_arg) return 1; if (flush_io_cache(&file) || reinit_io_cache(&file, READ_CACHE, 0L, 0, 0)) return 1; - size_t buff_sz= (max_in_memory_size / full_size + 1) * full_size; + /* + merge_buffer must fit at least MERGEBUFF2 keys, because + merge_index() can merge that many BUFFPEKs at once. + */ + size_t buff_sz= MY_MAX(MERGEBUFF2, max_in_memory_size/full_size+1) * full_size; if (!(merge_buffer = (uchar *)my_malloc(buff_sz, MYF(MY_THREAD_SPECIFIC|MY_WME)))) return 1; if (buff_sz < full_size * (file_ptrs.elements + 1UL)) res= merge(table, merge_buffer, buff_sz >= full_size * MERGEBUFF2) ; - + if (!res) - { - res= merge_walk(merge_buffer, (ulong) max_in_memory_size, full_size, + { + res= merge_walk(merge_buffer, buff_sz, full_size, (BUFFPEK *) file_ptrs.buffer, (BUFFPEK *) file_ptrs.buffer + file_ptrs.elements, action, walk_action_arg, diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 58342b0b97a..4c0a5570f16 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -2009,7 +2009,7 @@ static bool have_client_connections() static void wsrep_close_thread(THD *thd) { - thd->killed= KILL_CONNECTION; + thd->set_killed(KILL_CONNECTION); MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (thd)); if (thd->mysys_var) { @@ -2089,7 +2089,7 @@ void wsrep_close_client_connections(my_bool wait_to_end) if (is_replaying_connection(tmp)) { - tmp->killed= KILL_CONNECTION; + tmp->set_killed(KILL_CONNECTION); continue; } diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc index f8db20ace99..5f29d28b19f 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -234,7 +234,7 @@ void wsrep_replay_transaction(THD *thd) mysql_mutex_unlock(&thd->LOCK_wsrep_thd); thd->reset_for_next_command(); - thd->killed= NOT_KILLED; + thd->reset_killed(); close_thread_tables(thd); if (thd->locked_tables_mode && thd->lock) { |