diff options
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r-- | sql/sql_parse.cc | 148 |
1 files changed, 48 insertions, 100 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1d5de9dc276..d2dde1277a1 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -546,10 +546,11 @@ void init_update_queries(void) sql_command_flags[SQLCOM_CREATE_TABLE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS | CF_CAN_GENERATE_ROW_EVENTS; - 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_REPORT_PROGRESS | CF_ADMIN_COMMAND; 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_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; @@ -560,8 +561,10 @@ void init_update_queries(void) sql_command_flags[SQLCOM_DROP_DB]= 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; - 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; @@ -735,10 +738,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; @@ -1612,10 +1619,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, m_key); thd->set_command(command); - /* - Commands which always take a long time are logged into - the slow log only if opt_log_slow_admin_statements is set. - */ thd->enable_slow_log= true; thd->query_plan_flags= QPLAN_INIT; thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */ @@ -2062,7 +2065,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, status_var_increment(thd->status_var.com_other); - thd->enable_slow_log&= opt_log_slow_admin_statements; thd->query_plan_flags|= QPLAN_ADMIN; if (check_global_access(thd, REPL_SLAVE_ACL)) break; @@ -2449,31 +2451,6 @@ com_multi_end: } -static bool log_slow_enabled_statement(const THD *thd) -{ - /* - 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) && - !opt_log_slow_admin_statements) - return true; - - return global_system_variables.sql_log_slow && - thd->variables.sql_log_slow; -} - - /* @note This function must call delete_explain_query(). @@ -2502,16 +2479,27 @@ void log_slow_statement(THD *thd) if (!thd->enable_slow_log) goto end; // E.g. SP statement + DBUG_EXECUTE_IF("simulate_slow_query", + thd->server_status|= SERVER_QUERY_WAS_SLOW;); + if (((thd->server_status & SERVER_QUERY_WAS_SLOW) || ((thd->server_status & (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) && opt_log_queries_not_using_indexes && - !(sql_command_flags[thd->lex->sql_command] & CF_STATUS_COMMAND))) && + !(thd->query_plan_flags & QPLAN_STATUS))) && thd->get_examined_row_count() >= thd->variables.min_examined_row_limit) { thd->status_var.long_query_count++; - if (!log_slow_enabled_statement(thd)) + /* + until opt_log_slow_admin_statements is removed, it + duplicates slow_log_filter=admin + */ + if ((thd->query_plan_flags & QPLAN_ADMIN) && + !opt_log_slow_admin_statements) + goto end; + + if (!global_system_variables.sql_log_slow || !thd->variables.sql_log_slow) goto end; /* @@ -3448,6 +3436,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(); @@ -3510,12 +3503,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; @@ -4080,7 +4075,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, first_table->table_name, NULL) - thd->query_plan_flags|= QPLAN_ADMIN; bzero((char*) &create_info, sizeof(create_info)); create_info.db_type= 0; @@ -4243,49 +4237,6 @@ end_with_restore_list: DBUG_PRINT("debug", ("lex->only_view: %d, table: %s.%s", lex->only_view, first_table->db, first_table->table_name)); - if (lex->only_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); - 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); - goto error; - } - } - - /* Access is granted. Execute the command. */ res= mysqld_show_create(thd, first_table); break; #endif @@ -4637,7 +4588,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)) @@ -4668,16 +4619,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) { @@ -6262,7 +6212,6 @@ end_with_restore_list: case SQLCOM_REPAIR: case SQLCOM_TRUNCATE: case SQLCOM_ALTER_TABLE: - thd->query_plan_flags|= QPLAN_ADMIN; DBUG_ASSERT(first_table == all_tables && first_table != 0); /* fall through */ case SQLCOM_SIGNAL: @@ -6506,8 +6455,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); @@ -7062,7 +7011,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); @@ -9599,7 +9548,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 @@ -9637,8 +9586,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; } |