From 492c3b09d2b3c11ebb043276ff4b245d54d99fd0 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Mar 2013 14:58:19 +0100 Subject: Fix compile error when building with DBUG, but without DEBUG_SYNC. --- sql/sql_parse.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 6ea0dcbeb8e..808214402ff 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2944,6 +2944,7 @@ end_with_restore_list: thd->first_successful_insert_id_in_cur_stmt= thd->first_successful_insert_id_in_prev_stmt; +#ifdef ENABLED_DEBUG_SYNC DBUG_EXECUTE_IF("after_mysql_insert", { const char act1[]= @@ -2959,6 +2960,7 @@ end_with_restore_list: STRING_WITH_LEN(act2))); };); DEBUG_SYNC(thd, "after_mysql_insert"); +#endif break; } case SQLCOM_REPLACE_SELECT: -- cgit v1.2.1 From e73f13a707a2bc8e19c7c1424342eec7545797ae Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 19 Mar 2013 15:25:58 +0100 Subject: extend check_global_access() to avoid my_error when it's not needed (in INFORMATION_SCHEMA). --- sql/sql_parse.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 808214402ff..989f1ed66de 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1630,7 +1630,7 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, break; case SCH_USER_STATS: case SCH_CLIENT_STATS: - if (check_global_access(thd, SUPER_ACL | PROCESS_ACL)) + if (check_global_access(thd, SUPER_ACL | PROCESS_ACL, true)) DBUG_RETURN(1); case SCH_TABLE_STATS: case SCH_INDEX_STATS: @@ -1805,7 +1805,7 @@ bool sp_process_definer(THD *thd) if ((strcmp(lex->definer->user.str, thd->security_ctx->priv_user) || my_strcasecmp(system_charset_info, lex->definer->host.str, thd->security_ctx->priv_host)) && - check_global_access(thd, SUPER_ACL)) + check_global_access(thd, SUPER_ACL, true)) { my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER"); DBUG_RETURN(TRUE); @@ -5316,14 +5316,17 @@ bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table) 1 Access denied. In this case an error is sent to the client */ -bool check_global_access(THD *thd, ulong want_access) +bool check_global_access(THD *thd, ulong want_access, bool no_errors) { #ifndef NO_EMBEDDED_ACCESS_CHECKS char command[128]; if ((thd->security_ctx->master_access & want_access)) return 0; - get_privilege_desc(command, sizeof(command), want_access); - my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command); + if (!no_errors) + { + get_privilege_desc(command, sizeof(command), want_access); + my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command); + } status_var_increment(thd->status_var.access_denied_errors); return 1; #else -- cgit v1.2.1 From d8986fd6c3b69d2970e66684e1d00dd603fc9ab7 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Mon, 25 Mar 2013 11:13:42 +0200 Subject: Speed up connection time: -Change my_rnd() slightly to make it safer if two threads use it at the same time. -Avoid some sprintf and strmov in vio. -Changed thread_count to be automaticly incremented (instead of under LOCK_thread_count). -Thread cache now uses LOCK_thread_cache instead of LOCK_thread_count. -Moved delete thd out from LOCK_thread_count. -Save some mysql_cond_broadcast(&COND_thread_count) calls. -Removed call to getsockname() during connect. -Initialize random generator without locks. Other things: -Fixed test cases that depends on changes for LOCK_grant -Added thread_safe_decrement32() and thread_safe_increment32() -Removed sql_rnd_with_mutex() and get_thread_running() -In check_table_access() don't lock LOCK_grant if we can resolve the grant with user or db level grants (the normal case). -Don't use a lock for setting THD->query_id. -Fixed bug where thd->set_query_id() could be set to same value by multiple threads. Thanks to Yoshinori Matsunobu for the benchmark of connection speed and to Domas Mituzas for the inspiration for many of the fixes. include/violite.h: Change desc to a string pointer mysql-test/suite/perfschema/r/all_instances.result: Added new mutex mysql-test/suite/perfschema/t/func_mutex.test: Test for LOCK_system_variables_hash instead of LOCK_grant, as LOCK_grant is not anymore always taken for SELECT's. mysys/my_gethwaddr.c: More DBUG mysys/my_rnd.c: Change my_rnd() slightly to make it safer if two threads use it at the same time. sql/event_scheduler.cc: Changed thread_count to be automically incremented Moved some safe things out from LOCK_thread_count. Simplify deleting of THD for running thread. sql/mysqld.cc: Changed thread_count to be automically incremented Thread cache now uses LOCK_thread_cache instead of LOCK_thread_count Added delete_running_thd() Moved delete thd out from LOCK_thread_count More DBUG Only call mysql_cond_broadcast(&COND_thread_count) if thread_count is 0 Removed call to getsockname() (old not anymore needed check) sql/mysqld.h: Removed sql_rnd_with_mutex() (not needed anymore) Removed not used function get_thread_running() Added thread_safe_decrement32() and thread_safe_increment32() Simplified dec_thread_running() and inc_thread_running() next_query_id() should return the original value for global_query_id, not the next one. (Bug introduced with MySQL 5.5 merge). sql/sql_acl.cc: In check_table_access() don't lock LOCK_grant if we can resolve the grant with user or db level grants (the normal case). sql/sql_class.cc: Removed thd_lock_thread_count() and thd_unlock_thread_count() Initialize random generator without locks Don't use a lock for setting THD->query_id. (This is only accessed by thread owning the THD) sql/sql_class.h: Don't use a lock for setting THD->query_id. sql/sql_insert.cc: Changed thread_count to be automically incremented sql/sql_parse.cc: Changed thread_count to be automically incremented Fixed bug where thd->set_query_id() could be set to same value by multiple threads. vio/vio.c: Don't generate 'desc' with sprintf/strmov. Assign a pointer instead. (Good enough as this is just for debugging) --- sql/sql_parse.cc | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0abb249d97b..bdf2bd17589 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -645,9 +645,10 @@ end: delete thd; #ifndef EMBEDDED_LIBRARY - mysql_mutex_lock(&LOCK_thread_count); - thread_count--; + thread_safe_decrement32(&thread_count, &thread_count_lock); in_bootstrap= FALSE; + + mysql_mutex_lock(&LOCK_thread_count); mysql_cond_broadcast(&COND_thread_count); mysql_mutex_unlock(&LOCK_thread_count); my_thread_end(); @@ -930,9 +931,16 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->query_plan_flags= QPLAN_INIT; thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */ thd->set_time(); - thd->set_query_id(get_query_id()); if (!(server_command_flags[command] & CF_SKIP_QUERY_ID)) - next_query_id(); + thd->set_query_id(next_query_id()); + else + { + /* + ping, get statistics or similar stateless command. + No reason to increase query id here. + */ + thd->set_query_id(get_query_id()); + } inc_thread_running(); if (!(server_command_flags[command] & CF_SKIP_QUESTIONS)) @@ -5021,6 +5029,10 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, if ((db != NULL) && (db != any_db)) { + /* + Check if this is reserved database, like information schema or + performance schema + */ const ACL_internal_schema_access *access; access= get_cached_schema_access(grant_internal_info, db); if (access) -- cgit v1.2.1 From 4ec6fe10e56de0cf9b4dbc649b8552ae39c2c500 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 14:00:16 +0200 Subject: remove ULL() and LL(), because they're totally unnecessary and sometimes harmful (used with expressions) --- sql/sql_parse.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ed4a68c8534..e866d2b74ef 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2012, Oracle and/or its affiliates. - Copyright (c) 2008, 2012, Monty Program Ab + Copyright (c) 2008, 2013, Monty Program Ab 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 @@ -1379,7 +1379,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (!(uptime= (ulong) (thd->start_time - server_start_time))) queries_per_second1000= 0; else - queries_per_second1000= thd->query_id * LL(1000) / uptime; + queries_per_second1000= thd->query_id * 1000 / uptime; length= my_snprintf(buff, buff_len - 1, "Uptime: %lu Threads: %d Questions: %lu " -- cgit v1.2.1 From 336da6e2709dac5f065a14cebadeb2c97eaf1f47 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:18:37 +0200 Subject: cleanup --- sql/sql_parse.cc | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e866d2b74ef..62e5a99f941 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7683,6 +7683,7 @@ bool check_string_char_length(LEX_STRING *str, const char *err_msg, return TRUE; } +C_MODE_START /* Check if path does not contain mysql data home directory @@ -7695,7 +7696,6 @@ bool check_string_char_length(LEX_STRING *str, const char *err_msg, 0 ok 1 error ; Given path contains data directory */ -C_MODE_START int test_if_data_home_dir(const char *dir) { @@ -7706,6 +7706,22 @@ int test_if_data_home_dir(const char *dir) if (!dir) DBUG_RETURN(0); + /* + data_file_name and index_file_name include the table name without + extension. Mostly this does not refer to an existing file. When + comparing data_file_name or index_file_name against the data + directory, we try to resolve all symbolic links. On some systems, + we use realpath(3) for the resolution. This returns ENOENT if the + resolved path does not refer to an existing file. my_realpath() + does then copy the requested path verbatim, without symlink + resolution. Thereafter the comparison can fail even if the + requested path is within the data directory. E.g. if symlinks to + another file system are used. To make realpath(3) return the + resolved path, we strip the table name and compare the directory + path only. If the directory doesn't exist either, table creation + will fail anyway. + */ + (void) fn_format(path, dir, "", "", (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS)); dir_len= strlen(path); @@ -7739,6 +7755,22 @@ int test_if_data_home_dir(const char *dir) C_MODE_END +int error_if_data_home_dir(const char *path, const char *what) +{ + size_t dirlen; + char dirpath[FN_REFLEN]; + if (path) + { + dirname_part(dirpath, path, &dirlen); + if (test_if_data_home_dir(dirpath)) + { + my_error(ER_WRONG_ARGUMENTS, MYF(0), what); + return 1; + } + } + return 0; +} + /** Check that host name string is valid. -- cgit v1.2.1 From 68f6c229c563b5e92a2ef7ea2a429edbdb69c303 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:27:37 +0200 Subject: prefer static inline functions to macros. avoid unnecessary strlen()'s --- sql/sql_parse.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 62e5a99f941..c68e20f1b3a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1011,7 +1011,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, else rc= acl_authenticate(thd, 0, packet_length); - MYSQL_AUDIT_NOTIFY_CONNECTION_CHANGE_USER(thd); + mysql_audit_notify_connection_change_user(thd); if (rc) { /* Free user if allocated by acl_authenticate */ -- cgit v1.2.1 From d8dccde6df47e814c208e8853b4118a569ccf142 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Sat, 13 Apr 2013 11:59:16 +0500 Subject: MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). Syntax modified to allow statements: ALTER TABLE ADD/DROP COLUMN ALTER TABLE ADD/DROP INDEX ALTER TABLE ADD/DROP FOREIGN KEY ALTER TABLE ADD/DROP PARTITION ALTER TABLE CHANGE COLUMN ALTER TABLE MODIFY COLUMN DROP INDEX to have IF (NOT) EXISTS options. Appropriate implementations added to mysql_alter_table(). per-file comments: mysql-test/r/alter_table.result MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). test result updated. mysql-test/r/fulltext.result MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). mysql-test/r/partition.result test result updated. MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). mysql-test/t/alter_table.test tests added. MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). mysql-test/t/fulltext.test MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). tests added. mysql-test/t/partition.test MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). tests added. sql/field.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). create_if_not_exists field added. sql/field.h MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). create_if_not_exists field added. sql/partition_info.h MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). has_unique_name made public. sql/sp_head.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). sql/sql_class.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). create_if_not_exists inited. sql/sql_class.h MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). create_if_not_exists inited. sql/sql_lex.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). check_exists inited. sql/sql_lex.h MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). check_exists inited. sql/sql_parse.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). check_exists inited. sql/sql_table.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). handle_if_exists_options() added. it's called in mysql_alter_table(). sql/sql_trigger.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). check_exists instead of drop_if_exists. sql/sql_view.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). check_exists instead of drop_if_exists. sql/sql_yacc.yy MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). sintax modified. --- sql/sql_parse.cc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c68e20f1b3a..c6e46cbab80 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2084,7 +2084,7 @@ mysql_execute_command(THD *thd) if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) && !(lex->sql_command == SQLCOM_SET_OPTION) && !(lex->sql_command == SQLCOM_DROP_TABLE && - lex->drop_temporary && lex->drop_if_exists) && + lex->drop_temporary && lex->check_exists) && all_tables_not_ok(thd, all_tables)) { /* we warn the slave SQL thread */ @@ -3285,7 +3285,7 @@ end_with_restore_list: thd->variables.option_bits|= OPTION_KEEP_LOG; } /* DDL and binlog write order are protected by metadata locks. */ - res= mysql_rm_table(thd, first_table, lex->drop_if_exists, + res= mysql_rm_table(thd, first_table, lex->check_exists, lex->drop_temporary); } break; @@ -3499,7 +3499,7 @@ end_with_restore_list: #endif if (check_access(thd, DROP_ACL, lex->name.str, NULL, NULL, 1, 0)) break; - res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0); + res= mysql_rm_db(thd, lex->name.str, lex->check_exists, 0); break; } case SQLCOM_ALTER_DB_UPGRADE: @@ -3627,7 +3627,7 @@ end_with_restore_list: case SQLCOM_DROP_EVENT: if (!(res= Events::drop_event(thd, lex->spname->m_db, lex->spname->m_name, - lex->drop_if_exists))) + lex->check_exists))) my_ok(thd); break; #else @@ -4314,7 +4314,7 @@ create_sp_error: if (lex->spname->m_db.str == NULL) { - if (lex->drop_if_exists) + if (lex->check_exists) { push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), @@ -4383,7 +4383,7 @@ create_sp_error: my_ok(thd); break; case SP_KEY_NOT_FOUND: - if (lex->drop_if_exists) + if (lex->check_exists) { res= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, @@ -4596,7 +4596,7 @@ create_sp_error: if ((err_code= drop_server(thd, &lex->server_options))) { - if (! lex->drop_if_exists && err_code == ER_FOREIGN_SERVER_DOESNT_EXIST) + if (! lex->check_exists && err_code == ER_FOREIGN_SERVER_DOESNT_EXIST) { DBUG_PRINT("info", ("problem dropping server %s", lex->server_options.server_name)); @@ -6016,7 +6016,7 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type, lex->col_list.push_back(new Key_part_spec(*field_name, 0)); key= new Key(Key::PRIMARY, null_lex_str, &default_key_create_info, - 0, lex->col_list, NULL); + 0, lex->col_list, NULL, lex->check_exists); lex->alter_info.key_list.push_back(key); lex->col_list.empty(); } @@ -6026,7 +6026,7 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type, lex->col_list.push_back(new Key_part_spec(*field_name, 0)); key= new Key(Key::UNIQUE, null_lex_str, &default_key_create_info, 0, - lex->col_list, NULL); + lex->col_list, NULL, lex->check_exists); lex->alter_info.key_list.push_back(key); lex->col_list.empty(); } @@ -6078,7 +6078,7 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type, new_field->init(thd, field_name->str, type, length, decimals, type_modifier, default_value, on_update_value, comment, change, interval_list, cs, uint_geom_type, vcol_info, - create_options)) + create_options, lex->check_exists)) DBUG_RETURN(1); lex->alter_info.create_list.push_back(new_field); -- cgit v1.2.1