summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/flush.result27
-rw-r--r--mysql-test/t/flush.test31
-rw-r--r--sql/sql_parse.cc23
3 files changed, 81 insertions, 0 deletions
diff --git a/mysql-test/r/flush.result b/mysql-test/r/flush.result
index fd23bfa0562..3702443d04a 100644
--- a/mysql-test/r/flush.result
+++ b/mysql-test/r/flush.result
@@ -207,3 +207,30 @@ insert into t2 (a) values (3);
unlock tables;
# --> connection con1
drop table t1, t2, t3;
+#
+# Bug#51710 FLUSH TABLES <view> WITH READ LOCK kills the server
+#
+drop view if exists v1, v2, v3;
+drop table if exists t1, v1;
+create table t1 (a int);
+create view v1 as select 1;
+create view v2 as select * from t1;
+create view v3 as select * from v2;
+flush table v1, v2, v3 with read lock;
+ERROR HY000: 'test.v1' is not BASE TABLE
+flush table v1 with read lock;
+ERROR HY000: 'test.v1' is not BASE TABLE
+flush table v2 with read lock;
+ERROR HY000: 'test.v2' is not BASE TABLE
+flush table v3 with read lock;
+ERROR HY000: 'test.v3' is not BASE TABLE
+create temporary table v1 (a int);
+flush table v1 with read lock;
+ERROR HY000: 'test.v1' is not BASE TABLE
+drop view v1;
+create table v1 (a int);
+flush table v1 with read lock;
+drop temporary table v1;
+unlock tables;
+drop view v2, v3;
+drop table t1, v1;
diff --git a/mysql-test/t/flush.test b/mysql-test/t/flush.test
index 582d2562fc6..0d406338394 100644
--- a/mysql-test/t/flush.test
+++ b/mysql-test/t/flush.test
@@ -324,3 +324,34 @@ disconnect con1;
--source include/wait_until_disconnected.inc
connection default;
drop table t1, t2, t3;
+
+--echo #
+--echo # Bug#51710 FLUSH TABLES <view> WITH READ LOCK kills the server
+--echo #
+--disable_warnings
+drop view if exists v1, v2, v3;
+drop table if exists t1, v1;
+--enable_warnings
+create table t1 (a int);
+create view v1 as select 1;
+create view v2 as select * from t1;
+create view v3 as select * from v2;
+
+--error ER_WRONG_OBJECT
+flush table v1, v2, v3 with read lock;
+--error ER_WRONG_OBJECT
+flush table v1 with read lock;
+--error ER_WRONG_OBJECT
+flush table v2 with read lock;
+--error ER_WRONG_OBJECT
+flush table v3 with read lock;
+create temporary table v1 (a int);
+--error ER_WRONG_OBJECT
+flush table v1 with read lock;
+drop view v1;
+create table v1 (a int);
+flush table v1 with read lock;
+drop temporary table v1;
+unlock tables;
+drop view v2, v3;
+drop table t1, v1;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 6403ad99282..23e0d8c0d70 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1631,6 +1631,14 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
- you can't flush WITH READ LOCK a non-existent table
- you can't flush WITH READ LOCK under LOCK TABLES
- currently incompatible with the GRL (@todo: fix)
+
+ Effect on views and temporary tables.
+ ------------------------------------
+ You can only apply this command to existing base tables.
+ If a view with such name exists, ER_WRONG_OBJECT is returned.
+ If a temporary table with such name exists, it's ignored:
+ if there is a base table, it's used, otherwise ER_NO_SUCH_TABLE
+ is returned.
*/
static bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
@@ -1665,6 +1673,21 @@ static bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
if (lock_table_names(thd, all_tables))
goto error;
+ for (table_list= all_tables; table_list;
+ table_list= table_list->next_global)
+ {
+ /* Remove the table from cache. */
+ mysql_mutex_lock(&LOCK_open);
+ tdc_remove_table(thd, TDC_RT_REMOVE_ALL,
+ table_list->db,
+ table_list->table_name);
+ mysql_mutex_unlock(&LOCK_open);
+
+ /* Skip views and temporary tables. */
+ table_list->required_type= FRMTYPE_TABLE; /* Don't try to flush views. */
+ table_list->open_type= OT_BASE_ONLY; /* Ignore temporary tables. */
+ }
+
if (open_and_lock_tables(thd, all_tables, FALSE,
MYSQL_OPEN_HAS_MDL_LOCK,
&lock_tables_prelocking_strategy) ||