Commit b592c8d2 authored by unknown's avatar unknown

Bug10213 mysqldump crashes when dumping VIEWs

 - Added testcase for this bug
 - Check if compact view format can be used
 - Clean up mysqld_show_create


mysql-test/r/mysqldump.result:
  Updated test result
mysql-test/t/mysqldump.test:
  Added testcase
sql/item.cc:
  Check if compact format can be used
sql/sql_select.cc:
  Check if compact format can be used
sql/sql_show.cc:
  Cleanup of mysqld_show_create
   -remove extra invocation of view_store_create_info
   -Remove unused vars
   -Remove unused codes
  Check if compact show view format can be used 
    - if user has db of this view as current db
    - if this view only references table inside it's own db
sql/table.h:
  Add variable for compact_view_format indicator
parent 4c4d5e41
DROP TABLE IF EXISTS t1, `"t"1`, t1aa, t2, t2aa; DROP TABLE IF EXISTS t1, `"t"1`, t1aa, t2, t2aa;
drop database if exists mysqldump_test_db; drop database if exists mysqldump_test_db;
drop view if exists v1; drop database if exists db1;
drop view if exists v1, v2;
CREATE TABLE t1(a int); CREATE TABLE t1(a int);
INSERT INTO t1 VALUES (1), (2); INSERT INTO t1 VALUES (1), (2);
<?xml version="1.0"?> <?xml version="1.0"?>
...@@ -1422,3 +1423,51 @@ UNLOCK TABLES; ...@@ -1422,3 +1423,51 @@ UNLOCK TABLES;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
DROP TABLE t1; 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;
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
--disable_warnings --disable_warnings
DROP TABLE IF EXISTS t1, `"t"1`, t1aa, t2, t2aa; DROP TABLE IF EXISTS t1, `"t"1`, t1aa, t2, t2aa;
drop database if exists mysqldump_test_db; drop database if exists mysqldump_test_db;
drop view if exists v1; drop database if exists db1;
drop database if exists db2;
drop view if exists v1, v2;
--enable_warnings --enable_warnings
# XML output # XML output
...@@ -563,3 +565,63 @@ CREATE TABLE t1 (a int); ...@@ -563,3 +565,63 @@ CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (1),(2),(3); INSERT INTO t1 VALUES (1),(2),(3);
--exec $MYSQL_DUMP --add-drop-database --skip-comments --databases test --exec $MYSQL_DUMP --add-drop-database --skip-comments --databases test
DROP TABLE t1; 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;
...@@ -1136,9 +1136,13 @@ void Item_ident::print(String *str) ...@@ -1136,9 +1136,13 @@ void Item_ident::print(String *str)
return; return;
} }
if (db_name && db_name[0] && !alias_name_used) if (db_name && db_name[0] && !alias_name_used)
{
if (!(cached_table && cached_table->belong_to_view &&
cached_table->belong_to_view->compact_view_format))
{ {
append_identifier(thd, str, d_name, strlen(d_name)); append_identifier(thd, str, d_name, strlen(d_name));
str->append('.'); str->append('.');
}
append_identifier(thd, str, t_name, strlen(t_name)); append_identifier(thd, str, t_name, strlen(t_name));
str->append('.'); str->append('.');
append_identifier(thd, str, field_name, strlen(field_name)); append_identifier(thd, str, field_name, strlen(field_name));
......
...@@ -13672,23 +13672,36 @@ void st_table_list::print(THD *thd, String *str) ...@@ -13672,23 +13672,36 @@ void st_table_list::print(THD *thd, String *str)
{ {
const char *cmp_name; // Name to compare with alias const char *cmp_name; // Name to compare with alias
if (view_name.str) if (view_name.str)
{
// A view
if (!(belong_to_view &&
belong_to_view->compact_view_format))
{ {
append_identifier(thd, str, view_db.str, view_db.length); append_identifier(thd, str, view_db.str, view_db.length);
str->append('.'); str->append('.');
}
append_identifier(thd, str, view_name.str, view_name.length); append_identifier(thd, str, view_name.str, view_name.length);
cmp_name= view_name.str; cmp_name= view_name.str;
} }
else if (derived) else if (derived)
{ {
// A derived table
str->append('('); str->append('(');
derived->print(str); derived->print(str);
str->append(')'); str->append(')');
cmp_name= ""; // Force printing of alias cmp_name= ""; // Force printing of alias
} }
else else
{
// A normal table
if (!(belong_to_view &&
belong_to_view->compact_view_format))
{ {
append_identifier(thd, str, db, db_length); append_identifier(thd, str, db, db_length);
str->append('.'); str->append('.');
}
if (schema_table) if (schema_table)
{ {
append_identifier(thd, str, schema_table_name, append_identifier(thd, str, schema_table_name,
......
...@@ -339,7 +339,6 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, ...@@ -339,7 +339,6 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
bool bool
mysqld_show_create(THD *thd, TABLE_LIST *table_list) mysqld_show_create(THD *thd, TABLE_LIST *table_list)
{ {
TABLE *table;
Protocol *protocol= thd->protocol; Protocol *protocol= thd->protocol;
char buff[2048]; char buff[2048];
String buffer(buff, sizeof(buff), system_charset_info); String buffer(buff, sizeof(buff), system_charset_info);
...@@ -349,9 +348,8 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) ...@@ -349,9 +348,8 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
/* Only one table for now, but VIEW can involve several tables */ /* Only one table for now, but VIEW can involve several tables */
if (open_normal_and_derived_tables(thd, table_list)) if (open_normal_and_derived_tables(thd, table_list))
{
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
}
/* TODO: add environment variables show when it become possible */ /* TODO: add environment variables show when it become possible */
if (thd->lex->only_view && !table_list->view) if (thd->lex->only_view && !table_list->view)
{ {
...@@ -360,8 +358,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) ...@@ -360,8 +358,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
table= table_list->table; buffer.length(0);
if ((table_list->view ? if ((table_list->view ?
view_store_create_info(thd, table_list, &buffer) : view_store_create_info(thd, table_list, &buffer) :
store_create_info(thd, table_list, &buffer))) store_create_info(thd, table_list, &buffer)))
...@@ -386,22 +383,15 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) ...@@ -386,22 +383,15 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
protocol->prepare_for_resend(); protocol->prepare_for_resend();
buffer.length(0);
if (table_list->view) if (table_list->view)
{
protocol->store(table_list->view_name.str, system_charset_info); protocol->store(table_list->view_name.str, system_charset_info);
if (view_store_create_info(thd, table_list, &buffer))
DBUG_RETURN(TRUE);
}
else else
{ {
if (table_list->schema_table) if (table_list->schema_table)
protocol->store(table_list->schema_table->table_name, protocol->store(table_list->schema_table->table_name,
system_charset_info); system_charset_info);
else else
protocol->store(table->alias, system_charset_info); protocol->store(table_list->table->alias, system_charset_info);
if (store_create_info(thd, table_list, &buffer))
DBUG_RETURN(TRUE);
} }
protocol->store(buffer.ptr(), buffer.length(), buffer.charset()); protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
...@@ -1037,6 +1027,29 @@ view_store_create_info(THD *thd, TABLE_LIST *table, String *buff) ...@@ -1037,6 +1027,29 @@ view_store_create_info(THD *thd, TABLE_LIST *table, String *buff)
MODE_DB2 | MODE_DB2 |
MODE_MAXDB | MODE_MAXDB |
MODE_ANSI)) != 0; 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); buff->append("CREATE ", 7);
if (!foreign_db_mode) if (!foreign_db_mode)
{ {
...@@ -1057,11 +1070,14 @@ view_store_create_info(THD *thd, TABLE_LIST *table, String *buff) ...@@ -1057,11 +1070,14 @@ view_store_create_info(THD *thd, TABLE_LIST *table, String *buff)
} }
} }
buff->append("VIEW ", 5); buff->append("VIEW ", 5);
if (!table->compact_view_format)
{
append_identifier(thd, buff, table->view_db.str, table->view_db.length); append_identifier(thd, buff, table->view_db.str, table->view_db.length);
buff->append('.'); buff->append('.');
}
append_identifier(thd, buff, table->view_name.str, table->view_name.length); append_identifier(thd, buff, table->view_name.str, table->view_name.length);
buff->append(" AS ", 4); buff->append(" AS ", 4);
buff->append(table->query.str, table->query.length); table->view->unit.print(buff);
if (table->with_check != VIEW_CHECK_NONE) if (table->with_check != VIEW_CHECK_NONE)
{ {
if (table->with_check == VIEW_CHECK_LOCAL) if (table->with_check == VIEW_CHECK_LOCAL)
......
...@@ -437,6 +437,7 @@ typedef struct st_table_list ...@@ -437,6 +437,7 @@ typedef struct st_table_list
/* TRUE if this merged view contain auto_increment field */ /* TRUE if this merged view contain auto_increment field */
bool contain_auto_increment; bool contain_auto_increment;
bool multitable_view; /* TRUE iff this is multitable view */ bool multitable_view; /* TRUE iff this is multitable view */
bool compact_view_format; /* Use compact format for SHOW CREATE VIEW */
/* FRMTYPE_ERROR if any type is acceptable */ /* FRMTYPE_ERROR if any type is acceptable */
enum frm_type_enum required_type; enum frm_type_enum required_type;
char timestamp_buffer[20]; /* buffer for timestamp (19+1) */ char timestamp_buffer[20]; /* buffer for timestamp (19+1) */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment