summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2017-08-25 10:25:48 +0200
committerSergei Golubchik <serg@mariadb.org>2017-08-25 10:25:48 +0200
commit27412877dbcf601676f4515a99b2abee1f19623b (patch)
tree2cb1a2e1a58ba10f2a96fcdec43f5ed77c326fd0 /sql
parentf2033df6ac0f64664d9aad2d56fdd74f4bf9d666 (diff)
parenta544225d0a772bd4b67c96f5861ecc0ef7e69bba (diff)
downloadmariadb-git-27412877dbcf601676f4515a99b2abee1f19623b.tar.gz
Merge branch '10.2' into bb-10.2-ext
Diffstat (limited to 'sql')
-rw-r--r--sql/CMakeLists.txt2
-rw-r--r--sql/debug_sync.cc2
-rw-r--r--sql/encryption.cc20
-rw-r--r--sql/item.cc4
-rw-r--r--sql/item_cmpfunc.cc15
-rw-r--r--sql/item_cmpfunc.h2
-rw-r--r--sql/item_jsonfunc.cc19
-rw-r--r--sql/item_strfunc.cc14
-rw-r--r--sql/item_strfunc.h2
-rw-r--r--sql/item_subselect.cc6
-rw-r--r--sql/log.cc2
-rw-r--r--sql/log_event.cc21
-rw-r--r--sql/multi_range_read.cc22
-rw-r--r--sql/mysqld.cc43
-rw-r--r--sql/mysqld.h2
-rw-r--r--sql/net_serv.cc2
-rw-r--r--sql/opt_range.cc2
-rw-r--r--sql/records.cc1
-rw-r--r--sql/rpl_handler.cc2
-rw-r--r--sql/rpl_mi.cc6
-rw-r--r--sql/rpl_parallel.cc8
-rw-r--r--sql/rpl_rli.cc64
-rw-r--r--sql/rpl_rli.h12
-rw-r--r--sql/slave.cc7
-rw-r--r--sql/sp_rcontext.cc3
-rw-r--r--sql/spatial.cc27
-rw-r--r--sql/sql_base.cc2
-rw-r--r--sql/sql_cache.cc5
-rw-r--r--sql/sql_class.cc31
-rw-r--r--sql/sql_class.h85
-rw-r--r--sql/sql_connect.cc2
-rw-r--r--sql/sql_derived.cc2
-rw-r--r--sql/sql_insert.cc14
-rw-r--r--sql/sql_load.cc4
-rw-r--r--sql/sql_parse.cc59
-rw-r--r--sql/sql_repl.cc5
-rw-r--r--sql/sql_select.cc9
-rw-r--r--sql/sql_table.cc68
-rw-r--r--sql/sql_union.cc18
-rw-r--r--sql/sql_update.cc2
-rw-r--r--sql/sql_yacc.yy24
-rw-r--r--sql/sql_yacc_ora.yy24
-rw-r--r--sql/sys_vars.cc203
-rw-r--r--sql/table.cc2
-rw-r--r--sql/uniques.cc16
-rw-r--r--sql/wsrep_mysqld.cc4
-rw-r--r--sql/wsrep_thd.cc2
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)
{