summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-03-04 16:46:58 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2019-03-04 16:46:58 +0200
commit9835f7b80fc0eaa7fe4969ae87ae1bfbcc7aa157 (patch)
tree8c12732d7d80790d1f70ed5e302398600b733186 /sql
parent74d648db12e100c628548fb2e5aa67de718bd1fb (diff)
parent91e4f00389483d22fa81517bbcdcd21499fd283a (diff)
downloadmariadb-git-9835f7b80fc0eaa7fe4969ae87ae1bfbcc7aa157.tar.gz
Merge 10.1 into 10.2
Diffstat (limited to 'sql')
-rw-r--r--sql/log_event.cc2
-rw-r--r--sql/sql_admin.cc5
-rw-r--r--sql/sql_admin.h8
-rw-r--r--sql/sql_alter.cc4
-rw-r--r--sql/sql_alter.h2
-rw-r--r--sql/sql_cmd.h15
-rw-r--r--sql/sql_delete.cc8
-rw-r--r--sql/sql_derived.cc31
-rw-r--r--sql/sql_derived.h1
-rw-r--r--sql/sql_insert.cc3
-rw-r--r--sql/sql_lex.cc30
-rw-r--r--sql/sql_lex.h32
-rw-r--r--sql/sql_load.cc10
-rw-r--r--sql/sql_parse.cc62
-rw-r--r--sql/sql_partition_admin.cc1
-rw-r--r--sql/sql_prepare.cc22
-rw-r--r--sql/sql_select.cc4
-rw-r--r--sql/sql_union.cc5
18 files changed, 153 insertions, 92 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 947bcbf3509..8990e1953b6 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -5340,7 +5340,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi,
thd->variables.sql_log_slow= opt_log_slow_slave_statements;
}
- thd->enable_slow_log= thd->variables.sql_log_slow;
+ thd->enable_slow_log= true;
mysql_parse(thd, thd->query(), thd->query_length(), &parser_state,
FALSE, FALSE);
/* Finalize server status flags after executing a statement. */
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index edb94019cc6..155ed3bcecb 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -1305,7 +1305,6 @@ bool Sql_cmd_analyze_table::execute(THD *thd)
FALSE, UINT_MAX, FALSE))
goto error;
WSREP_TO_ISOLATION_BEGIN_WRTCHK(NULL, NULL, first_table);
- thd->enable_slow_log= opt_log_slow_admin_statements;
res= mysql_admin_table(thd, first_table, &m_lex->check_opt,
"analyze", lock_type, 1, 0, 0, 0,
&handler::ha_analyze, 0);
@@ -1337,8 +1336,6 @@ bool Sql_cmd_check_table::execute(THD *thd)
if (check_table_access(thd, SELECT_ACL, first_table,
TRUE, UINT_MAX, FALSE))
goto error; /* purecov: inspected */
- thd->enable_slow_log= opt_log_slow_admin_statements;
-
res= mysql_admin_table(thd, first_table, &m_lex->check_opt, "check",
lock_type, 0, 0, HA_OPEN_FOR_REPAIR, 0,
&handler::ha_check, &view_check);
@@ -1362,7 +1359,6 @@ bool Sql_cmd_optimize_table::execute(THD *thd)
FALSE, UINT_MAX, FALSE))
goto error; /* purecov: inspected */
WSREP_TO_ISOLATION_BEGIN_WRTCHK(NULL, NULL, first_table);
- thd->enable_slow_log= opt_log_slow_admin_statements;
res= (specialflag & SPECIAL_NO_NEW_FUNC) ?
mysql_recreate_table(thd, first_table, true) :
mysql_admin_table(thd, first_table, &m_lex->check_opt,
@@ -1395,7 +1391,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= opt_log_slow_admin_statements;
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 96594fad0cb..ce7308434c5 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.cc b/sql/sql_alter.cc
index f76c4046ee0..23522795cdc 100644
--- a/sql/sql_alter.cc
+++ b/sql/sql_alter.cc
@@ -303,8 +303,6 @@ bool Sql_cmd_alter_table::execute(THD *thd)
"INDEX DIRECTORY");
create_info.data_file_name= create_info.index_file_name= NULL;
- thd->enable_slow_log= opt_log_slow_admin_statements;
-
#ifdef WITH_WSREP
if (WSREP(thd) &&
(!thd->is_current_stmt_binlog_format_row() ||
@@ -351,8 +349,6 @@ bool Sql_cmd_discard_import_tablespace::execute(THD *thd)
if (check_grant(thd, ALTER_ACL, table_list, false, UINT_MAX, false))
return true;
- thd->enable_slow_log= opt_log_slow_admin_statements;
-
/*
Check if we attempt to alter mysql.slow_log or
mysql.general_log table and return an error if
diff --git a/sql/sql_alter.h b/sql/sql_alter.h
index e33efc9476f..9114c4bd075 100644
--- a/sql/sql_alter.h
+++ b/sql/sql_alter.h
@@ -370,7 +370,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 e33f8e443dc..d6220f9ee44 100644
--- a/sql/sql_cmd.h
+++ b/sql/sql_cmd.h
@@ -148,6 +148,8 @@ public:
*/
virtual bool execute(THD *thd) = 0;
+ virtual bool log_slow_enabled_statement(const THD *thd) const;
+
protected:
Sql_cmd()
{}
@@ -164,4 +166,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;
+};
+
+
+
#endif // SQL_CMD_INCLUDED
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index c0deb33410d..503e9b9dcbe 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
@@ -252,9 +252,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (open_and_lock_tables(thd, table_list, TRUE, 0))
DBUG_RETURN(TRUE);
- 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 44f8d74790f..500b0431bf9 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 b6d31c27feb..307473cecbd 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1482,7 +1482,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
@@ -1568,7 +1568,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 869d990ed6e..399e189a8d0 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -2132,7 +2132,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;
@@ -3661,9 +3661,10 @@ 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))
{
- first_execution= 0;
+ changed_elements|= TOUCHED_SEL_COND;
if (group_list.first)
{
if (!group_list_ptrs)
@@ -3914,14 +3915,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);
}
@@ -4843,6 +4837,20 @@ bool LEX::is_partition_management() const
alter_info.flags == Alter_info::ALTER_REORGANIZE_PARTITION));
}
+
+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 opt_log_slow_admin_statements &&
+ Sql_cmd::log_slow_enabled_statement(thd);
+}
+
+
#ifdef MYSQL_SERVER
uint binlog_unsafe_map[256];
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 53f2ec15341..2af1d527cd3 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -752,6 +752,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
*/
@@ -926,7 +930,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 */
@@ -3157,6 +3162,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;
+ }
};
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 37ac168de43..8c2f17dac3f 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -384,8 +384,9 @@ int mysql_load(THD *thd,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,
@@ -401,6 +402,11 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "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 ef5d1afcab2..507b1ffdc2b 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1616,7 +1616,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
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= 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();
@@ -2444,6 +2444,31 @@ 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().
@@ -2460,13 +2485,18 @@ void log_slow_statement(THD *thd)
if (unlikely(thd->in_sub_stmt))
goto end; // Don't set time for sub stmt
+ /*
+ 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
- /* Follow the slow log filter configuration. */
- if (!thd->enable_slow_log || !global_system_variables.sql_log_slow ||
- (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->server_status &
(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
@@ -2475,6 +2505,10 @@ void log_slow_statement(THD *thd)
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.
@@ -2483,6 +2517,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);
@@ -4033,12 +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)
- /*
- Currently CREATE INDEX or DROP INDEX cause a full table rebuild
- and thus classify as slow administrative statements just like
- ALTER TABLE.
- */
- thd->enable_slow_log&= opt_log_slow_admin_statements;
thd->query_plan_flags|= QPLAN_ADMIN;
bzero((char*) &create_info, sizeof(create_info));
diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc
index c13a4296996..7b2a2c24eff 100644
--- a/sql/sql_partition_admin.cc
+++ b/sql/sql_partition_admin.cc
@@ -91,7 +91,6 @@ bool Sql_cmd_alter_table_exchange_partition::execute(THD *thd)
DBUG_ASSERT(!create_info.data_file_name && !create_info.index_file_name);
WSREP_TO_ISOLATION_BEGIN_WRTCHK(NULL, NULL, first_table);
- thd->enable_slow_log= opt_log_slow_admin_statements;
DBUG_RETURN(exchange_partition(thd, first_table, &alter_info));
#ifdef WITH_WSREP
wsrep_error_label:
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index c3156ce1d5c..272d6615028 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
@@ -2944,7 +2944,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;
@@ -2991,8 +2991,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;
@@ -3006,15 +3011,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)
+ {
#ifndef DBUG_OFF
- 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 5e5878ebf65..91a6445c870 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
@@ -898,7 +898,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 eb66dce25e3..abee979ff1c 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -417,8 +417,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;