diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index f795bda5553..3fe537a986f 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -1,5 +1,6 @@ DROP TABLE IF EXISTS t1, `"t"1`, t1aa, t2, t2aa; drop database if exists mysqldump_test_db; +drop database if exists db1; drop view if exists v1, v2, v3; CREATE TABLE t1(a int); INSERT INTO t1 VALUES (1), (2); @@ -1355,6 +1356,54 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; DROP TABLE t1; +create database db1; +use db1; +CREATE TABLE t2 ( +a varchar(30) default NULL, +KEY a (a(5)) +); +INSERT INTO t2 VALUES ('alfred'); +INSERT INTO t2 VALUES ('angie'); +INSERT INTO t2 VALUES ('bingo'); +INSERT INTO t2 VALUES ('waffle'); +INSERT INTO t2 VALUES ('lemon'); +create view v2 as select * from t2 where a like 'a%' with check option; + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS `t2`; +CREATE TABLE `t2` ( + `a` varchar(30) default NULL, + KEY `a` (`a`(5)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + + +/*!40000 ALTER TABLE `t2` DISABLE KEYS */; +LOCK TABLES `t2` WRITE; +INSERT INTO `t2` VALUES ('alfred'),('angie'),('bingo'),('waffle'),('lemon'); +UNLOCK TABLES; +/*!40000 ALTER TABLE `t2` ENABLE KEYS */; +DROP TABLE IF EXISTS `v2`; +DROP VIEW IF EXISTS `v2`; +CREATE ALGORITHM=UNDEFINED VIEW `db1`.`v2` AS select `db1`.`t2`.`a` AS `a` from `db1`.`t2` where (`db1`.`t2`.`a` like _latin1'a%') WITH CASCADED CHECK OPTION; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +drop table t2; +drop view v2; +drop database db1; CREATE DATABASE mysqldump_test_db; USE mysqldump_test_db; CREATE TABLE t1 ( a INT ); diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index c34840b0725..cea5164a646 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -4,6 +4,8 @@ --disable_warnings DROP TABLE IF EXISTS t1, `"t"1`, t1aa, t2, t2aa; drop database if exists mysqldump_test_db; +drop database if exists db1; +drop database if exists db2; drop view if exists v1, v2, v3; --enable_warnings @@ -545,6 +547,66 @@ CREATE TABLE t1 (a int); INSERT INTO t1 VALUES (1),(2),(3); --exec $MYSQL_DUMP --add-drop-database --skip-comments --databases test DROP TABLE t1; + + +# +# Bug #10213 mysqldump crashes when dumping VIEWs(on MacOS X) +# + +create database db1; +use db1; + +CREATE TABLE t2 ( + a varchar(30) default NULL, + KEY a (a(5)) +); + +INSERT INTO t2 VALUES ('alfred'); +INSERT INTO t2 VALUES ('angie'); +INSERT INTO t2 VALUES ('bingo'); +INSERT INTO t2 VALUES ('waffle'); +INSERT INTO t2 VALUES ('lemon'); +create view v2 as select * from t2 where a like 'a%' with check option; +--exec $MYSQL_DUMP --skip-comments db1 +drop table t2; +drop view v2; +drop database db1; + +# +# Bug 10713 mysqldump includes database in create view and referenced tables +# + +# create table and views in testdb2 +create database db2; +use db2; +create table t1 (a int); +create table t2 (a int, b varchar(10), primary key(a)); +insert into t2 values (1, "on"), (2, "off"), (10, "pol"), (12, "meg"); +insert into t1 values (289), (298), (234), (456), (789); +create view v1 as select * from t2; +create view v2 as select * from t1; + +# dump tables and view from db2 +--exec $MYSQL_DUMP db2 +--exec $MYSQL_DUMP db2 > var/tmp/bug10713.sql + +# drop the db, tables and views +drop table t1, t2; +drop view v1, v2; +drop database db2; + +# create db1 and reload dump +create database db1; +use db1; +--exec $MYSQL db1 < var/tmp/bug10713.sql + +# check that all tables and views could be created +show tables; +#select * from t2 order by a; + +#drop table t1, t2; +#drop view t1, t2; +drop database db1; # # Bug #9558 mysqldump --no-data db t1 t2 format still dumps data # diff --git a/sql/item.cc b/sql/item.cc index e7da646ae73..b2fce8c20ef 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1528,11 +1528,15 @@ void Item_ident::print(String *str) } if (db_name && db_name[0] && !alias_name_used) { - append_identifier(thd, str, d_name, (uint) strlen(d_name)); + if (!(cached_table && cached_table->belong_to_view && + cached_table->belong_to_view->compact_view_format)) + { + append_identifier(thd, str, d_name, (uint)strlen(d_name)); + str->append('.'); + } + append_identifier(thd, str, t_name, (uint)strlen(t_name)); str->append('.'); - append_identifier(thd, str, t_name, (uint) strlen(t_name)); - str->append('.'); - append_identifier(thd, str, field_name, (uint) strlen(field_name)); + append_identifier(thd, str, field_name, (uint)strlen(field_name)); } else { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 04969b37012..74c9b793886 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13875,13 +13875,20 @@ void st_table_list::print(THD *thd, String *str) const char *cmp_name; // Name to compare with alias if (view_name.str) { - append_identifier(thd, str, view_db.str, view_db.length); - str->append('.'); + // A view + + if (!(belong_to_view && + belong_to_view->compact_view_format)) + { + append_identifier(thd, str, view_db.str, view_db.length); + str->append('.'); + } append_identifier(thd, str, view_name.str, view_name.length); cmp_name= view_name.str; } else if (derived) { + // A derived table str->append('('); derived->print(str); str->append(')'); @@ -13889,8 +13896,14 @@ void st_table_list::print(THD *thd, String *str) } else { - append_identifier(thd, str, db, db_length); - str->append('.'); + // A normal table + + if (!(belong_to_view && + belong_to_view->compact_view_format)) + { + append_identifier(thd, str, db, db_length); + str->append('.'); + } if (schema_table) { append_identifier(thd, str, schema_table_name, diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 51330a6109b..2a45be27bdc 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -347,7 +347,6 @@ mysql_find_files(THD *thd,List *files, const char *db,const char *path, bool mysqld_show_create(THD *thd, TABLE_LIST *table_list) { - TABLE *table; Protocol *protocol= thd->protocol; char buff[2048]; String buffer(buff, sizeof(buff), system_charset_info); @@ -360,9 +359,8 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) /* Only one table for now, but VIEW can involve several tables */ if (open_normal_and_derived_tables(thd, table_list, 0)) - { DBUG_RETURN(TRUE); - } + /* TODO: add environment variables show when it become possible */ if (thd->lex->only_view && !table_list->view) { @@ -371,8 +369,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) DBUG_RETURN(TRUE); } - table= table_list->table; - + buffer.length(0); if ((table_list->view ? view_store_create_info(thd, table_list, &buffer) : store_create_info(thd, table_list, &buffer))) @@ -397,22 +394,15 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) DBUG_RETURN(TRUE); protocol->prepare_for_resend(); - buffer.length(0); if (table_list->view) - { protocol->store(table_list->view_name.str, system_charset_info); - if (view_store_create_info(thd, table_list, &buffer)) - DBUG_RETURN(TRUE); - } else { if (table_list->schema_table) protocol->store(table_list->schema_table->table_name, system_charset_info); else - protocol->store(table->alias, system_charset_info); - if (store_create_info(thd, table_list, &buffer)) - DBUG_RETURN(TRUE); + protocol->store(table_list->table->alias, system_charset_info); } protocol->store(buffer.ptr(), buffer.length(), buffer.charset()); @@ -1055,6 +1045,29 @@ view_store_create_info(THD *thd, TABLE_LIST *table, String *buff) MODE_DB2 | MODE_MAXDB | MODE_ANSI)) != 0; + /* + Compact output format for view can be used + - if user has db of this view as current db + - if this view only references table inside it's own db + */ + if(strcmp(thd->db, table->view_db.str)) + table->compact_view_format= FALSE; + else + { + table->compact_view_format= TRUE; + TABLE_LIST *tbl; + for (tbl= thd->lex->query_tables; + tbl; + tbl= tbl->next_global) + { + if (strcmp(table->view_db.str, tbl->view ? tbl->view_db.str :tbl->db)!= 0) + { + table->compact_view_format= FALSE; + break; + } + } + } + buff->append("CREATE ", 7); if (!foreign_db_mode) { @@ -1075,8 +1088,11 @@ view_store_create_info(THD *thd, TABLE_LIST *table, String *buff) } } buff->append("VIEW ", 5); - append_identifier(thd, buff, table->view_db.str, table->view_db.length); - buff->append('.'); + if (!table->compact_view_format) + { + append_identifier(thd, buff, table->view_db.str, table->view_db.length); + buff->append('.'); + } append_identifier(thd, buff, table->view_name.str, table->view_name.length); buff->append(" AS ", 4); diff --git a/sql/table.h b/sql/table.h index d7c14e1938a..49104c9c1ff 100644 --- a/sql/table.h +++ b/sql/table.h @@ -576,6 +576,7 @@ typedef struct st_table_list /* TRUE if this merged view contain auto_increment field */ bool contain_auto_increment; bool multitable_view; /* TRUE iff this is multitable view */ + bool compact_view_format; /* Use compact format for SHOW CREATE VIEW */ /* view where processed */ bool where_processed; /* FRMTYPE_ERROR if any type is acceptable */