diff options
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r-- | sql/sql_parse.cc | 166 |
1 files changed, 57 insertions, 109 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8eeb0fa3415..b8ed887b52d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -545,12 +545,14 @@ void init_update_queries(void) CF_REEXECUTION_FRAGILE | CF_AUTO_COMMIT_TRANS | CF_SCHEMA_CHANGE); - sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS; + sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | + CF_ADMIN_COMMAND | CF_REPORT_PROGRESS; sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS | - CF_INSERTS_DATA; + CF_INSERTS_DATA | CF_ADMIN_COMMAND; sql_command_flags[SQLCOM_ALTER_SEQUENCE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND | - CF_AUTO_COMMIT_TRANS | CF_SCHEMA_CHANGE; + CF_AUTO_COMMIT_TRANS | CF_SCHEMA_CHANGE | + CF_ADMIN_COMMAND; sql_command_flags[SQLCOM_TRUNCATE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_DROP_TABLE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_SCHEMA_CHANGE; @@ -566,8 +568,9 @@ void init_update_queries(void) sql_command_flags[SQLCOM_DROP_PACKAGE_BODY]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_ALTER_DB_UPGRADE]= CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_ALTER_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_DB_CHANGE; - sql_command_flags[SQLCOM_RENAME_TABLE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; - sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS; + sql_command_flags[SQLCOM_RENAME_TABLE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_ADMIN_COMMAND; + sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | + CF_REPORT_PROGRESS | CF_ADMIN_COMMAND; sql_command_flags[SQLCOM_CREATE_VIEW]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_DROP_VIEW]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; @@ -747,10 +750,14 @@ void init_update_queries(void) The following admin table operations are allowed on log tables. */ - sql_command_flags[SQLCOM_REPAIR]= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS; - sql_command_flags[SQLCOM_OPTIMIZE]|= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS; - sql_command_flags[SQLCOM_ANALYZE]= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS; - sql_command_flags[SQLCOM_CHECK]= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS; + sql_command_flags[SQLCOM_REPAIR]= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS | + CF_REPORT_PROGRESS | CF_ADMIN_COMMAND; + sql_command_flags[SQLCOM_OPTIMIZE]|= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS | + CF_REPORT_PROGRESS | CF_ADMIN_COMMAND; + sql_command_flags[SQLCOM_ANALYZE]= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS | + CF_REPORT_PROGRESS | CF_ADMIN_COMMAND; + sql_command_flags[SQLCOM_CHECK]= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS | + CF_REPORT_PROGRESS | CF_ADMIN_COMMAND; sql_command_flags[SQLCOM_CHECKSUM]= CF_REPORT_PROGRESS; sql_command_flags[SQLCOM_CREATE_USER]|= CF_AUTO_COMMIT_TRANS; @@ -1638,10 +1645,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->reset_for_next_command(); thd->set_command(command); - /* - thd->variables.log_slow_disabled_statements defines which statements - are logged to slow log - */ thd->enable_slow_log= true; thd->query_plan_flags= QPLAN_INIT; thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */ @@ -2086,7 +2089,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, status_var_increment(thd->status_var.com_other); - thd->prepare_logs_for_admin_command(); + thd->query_plan_flags|= QPLAN_ADMIN; if (check_global_access(thd, REPL_SLAVE_ACL)) break; @@ -2470,33 +2473,11 @@ com_multi_end: DBUG_RETURN(error); } - -static bool log_slow_enabled_statement(const THD *thd) +static bool slow_filter_masked(THD *thd, ulonglong mask) { - /* - TODO-10.4: Add classes Sql_cmd_create_index and Sql_cmd_drop_index - for symmetry with other admin commands, so these statements can be - handled by this command: - */ - if (thd->lex->m_sql_cmd) - return thd->lex->m_sql_cmd->log_slow_enabled_statement(thd); - - /* - Currently CREATE INDEX or DROP INDEX cause a full table rebuild - and thus classify as slow administrative statements just like - ALTER TABLE. - */ - if ((thd->lex->sql_command == SQLCOM_CREATE_INDEX || - thd->lex->sql_command == SQLCOM_DROP_INDEX) && - MY_TEST(thd->variables.log_slow_disabled_statements & - LOG_SLOW_DISABLE_ADMIN)) - return true; - - return global_system_variables.sql_log_slow && - thd->variables.sql_log_slow; + return thd->variables.log_slow_filter && !(thd->variables.log_slow_filter & mask); } - /* Log query to slow queries, if it passes filtering @@ -2527,11 +2508,16 @@ void log_slow_statement(THD *thd) if (!thd->enable_slow_log) goto end; // E.g. SP statement + DBUG_EXECUTE_IF("simulate_slow_query", { + if (thd->get_command() == COM_QUERY || + thd->get_command() == COM_STMT_EXECUTE) + thd->server_status|= SERVER_QUERY_WAS_SLOW; + }); + if ((thd->server_status & (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) && - !(sql_command_flags[thd->last_sql_command] & CF_STATUS_COMMAND) && - (!thd->variables.log_slow_filter || - (thd->variables.log_slow_filter & QPLAN_NOT_USING_INDEX))) + !(thd->query_plan_flags & QPLAN_STATUS) && + !slow_filter_masked(thd, QPLAN_NOT_USING_INDEX)) { thd->query_plan_flags|= QPLAN_NOT_USING_INDEX; /* We are always logging no index queries if enabled in filter */ @@ -2543,7 +2529,15 @@ void log_slow_statement(THD *thd) { thd->status_var.long_query_count++; - if (!log_slow_enabled_statement(thd)) + /* + until log_slow_disabled_statements=admin is removed, it + duplicates slow_log_filter=admin + */ + if ((thd->query_plan_flags & QPLAN_ADMIN) && + (thd->variables.log_slow_disabled_statements & LOG_SLOW_DISABLE_ADMIN)) + goto end; + + if (!global_system_variables.sql_log_slow || !thd->variables.sql_log_slow) goto end; /* @@ -2558,8 +2552,7 @@ void log_slow_statement(THD *thd) Follow the slow log filter configuration: skip logging if the current statement matches the filter. */ - if (thd->variables.log_slow_filter && - !(thd->variables.log_slow_filter & thd->query_plan_flags)) + if (slow_filter_masked(thd, thd->query_plan_flags)) goto end; THD_STAGE_INFO(thd, stage_logging_slow_query); @@ -3729,6 +3722,11 @@ mysql_execute_command(THD *thd) goto error; } + if (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) + thd->query_plan_flags|= QPLAN_STATUS; + if (sql_command_flags[lex->sql_command] & CF_ADMIN_COMMAND) + thd->query_plan_flags|= QPLAN_ADMIN; + /* Start timeouts */ thd->set_query_timer(); @@ -3792,12 +3790,14 @@ mysql_execute_command(THD *thd) case SQLCOM_SHOW_PROFILE: case SQLCOM_SELECT: { -#ifdef WITH_WSREP if (lex->sql_command == SQLCOM_SELECT) - WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_READ) + WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_READ); else - WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW) -#endif /* WITH_WSREP */ + { + WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW); + if (lex->sql_command == SQLCOM_SHOW_PROFILE) + thd->profiling.discard_current_query(); + } thd->status_var.last_query_cost= 0.0; @@ -4370,12 +4370,6 @@ end_with_restore_list: if (check_one_table_access(thd, INDEX_ACL, all_tables)) goto error; /* purecov: inspected */ WSREP_TO_ISOLATION_BEGIN(first_table->db.str, first_table->table_name.str, NULL); - /* - Currently CREATE INDEX or DROP INDEX cause a full table rebuild - and thus classify as slow administrative statements just like - ALTER TABLE. - */ - thd->prepare_logs_for_admin_command(); bzero((char*) &create_info, sizeof(create_info)); create_info.db_type= 0; @@ -4538,48 +4532,6 @@ end_with_restore_list: DBUG_PRINT("debug", ("lex->only_view: %d, table: %s.%s", lex->table_type == TABLE_TYPE_VIEW, first_table->db.str, first_table->table_name.str)); - if (lex->table_type == TABLE_TYPE_VIEW) - { - if (check_table_access(thd, SELECT_ACL, first_table, FALSE, 1, FALSE)) - { - DBUG_PRINT("debug", ("check_table_access failed")); - my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), - "SHOW", thd->security_ctx->priv_user, - thd->security_ctx->host_or_ip, first_table->alias.str); - goto error; - } - DBUG_PRINT("debug", ("check_table_access succeeded")); - - /* Ignore temporary tables if this is "SHOW CREATE VIEW" */ - first_table->open_type= OT_BASE_ONLY; - } - else - { - /* - Temporary tables should be opened for SHOW CREATE TABLE, but not - for SHOW CREATE VIEW. - */ - if (thd->open_temporary_tables(all_tables)) - goto error; - - /* - The fact that check_some_access() returned FALSE does not mean that - access is granted. We need to check if first_table->grant.privilege - contains any table-specific privilege. - */ - DBUG_PRINT("debug", ("first_table->grant.privilege: %lx", - first_table->grant.privilege)); - if (check_some_access(thd, SHOW_CREATE_TABLE_ACLS, first_table) || - (first_table->grant.privilege & SHOW_CREATE_TABLE_ACLS) == 0) - { - my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), - "SHOW", thd->security_ctx->priv_user, - thd->security_ctx->host_or_ip, first_table->alias.str); - goto error; - } - } - - /* Access is granted. Execute the command. */ res= mysqld_show_create(thd, first_table); break; #endif @@ -4932,7 +4884,7 @@ end_with_restore_list: case SQLCOM_DELETE: { WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE); - select_result *sel_result=lex->result; + select_result *sel_result= NULL; DBUG_ASSERT(first_table == all_tables && first_table != 0); if (WSREP_CLIENT(thd) && wsrep_sync_wait(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE)) @@ -4963,16 +4915,15 @@ end_with_restore_list: } else { - if (!(sel_result= lex->result) && - !(sel_result= new (thd->mem_root) select_send(thd))) - return 1; + if (!lex->result && !(sel_result= new (thd->mem_root) select_send(thd))) + goto error; } } res = mysql_delete(thd, all_tables, select_lex->where, &select_lex->order_list, unit->select_limit_cnt, select_lex->options, - sel_result); + lex->result ? lex->result : sel_result); if (replaced_protocol) { @@ -6325,8 +6276,6 @@ end_with_restore_list: DBUG_ASSERT(first_table == all_tables && first_table != 0); /* fall through */ case SQLCOM_ALTER_SEQUENCE: - thd->query_plan_flags|= QPLAN_ADMIN; - /* fall through */ case SQLCOM_SIGNAL: case SQLCOM_RESIGNAL: case SQLCOM_GET_DIAGNOSTICS: @@ -6579,8 +6528,8 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables) Protocol *save_protocol= NULL; if (lex->analyze_stmt) { - if (result && result->is_result_interceptor()) - ((select_result_interceptor*)result)->disable_my_ok_calls(); + if (result && result->result_interceptor()) + result->result_interceptor()->disable_my_ok_calls(); else { DBUG_ASSERT(thd->protocol); @@ -7137,7 +7086,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table) Check_grant will grant access if there is any column privileges on all of the tables thanks to the fourth parameter (bool show_table). */ - if (check_grant(thd, SELECT_ACL, dst_table, TRUE, UINT_MAX, FALSE)) + if (check_grant(thd, SELECT_ACL, dst_table, TRUE, 1, FALSE)) return TRUE; /* Access denied */ close_thread_tables(thd); @@ -9664,7 +9613,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, goto err; /* If it is a merge table, check privileges for merge children. */ - if (lex->create_info.merge_list.first) + if (lex->create_info.merge_list) { /* The user must have (SELECT_ACL | UPDATE_ACL | DELETE_ACL) on the @@ -9702,8 +9651,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, */ if (check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL, - lex->create_info.merge_list.first, - FALSE, UINT_MAX, FALSE)) + lex->create_info.merge_list, FALSE, UINT_MAX, FALSE)) goto err; } |