Commit e6f0b97b authored by Georgi Kodinov's avatar Georgi Kodinov

Bug #11753490: 44939: sql dumps containing broad views fail when

executing

The problem is that mysql lacks information about the objects a view
depends on so it can't dump views and tables in the proper order.
Thus it needs to create "stand-in" myisam tables for each view while 
dumping the tables that it later drops and replaces with the actual view
view definition.
But since views can have much more columns than an actual table creating
these stand-in tables may be problematic.

There's no way to portably find out how many columns an mysiam table
can have. It's a complicated formula depending on internal server constants.
Thus we can't have a reliable error check without repeating the logic and 
the formula inside mysqldump.

1. Changed the type of the columns of the stand-in tables mysqldump
makes to satisfy view dependencies from the original type to smallint 
to save on row space.

2. Added a warning on the mysqldump's standard error for a possible 
problems replaying the dump file if the columns of a view exceed 1000.

3. Added a test case.
parent 623f930a
...@@ -2558,6 +2558,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, ...@@ -2558,6 +2558,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
if (strcmp(field->name, "View") == 0) if (strcmp(field->name, "View") == 0)
{ {
char *scv_buff= NULL; char *scv_buff= NULL;
my_ulonglong n_cols;
verbose_msg("-- It's a view, create dummy table for view\n"); verbose_msg("-- It's a view, create dummy table for view\n");
...@@ -2572,8 +2573,8 @@ static uint get_table_structure(char *table, char *db, char *table_type, ...@@ -2572,8 +2573,8 @@ static uint get_table_structure(char *table, char *db, char *table_type,
the same name in order to satisfy views that depend on this view. the same name in order to satisfy views that depend on this view.
The table will be removed when the actual view is created. The table will be removed when the actual view is created.
The properties of each column, aside from the data type, are not The properties of each column, are not preserved in this temporary
preserved in this temporary table, because they are not necessary. table, because they are not necessary.
This will not be necessary once we can determine dependencies This will not be necessary once we can determine dependencies
between views and can simply dump them in the appropriate order. between views and can simply dump them in the appropriate order.
...@@ -2600,8 +2601,23 @@ static uint get_table_structure(char *table, char *db, char *table_type, ...@@ -2600,8 +2601,23 @@ static uint get_table_structure(char *table, char *db, char *table_type,
else else
my_free(scv_buff); my_free(scv_buff);
if (mysql_num_rows(result)) n_cols= mysql_num_rows(result);
if (0 != n_cols)
{ {
/*
The actual formula is based on the column names and how the .FRM
files are stored and is too volatile to be repeated here.
Thus we simply warn the user if the columns exceed a limit we
know works most of the time.
*/
if (n_cols >= 1000)
fprintf(stderr,
"-- Warning: Creating a stand-in table for view %s may"
" fail when replaying the dump file produced because "
"of the number of columns exceeding 1000. Exercise "
"caution when replaying the produced dump file.\n",
table);
if (opt_drop) if (opt_drop)
{ {
/* /*
...@@ -2628,14 +2644,19 @@ static uint get_table_structure(char *table, char *db, char *table_type, ...@@ -2628,14 +2644,19 @@ static uint get_table_structure(char *table, char *db, char *table_type,
row= mysql_fetch_row(result); row= mysql_fetch_row(result);
fprintf(sql_file, " %s %s", quote_name(row[0], name_buff, 0), /*
row[1]); The actual column type doesn't matter anyway, since the table will
be dropped at run time.
We do tinyint to avoid hitting the row size limit.
*/
fprintf(sql_file, " %s tinyint NOT NULL",
quote_name(row[0], name_buff, 0));
while((row= mysql_fetch_row(result))) while((row= mysql_fetch_row(result)))
{ {
/* col name, col type */ /* col name, col type */
fprintf(sql_file, ",\n %s %s", fprintf(sql_file, ",\n %s tinyint NOT NULL",
quote_name(row[0], name_buff, 0), row[1]); quote_name(row[0], name_buff, 0));
} }
/* /*
......
...@@ -1988,7 +1988,7 @@ DROP TABLE IF EXISTS `v2`; ...@@ -1988,7 +1988,7 @@ DROP TABLE IF EXISTS `v2`;
SET @saved_cs_client = @@character_set_client; SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8; SET character_set_client = utf8;
/*!50001 CREATE TABLE `v2` ( /*!50001 CREATE TABLE `v2` (
`a` varchar(30) `a` tinyint NOT NULL
) ENGINE=MyISAM */; ) ENGINE=MyISAM */;
SET character_set_client = @saved_cs_client; SET character_set_client = @saved_cs_client;
/*!50001 DROP TABLE IF EXISTS `v2`*/; /*!50001 DROP TABLE IF EXISTS `v2`*/;
...@@ -2082,7 +2082,7 @@ DROP TABLE IF EXISTS `v1`; ...@@ -2082,7 +2082,7 @@ DROP TABLE IF EXISTS `v1`;
SET @saved_cs_client = @@character_set_client; SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8; SET character_set_client = utf8;
/*!50001 CREATE TABLE `v1` ( /*!50001 CREATE TABLE `v1` (
`a` int(11) `a` tinyint NOT NULL
) ENGINE=MyISAM */; ) ENGINE=MyISAM */;
SET character_set_client = @saved_cs_client; SET character_set_client = @saved_cs_client;
/*!50001 DROP TABLE IF EXISTS `v1`*/; /*!50001 DROP TABLE IF EXISTS `v1`*/;
...@@ -2156,7 +2156,7 @@ DROP TABLE IF EXISTS `v2`; ...@@ -2156,7 +2156,7 @@ DROP TABLE IF EXISTS `v2`;
SET @saved_cs_client = @@character_set_client; SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8; SET character_set_client = utf8;
/*!50001 CREATE TABLE `v2` ( /*!50001 CREATE TABLE `v2` (
`a` varchar(30) `a` tinyint NOT NULL
) ENGINE=MyISAM */; ) ENGINE=MyISAM */;
SET character_set_client = @saved_cs_client; SET character_set_client = @saved_cs_client;
/*!50001 DROP TABLE IF EXISTS `v2`*/; /*!50001 DROP TABLE IF EXISTS `v2`*/;
...@@ -2270,9 +2270,9 @@ DROP TABLE IF EXISTS `v1`; ...@@ -2270,9 +2270,9 @@ DROP TABLE IF EXISTS `v1`;
SET @saved_cs_client = @@character_set_client; SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8; SET character_set_client = utf8;
/*!50001 CREATE TABLE `v1` ( /*!50001 CREATE TABLE `v1` (
`a` int(11), `a` tinyint NOT NULL,
`b` int(11), `b` tinyint NOT NULL,
`c` varchar(30) `c` tinyint NOT NULL
) ENGINE=MyISAM */; ) ENGINE=MyISAM */;
SET character_set_client = @saved_cs_client; SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS `v2`; DROP TABLE IF EXISTS `v2`;
...@@ -2280,7 +2280,7 @@ DROP TABLE IF EXISTS `v2`; ...@@ -2280,7 +2280,7 @@ DROP TABLE IF EXISTS `v2`;
SET @saved_cs_client = @@character_set_client; SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8; SET character_set_client = utf8;
/*!50001 CREATE TABLE `v2` ( /*!50001 CREATE TABLE `v2` (
`a` int(11) `a` tinyint NOT NULL
) ENGINE=MyISAM */; ) ENGINE=MyISAM */;
SET character_set_client = @saved_cs_client; SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS `v3`; DROP TABLE IF EXISTS `v3`;
...@@ -2288,9 +2288,9 @@ DROP TABLE IF EXISTS `v3`; ...@@ -2288,9 +2288,9 @@ DROP TABLE IF EXISTS `v3`;
SET @saved_cs_client = @@character_set_client; SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8; SET character_set_client = utf8;
/*!50001 CREATE TABLE `v3` ( /*!50001 CREATE TABLE `v3` (
`a` int(11), `a` tinyint NOT NULL,
`b` int(11), `b` tinyint NOT NULL,
`c` varchar(30) `c` tinyint NOT NULL
) ENGINE=MyISAM */; ) ENGINE=MyISAM */;
SET character_set_client = @saved_cs_client; SET character_set_client = @saved_cs_client;
/*!50001 DROP TABLE IF EXISTS `v1`*/; /*!50001 DROP TABLE IF EXISTS `v1`*/;
...@@ -3027,9 +3027,9 @@ DROP TABLE IF EXISTS `v0`; ...@@ -3027,9 +3027,9 @@ DROP TABLE IF EXISTS `v0`;
SET @saved_cs_client = @@character_set_client; SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8; SET character_set_client = utf8;
/*!50001 CREATE TABLE `v0` ( /*!50001 CREATE TABLE `v0` (
`a` int(11), `a` tinyint NOT NULL,
`b` varchar(32), `b` tinyint NOT NULL,
`c` varchar(32) `c` tinyint NOT NULL
) ENGINE=MyISAM */; ) ENGINE=MyISAM */;
SET character_set_client = @saved_cs_client; SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS `v1`; DROP TABLE IF EXISTS `v1`;
...@@ -3037,9 +3037,9 @@ DROP TABLE IF EXISTS `v1`; ...@@ -3037,9 +3037,9 @@ DROP TABLE IF EXISTS `v1`;
SET @saved_cs_client = @@character_set_client; SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8; SET character_set_client = utf8;
/*!50001 CREATE TABLE `v1` ( /*!50001 CREATE TABLE `v1` (
`a` int(11), `a` tinyint NOT NULL,
`b` varchar(32), `b` tinyint NOT NULL,
`c` varchar(32) `c` tinyint NOT NULL
) ENGINE=MyISAM */; ) ENGINE=MyISAM */;
SET character_set_client = @saved_cs_client; SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS `v2`; DROP TABLE IF EXISTS `v2`;
...@@ -3047,9 +3047,9 @@ DROP TABLE IF EXISTS `v2`; ...@@ -3047,9 +3047,9 @@ DROP TABLE IF EXISTS `v2`;
SET @saved_cs_client = @@character_set_client; SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8; SET character_set_client = utf8;
/*!50001 CREATE TABLE `v2` ( /*!50001 CREATE TABLE `v2` (
`a` int(11), `a` tinyint NOT NULL,
`b` varchar(32), `b` tinyint NOT NULL,
`c` varchar(32) `c` tinyint NOT NULL
) ENGINE=MyISAM */; ) ENGINE=MyISAM */;
SET character_set_client = @saved_cs_client; SET character_set_client = @saved_cs_client;
...@@ -3429,7 +3429,7 @@ DROP TABLE IF EXISTS `v1`; ...@@ -3429,7 +3429,7 @@ DROP TABLE IF EXISTS `v1`;
SET @saved_cs_client = @@character_set_client; SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8; SET character_set_client = utf8;
/*!50001 CREATE TABLE `v1` ( /*!50001 CREATE TABLE `v1` (
`id` int(11) `id` tinyint NOT NULL
) ENGINE=MyISAM */; ) ENGINE=MyISAM */;
SET character_set_client = @saved_cs_client; SET character_set_client = @saved_cs_client;
...@@ -3489,7 +3489,7 @@ USE `mysqldump_views`; ...@@ -3489,7 +3489,7 @@ USE `mysqldump_views`;
SET @saved_cs_client = @@character_set_client; SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8; SET character_set_client = utf8;
/*!50001 CREATE TABLE `nasishnasifu` ( /*!50001 CREATE TABLE `nasishnasifu` (
`id` bigint(20) unsigned `id` tinyint NOT NULL
) ENGINE=MyISAM */; ) ENGINE=MyISAM */;
SET character_set_client = @saved_cs_client; SET character_set_client = @saved_cs_client;
...@@ -3882,7 +3882,7 @@ DROP TABLE IF EXISTS `v2`; ...@@ -3882,7 +3882,7 @@ DROP TABLE IF EXISTS `v2`;
SET @saved_cs_client = @@character_set_client; SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8; SET character_set_client = utf8;
/*!50001 CREATE TABLE `v2` ( /*!50001 CREATE TABLE `v2` (
`c` int(11) `c` tinyint NOT NULL
) ENGINE=MyISAM */; ) ENGINE=MyISAM */;
SET character_set_client = @saved_cs_client; SET character_set_client = @saved_cs_client;
/*!50001 DROP TABLE IF EXISTS `v2`*/; /*!50001 DROP TABLE IF EXISTS `v2`*/;
...@@ -4299,7 +4299,7 @@ DROP TABLE IF EXISTS `v1`; ...@@ -4299,7 +4299,7 @@ DROP TABLE IF EXISTS `v1`;
SET @saved_cs_client = @@character_set_client; SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8; SET character_set_client = utf8;
/*!50001 CREATE TABLE `v1` ( /*!50001 CREATE TABLE `v1` (
`id` int(11) `id` tinyint NOT NULL
) ENGINE=MyISAM */; ) ENGINE=MyISAM */;
SET character_set_client = @saved_cs_client; SET character_set_client = @saved_cs_client;
......
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