diff --git a/mysql-test/suite/galera/r/view.result b/mysql-test/suite/galera/r/view.result new file mode 100644 index 00000000000..4ab34e4a26a --- /dev/null +++ b/mysql-test/suite/galera/r/view.result @@ -0,0 +1,46 @@ +# +# MDEV-8464 : ALTER VIEW not replicated in some cases +# +# On node_1 +USE test; +CREATE TABLE t1(i INT) ENGINE=INNODB; +CREATE DEFINER=CURRENT_USER VIEW v1 AS SELECT * FROM t1; +CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t1; +CREATE ALGORITHM=TEMPTABLE VIEW v3 AS SELECT * FROM t1; +CREATE ALGORITHM=UNDEFINED DEFINER=CURRENT_USER VIEW v4 AS SELECT * FROM t1; +# On node_2 +USE test; +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci +SHOW CREATE VIEW v2; +View Create View character_set_client collation_connection +v2 CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci +SHOW CREATE VIEW v3; +View Create View character_set_client collation_connection +v3 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci +SHOW CREATE VIEW v4; +View Create View character_set_client collation_connection +v4 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS select `t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci +# On node_1 +ALTER ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1; +ALTER ALGORITHM=UNDEFINED VIEW v2 AS SELECT * FROM t1; +ALTER DEFINER=CURRENT_USER VIEW v3 AS SELECT * FROM t1; +ALTER ALGORITHM=TEMPTABLE DEFINER=CURRENT_USER VIEW v4 AS SELECT * FROM t1; +# On node_2 +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci +SHOW CREATE VIEW v2; +View Create View character_set_client collation_connection +v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci +SHOW CREATE VIEW v3; +View Create View character_set_client collation_connection +v3 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci +SHOW CREATE VIEW v4; +View Create View character_set_client collation_connection +v4 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS select `t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci +# Cleanup +DROP VIEW v1, v2, v3, v4; +DROP TABLE t1; +# End of tests diff --git a/mysql-test/suite/galera/t/view.test b/mysql-test/suite/galera/t/view.test new file mode 100644 index 00000000000..d72ad264358 --- /dev/null +++ b/mysql-test/suite/galera/t/view.test @@ -0,0 +1,43 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc + +--echo # +--echo # MDEV-8464 : ALTER VIEW not replicated in some cases +--echo # +--echo # On node_1 +--connection node_1 +USE test; +CREATE TABLE t1(i INT) ENGINE=INNODB; +CREATE DEFINER=CURRENT_USER VIEW v1 AS SELECT * FROM t1; +CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t1; +CREATE ALGORITHM=TEMPTABLE VIEW v3 AS SELECT * FROM t1; +CREATE ALGORITHM=UNDEFINED DEFINER=CURRENT_USER VIEW v4 AS SELECT * FROM t1; + +--echo # On node_2 +--connection node_2 +USE test; +SHOW CREATE VIEW v1; +SHOW CREATE VIEW v2; +SHOW CREATE VIEW v3; +SHOW CREATE VIEW v4; + +--echo # On node_1 +--connection node_1 +ALTER ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1; +ALTER ALGORITHM=UNDEFINED VIEW v2 AS SELECT * FROM t1; +ALTER DEFINER=CURRENT_USER VIEW v3 AS SELECT * FROM t1; +ALTER ALGORITHM=TEMPTABLE DEFINER=CURRENT_USER VIEW v4 AS SELECT * FROM t1; + +--echo # On node_2 +--connection node_2 +SHOW CREATE VIEW v1; +SHOW CREATE VIEW v2; +SHOW CREATE VIEW v3; +SHOW CREATE VIEW v4; + +--echo # Cleanup +DROP VIEW v1, v2, v3, v4; +DROP TABLE t1; + +--echo # End of tests + diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 1ff842d9723..e7a82927a40 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -119,9 +119,6 @@ static void get_cs_converted_string_value(THD *thd, bool use_hex); #endif -static void -append_algorithm(TABLE_LIST *table, String *buff); - static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table); /*************************************************************************** @@ -1972,32 +1969,30 @@ static void store_key_options(THD *thd, String *packet, TABLE *table, } } - -void -view_store_options(THD *thd, TABLE_LIST *table, String *buff) -{ - append_algorithm(table, buff); - append_definer(thd, buff, &table->definer.user, &table->definer.host); - if (table->view_suid) - buff->append(STRING_WITH_LEN("SQL SECURITY DEFINER ")); - else - buff->append(STRING_WITH_LEN("SQL SECURITY INVOKER ")); -} - - /* - Append DEFINER clause to the given buffer. + Append ALGORITHM clause to the given buffer. SYNOPSIS - append_definer() - thd [in] thread handle - buffer [inout] buffer to hold DEFINER clause - definer_user [in] user name part of definer - definer_host [in] host name part of definer + append_algorithm() + table [in] table list + buff [inout] buffer to hold the ALGORITHM clause + check_inherit [in] if true, do nothing if algorithm is INHERIT */ -static void append_algorithm(TABLE_LIST *table, String *buff) +static void append_algorithm(TABLE_LIST *table, String *buff, + bool check_inherit) { + int16 algorithm= (int16) table->algorithm; + + DBUG_ENTER("append_algorithm"); + + /* + Handle a special case when ALGORITHM is not specified, in which case we + simply return. + */ + if (check_inherit && (algorithm == VIEW_ALGORITHM_INHERIT)) + DBUG_VOID_RETURN; + buff->append(STRING_WITH_LEN("ALGORITHM=")); switch ((int16)table->algorithm) { case VIEW_ALGORITHM_UNDEFINED: @@ -2012,6 +2007,8 @@ static void append_algorithm(TABLE_LIST *table, String *buff) default: DBUG_ASSERT(0); // never should happen } + + DBUG_VOID_RETURN; } /* @@ -2035,6 +2032,23 @@ void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user, buffer->append(' '); } +void +view_store_options4(THD *thd, TABLE_LIST *table, String *buff, + bool check_inherit) +{ + append_algorithm(table, buff, check_inherit); + append_definer(thd, buff, &table->definer.user, &table->definer.host); + if (table->view_suid) + buff->append(STRING_WITH_LEN("SQL SECURITY DEFINER ")); + else + buff->append(STRING_WITH_LEN("SQL SECURITY INVOKER ")); +} + +void +view_store_options(THD *thd, TABLE_LIST *table, String *buff) +{ + view_store_options4(thd, table, buff, false); +} int view_store_create_info(THD *thd, TABLE_LIST *table, String *buff) diff --git a/sql/sql_show.h b/sql/sql_show.h index 6e87f6097f0..04997fe8965 100644 --- a/sql/sql_show.h +++ b/sql/sql_show.h @@ -115,6 +115,8 @@ void free_status_vars(); void reset_status_vars(); bool show_create_trigger(THD *thd, const sp_name *trg_name); void view_store_options(THD *thd, TABLE_LIST *table, String *buff); +void view_store_options4(THD *thd, TABLE_LIST *table, String *buff, + bool check_inherit); void init_fill_schema_files_row(TABLE* table); bool schema_table_store_record(THD *thd, TABLE *table); diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index ef804fb7c5f..340ff3233e7 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1193,7 +1193,7 @@ create_view_query(THD *thd, uchar** buf, size_t* buf_len) views->view_suid = lex->create_view_suid; views->with_check = lex->create_view_check; - view_store_options(thd, views, &buff); + view_store_options4(thd, views, &buff, true); buff.append(STRING_WITH_LEN("VIEW ")); /* Test if user supplied a db (ie: we did not use thd->db) */ if (views->db && views->db[0] &&