diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2019-03-05 12:56:05 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2019-03-05 12:56:05 +0200 |
commit | 446b3ebdfc75f3a97d349d1347c4900a2e3eee03 (patch) | |
tree | 1fc75e520ac84591d2e2c647855f153a07ec3190 /sql | |
parent | 8f4de38f65ba89c6273c15c9adb50ab762d03f59 (diff) | |
parent | 90f09ba8c249e23e015ce9d1d56463869f1a5358 (diff) | |
download | mariadb-git-446b3ebdfc75f3a97d349d1347c4900a2e3eee03.tar.gz |
Merge 10.2 into 10.3
FIXME: Properly resolve conflicts between MDEV-18883
and MDEV-7742/MDEV-8305, and record the correct result for
main.log_slow
Diffstat (limited to 'sql')
-rw-r--r-- | sql/sql_admin.cc | 4 | ||||
-rw-r--r-- | sql/sql_admin.h | 8 | ||||
-rw-r--r-- | sql/sql_alter.h | 2 | ||||
-rw-r--r-- | sql/sql_cmd.h | 13 | ||||
-rw-r--r-- | sql/sql_delete.cc | 8 | ||||
-rw-r--r-- | sql/sql_derived.cc | 31 | ||||
-rw-r--r-- | sql/sql_derived.h | 1 | ||||
-rw-r--r-- | sql/sql_insert.cc | 3 | ||||
-rw-r--r-- | sql/sql_lex.cc | 32 | ||||
-rw-r--r-- | sql/sql_lex.h | 32 | ||||
-rw-r--r-- | sql/sql_load.cc | 10 | ||||
-rw-r--r-- | sql/sql_parse.cc | 58 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 22 | ||||
-rw-r--r-- | sql/sql_select.cc | 4 | ||||
-rw-r--r-- | sql/sql_union.cc | 5 |
15 files changed, 153 insertions, 80 deletions
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index c17567e6a89..914cd4d826b 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2010, 2015, Oracle and/or its affiliates. - Copyright (c) 2011, 2018, MariaDB + Copyright (c) 2011, 2019, MariaDB 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 @@ -1398,8 +1398,6 @@ bool Sql_cmd_repair_table::execute(THD *thd) if (check_table_access(thd, SELECT_ACL | INSERT_ACL, first_table, FALSE, UINT_MAX, FALSE)) goto error; /* purecov: inspected */ - thd->enable_slow_log&= !MY_TEST(thd->variables.log_slow_disabled_statements & - LOG_SLOW_DISABLE_ADMIN); WSREP_TO_ISOLATION_BEGIN_WRTCHK(NULL, NULL, first_table); res= mysql_admin_table(thd, first_table, &m_lex->check_opt, "repair", TL_WRITE, 1, diff --git a/sql/sql_admin.h b/sql/sql_admin.h index e7f4086540a..dea835c2de9 100644 --- a/sql/sql_admin.h +++ b/sql/sql_admin.h @@ -28,7 +28,7 @@ int reassign_keycache_tables(THD* thd, KEY_CACHE *src_cache, /** Sql_cmd_analyze_table represents the ANALYZE TABLE statement. */ -class Sql_cmd_analyze_table : public Sql_cmd +class Sql_cmd_analyze_table : public Sql_cmd_admin { public: /** @@ -53,7 +53,7 @@ public: /** Sql_cmd_check_table represents the CHECK TABLE statement. */ -class Sql_cmd_check_table : public Sql_cmd +class Sql_cmd_check_table : public Sql_cmd_admin { public: /** @@ -77,7 +77,7 @@ public: /** Sql_cmd_optimize_table represents the OPTIMIZE TABLE statement. */ -class Sql_cmd_optimize_table : public Sql_cmd +class Sql_cmd_optimize_table : public Sql_cmd_admin { public: /** @@ -102,7 +102,7 @@ public: /** Sql_cmd_repair_table represents the REPAIR TABLE statement. */ -class Sql_cmd_repair_table : public Sql_cmd +class Sql_cmd_repair_table : public Sql_cmd_admin { public: /** diff --git a/sql/sql_alter.h b/sql/sql_alter.h index 14242015bd2..e2e7abe2a1c 100644 --- a/sql/sql_alter.h +++ b/sql/sql_alter.h @@ -333,7 +333,7 @@ private: statements. @todo move Alter_info and other ALTER generic structures from Lex here. */ -class Sql_cmd_common_alter_table : public Sql_cmd +class Sql_cmd_common_alter_table : public Sql_cmd_admin { protected: /** diff --git a/sql/sql_cmd.h b/sql/sql_cmd.h index 1c4c89eb132..83dd1b1da4f 100644 --- a/sql/sql_cmd.h +++ b/sql/sql_cmd.h @@ -160,6 +160,8 @@ public: */ virtual bool execute(THD *thd) = 0; + virtual bool log_slow_enabled_statement(const THD *thd) const; + protected: Sql_cmd() {} @@ -177,6 +179,17 @@ protected: }; +class Sql_cmd_admin: public Sql_cmd +{ +public: + Sql_cmd_admin() + {} + ~Sql_cmd_admin() + {} + bool log_slow_enabled_statement(const THD *thd) const; +}; + + /** Sql_cmd_call represents the CALL statement. */ diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 6cf89ed09fc..1735a5ac863 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2010, Oracle and/or its affiliates. - Copyright (c) 2010, 2015, MariaDB + Copyright (c) 2010, 2019, MariaDB 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 @@ -41,7 +41,7 @@ #include "records.h" // init_read_record, #include "filesort.h" #include "uniques.h" -#include "sql_derived.h" // mysql_handle_list_of_derived +#include "sql_derived.h" // mysql_handle_derived // end_read_record #include "sql_partition.h" // make_used_partitions_str @@ -335,9 +335,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, } } - if (mysql_handle_list_of_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT)) + if (thd->lex->handle_list_of_derived(table_list, DT_MERGE_FOR_INSERT)) DBUG_RETURN(TRUE); - if (mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE)) + if (thd->lex->handle_list_of_derived(table_list, DT_PREPARE)) DBUG_RETURN(TRUE); if (!table_list->single_table_updatable()) diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 589d0214292..e6a2d54ae6f 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -93,6 +93,7 @@ mysql_handle_derived(LEX *lex, uint phases) sl= sl->next_select_in_list()) { TABLE_LIST *cursor= sl->get_table_list(); + sl->changed_elements|= TOUCHED_SEL_DERIVED; /* DT_MERGE_FOR_INSERT is not needed for views/derived tables inside subqueries. Views and derived tables of subqueries should be @@ -203,36 +204,6 @@ mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases) /** - Run specified phases for derived tables/views in the given list - - @param lex LEX for this thread - @param table_list list of derived tables/view to handle - @param phase_map phases to process tables/views through - - @details - This function runs phases specified by the 'phases_map' on derived - tables/views found in the 'dt_list' with help of the - TABLE_LIST::handle_derived function. - 'lex' is passed as an argument to the TABLE_LIST::handle_derived. - - @return FALSE ok - @return TRUE error -*/ - -bool -mysql_handle_list_of_derived(LEX *lex, TABLE_LIST *table_list, uint phases) -{ - for (TABLE_LIST *tl= table_list; tl; tl= tl->next_local) - { - if (tl->is_view_or_derived() && - tl->handle_derived(lex, phases)) - return TRUE; - } - return FALSE; -} - - -/** Merge a derived table/view into the embedding select @param thd thread handle diff --git a/sql/sql_derived.h b/sql/sql_derived.h index f098cf39083..621a6e9ec24 100644 --- a/sql/sql_derived.h +++ b/sql/sql_derived.h @@ -22,7 +22,6 @@ struct LEX; bool mysql_handle_derived(LEX *lex, uint phases); bool mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases); -bool mysql_handle_list_of_derived(LEX *lex, TABLE_LIST *dt_list, uint phases); bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived); /** diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index aade7e0d876..c6c14bd6ffb 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1491,7 +1491,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, DBUG_RETURN(TRUE); if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT)) DBUG_RETURN(TRUE); - if (mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE)) + if (thd->lex->handle_list_of_derived(table_list, DT_PREPARE)) DBUG_RETURN(TRUE); /* For subqueries in VALUES() we should not see the table in which we are @@ -1584,7 +1584,6 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, DBUG_RETURN(TRUE); } select_lex->fix_prepare_information(thd, &fake_conds, &fake_conds); - select_lex->first_execution= 0; } /* Only call prepare_for_posistion() if we are not performing a DELAYED diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 4282a8fb8ae..d6cc62c9dbf 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2014, Oracle and/or its affiliates. - Copyright (c) 2009, 2018, MariaDB Corporation + Copyright (c) 2009, 2019, 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 @@ -2317,7 +2317,7 @@ void st_select_lex::init_query() hidden_bit_fields= 0; subquery_in_having= explicit_limit= 0; is_item_list_lookup= 0; - first_execution= 1; + changed_elements= 0; first_natural_join_processing= 1; first_cond_optimization= 1; parsing_place= NO_MATTER; @@ -3843,10 +3843,11 @@ void st_select_lex::fix_prepare_information(THD *thd, Item **conds, Item **having_conds) { DBUG_ENTER("st_select_lex::fix_prepare_information"); - if (!thd->stmt_arena->is_conventional() && first_execution) + if (!thd->stmt_arena->is_conventional() && + !(changed_elements & TOUCHED_SEL_COND)) { Query_arena_stmt on_stmt_arena(thd); - first_execution= 0; + changed_elements|= TOUCHED_SEL_COND; if (group_list.first) { if (!group_list_ptrs) @@ -4097,14 +4098,7 @@ bool st_select_lex::optimize_unflattened_subqueries(bool const_only) bool st_select_lex::handle_derived(LEX *lex, uint phases) { - for (TABLE_LIST *cursor= (TABLE_LIST*) table_list.first; - cursor; - cursor= cursor->next_local) - { - if (cursor->is_view_or_derived() && cursor->handle_derived(lex, phases)) - return TRUE; - } - return FALSE; + return lex->handle_list_of_derived(table_list.first, phases); } @@ -5110,6 +5104,20 @@ bool LEX::is_partition_management() const } +bool Sql_cmd::log_slow_enabled_statement(const THD *thd) const +{ + return global_system_variables.sql_log_slow && thd->variables.sql_log_slow; +} + + +bool Sql_cmd_admin::log_slow_enabled_statement(const THD *thd) const +{ + return !MY_TEST(thd->variables.log_slow_disabled_statements & + LOG_SLOW_DISABLE_ADMIN) && + Sql_cmd::log_slow_enabled_statement(thd); +} + + /** Exclude last added SELECT_LEX (current) in the UNIT and return pointer in it (previous become currect) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 0e916b6c1c1..926b09ed3a7 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -931,6 +931,10 @@ public: :tmp_field(fld), producing_item(item) {} }; + +#define TOUCHED_SEL_COND 1/* WHERE/HAVING/ON should be reinited before use */ +#define TOUCHED_SEL_DERIVED (1<<1)/* derived should be reinited before use */ + /* SELECT_LEX - store information of parsed SELECT statment */ @@ -1117,7 +1121,8 @@ public: subquery. Prepared statements work OK in that regard, as in case of an error during prepare the PS is not created. */ - bool first_execution; + uint8 changed_elements; // see TOUCHED_SEL_* + /* TODO: add foloowing first_* to bitmap above */ bool first_natural_join_processing; bool first_cond_optimization; /* do not wrap view fields with Item_ref */ @@ -3949,6 +3954,31 @@ public: bool tmp_table() const { return create_info.tmp_table(); } bool if_exists() const { return create_info.if_exists(); } + /* + Run specified phases for derived tables/views in the given list + + @param table_list - list of derived tables/view to handle + @param phase - phases to process tables/views through + + @details + This method runs phases specified by the 'phases' on derived + tables/views found in the 'table_list' with help of the + TABLE_LIST::handle_derived function. + 'this' is passed as an argument to the TABLE_LIST::handle_derived. + + @return false - ok + @return true - error + */ + bool handle_list_of_derived(TABLE_LIST *table_list, uint phases) + { + for (TABLE_LIST *tl= table_list; tl; tl= tl->next_local) + { + if (tl->is_view_or_derived() && tl->handle_derived(this, phases)) + return true; + } + return false; + } + SELECT_LEX *exclude_last_select(); bool add_unit_in_brackets(SELECT_LEX *nselect); void check_automatic_up(enum sub_select_type type); diff --git a/sql/sql_load.cc b/sql/sql_load.cc index ddb5029c78a..b7e110e4b95 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -387,8 +387,9 @@ int mysql_load(THD *thd, const sql_exchange *ex, TABLE_LIST *table_list, if (open_and_lock_tables(thd, table_list, TRUE, 0)) DBUG_RETURN(TRUE); - if (mysql_handle_single_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT) || - mysql_handle_single_derived(thd->lex, table_list, DT_PREPARE)) + if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT)) + DBUG_RETURN(TRUE); + if (thd->lex->handle_list_of_derived(table_list, DT_PREPARE)) DBUG_RETURN(TRUE); if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context, &thd->lex->select_lex.top_join_list, @@ -404,6 +405,11 @@ int mysql_load(THD *thd, const sql_exchange *ex, TABLE_LIST *table_list, my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias.str, "LOAD"); DBUG_RETURN(TRUE); } + if (table_list->is_multitable()) + { + my_error(ER_WRONG_USAGE, MYF(0), "Multi-table VIEW", "LOAD"); + DBUG_RETURN(TRUE); + } if (table_list->prepare_where(thd, 0, TRUE) || table_list->prepare_check_option(thd)) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 73f17c21abe..f03f4590447 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1642,7 +1642,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->variables.log_slow_disabled_statements defines which statements are logged to slow log */ - thd->enable_slow_log= thd->variables.sql_log_slow; + thd->enable_slow_log= true; thd->query_plan_flags= QPLAN_INIT; thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */ thd->reset_kill_query(); @@ -2466,6 +2466,32 @@ 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) && + 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; +} + + /* Log query to slow queries, if it passes filtering @@ -2484,8 +2510,17 @@ void log_slow_statement(THD *thd) */ if (unlikely(thd->in_sub_stmt)) goto end; // Don't set time for sub stmt - if (!thd->enable_slow_log || !global_system_variables.sql_log_slow) - goto end; + /* + Skip both long_query_count increment and logging if the current + statement forces slow log suppression (e.g. an SP statement). + + Note, we don't check for global_system_variables.sql_log_slow here. + According to the manual, the "Slow_queries" status variable does not require + sql_log_slow to be ON. So even if sql_log_slow is OFF, we still need to + continue and increment long_query_count (and skip only logging, see below): + */ + if (!thd->enable_slow_log) + goto end; // E.g. SP statement if ((thd->server_status & (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) && @@ -2498,15 +2533,14 @@ void log_slow_statement(THD *thd) thd->server_status|= SERVER_QUERY_WAS_SLOW; } - /* Follow the slow log filter configuration. */ - if (thd->variables.log_slow_filter && - !(thd->variables.log_slow_filter & thd->query_plan_flags)) - goto end; - if ((thd->server_status & SERVER_QUERY_WAS_SLOW) && thd->get_examined_row_count() >= thd->variables.min_examined_row_limit) { thd->status_var.long_query_count++; + + if (!log_slow_enabled_statement(thd)) + goto end; + /* If rate limiting of slow log writes is enabled, decide whether to log this query to the log or not. @@ -2515,6 +2549,14 @@ void log_slow_statement(THD *thd) (global_query_id % thd->variables.log_slow_rate_limit) != 0) goto end; + /* + 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)) + goto end; + THD_STAGE_INFO(thd, stage_logging_slow_query); slow_log_print(thd, thd->query(), thd->query_length(), thd->utime_after_query); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 2bbbd5054c8..d83e88a8d13 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2002, 2015, Oracle and/or its affiliates. - Copyright (c) 2008, 2017, MariaDB + Copyright (c) 2008, 2019, MariaDB 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 @@ -2930,7 +2930,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) } for (; sl; sl= sl->next_select_in_list()) { - if (!sl->first_execution) + if (sl->changed_elements & TOUCHED_SEL_COND) { /* remove option which was put by mysql_explain_union() */ sl->options&= ~SELECT_DESCRIBE; @@ -2977,8 +2977,13 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) order->next= sl->group_list_ptrs->at(ix+1); } } + } + { // no harm to do it (item_ptr set on parsing) + ORDER *order; for (order= sl->group_list.first; order; order= order->next) + { order->item= &order->item_ptr; + } /* Fix ORDER list */ for (order= sl->order_list.first; order; order= order->next) order->item= &order->item_ptr; @@ -2992,15 +2997,16 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) for (order= win_spec->order_list->first; order; order= order->next) order->item= &order->item_ptr; } - - { + } + if (sl->changed_elements & TOUCHED_SEL_DERIVED) + { #ifdef DBUG_ASSERT_EXISTS - bool res= + bool res= #endif - sl->handle_derived(lex, DT_REINIT); - DBUG_ASSERT(res == 0); - } + sl->handle_derived(lex, DT_REINIT); + DBUG_ASSERT(res == 0); } + { SELECT_LEX_UNIT *unit= sl->master_unit(); unit->unclean(); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index e084ad74224..831bd66166c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2016 Oracle and/or its affiliates. - Copyright (c) 2009, 2018 MariaDB Corporation + Copyright (c) 2009, 2019 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 @@ -1184,7 +1184,7 @@ JOIN::prepare(TABLE_LIST *tables_init, select_lex->check_unrestricted_recursive( thd->variables.only_standard_compliant_cte)) DBUG_RETURN(-1); - if (select_lex->first_execution) + if (!(select_lex->changed_elements & TOUCHED_SEL_COND)) select_lex->check_subqueries_with_recursive_references(); int res= check_and_do_in_subquery_rewrites(this); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index edf85c2084b..7b0e79620ff 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -611,8 +611,9 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg, called at the first execution of the statement, while first_execution shows whether this is called at the first execution of the union that may form just a subselect. - */ - if (!fake_select_lex->first_execution && first_execution) + */ + if ((fake_select_lex->changed_elements & TOUCHED_SEL_COND) && + first_execution) { for (ORDER *order= global_parameters()->order_list.first; order; |