summaryrefslogtreecommitdiff
path: root/sql/sql_parse.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r--sql/sql_parse.cc166
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;
}