Commit 7f50fc02 authored by Tatiana A. Nurnberg's avatar Tatiana A. Nurnberg

Bug#34861: mysqldump with --tab gives weird output for triggers.

mysqldump --tab still dumped triggers to stdout rather than to
individual tables.

We now append triggers to the .sql file for the corresponding
table.

--events and --routines correspond to a database rather than a
table and will still go to stdout with --tab unless redirected
with --result-file (-r).

client/mysqldump.c:
  Extend open_sql_file_for_table() so we can open-append.
  Change dump_triggers_for_table() so it will append its
  output to the table's .sql-file when --tab is used.
mysql-test/r/mysqldump.result:
  Show that when using --tab, triggers now end up in the .sql
  file with the corresponding table (after that table), while
  --routines and --events go to stdout or --result-file.
mysql-test/t/mysqldump.test:
  Show that when using --tab, triggers now end up in the .sql
  file with the corresponding table (after that table), while
  --routines and --events go to stdout or --result-file.
parent d7d3c56a
......@@ -1397,18 +1397,19 @@ static char *cover_definer_clause_in_sp(const char *def_str,
SYNOPSIS
open_sql_file_for_table
name name of the table or view
flags flags (as per "man 2 open")
RETURN VALUES
0 Failed to open file
> 0 Handle of the open file
*/
static FILE* open_sql_file_for_table(const char* table)
static FILE* open_sql_file_for_table(const char* table, int flags)
{
FILE* res;
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
convert_dirname(tmp_path,path,NullS);
res= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
O_WRONLY, MYF(MY_WME));
flags, MYF(MY_WME));
return res;
}
......@@ -2290,7 +2291,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
if (path)
{
if (!(sql_file= open_sql_file_for_table(table)))
if (!(sql_file= open_sql_file_for_table(table, O_WRONLY)))
DBUG_RETURN(0);
write_header(sql_file, db);
......@@ -2501,7 +2502,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
{
if (path)
{
if (!(sql_file= open_sql_file_for_table(table)))
if (!(sql_file= open_sql_file_for_table(table, O_WRONLY)))
DBUG_RETURN(0);
write_header(sql_file, db);
}
......@@ -2725,12 +2726,10 @@ static uint get_table_structure(char *table, char *db, char *table_type,
DBUG_RETURN((uint) num_fields);
} /* get_table_structure */
static void dump_trigger_old(MYSQL_RES *show_triggers_rs,
static void dump_trigger_old(FILE *sql_file, MYSQL_RES *show_triggers_rs,
MYSQL_ROW *show_trigger_row,
const char *table_name)
{
FILE *sql_file= md_result_file;
char quoted_table_name_buf[NAME_LEN * 2 + 3];
char *quoted_table_name= quote_name(table_name, quoted_table_name_buf, 1);
......@@ -2796,11 +2795,10 @@ static void dump_trigger_old(MYSQL_RES *show_triggers_rs,
DBUG_VOID_RETURN;
}
static int dump_trigger(MYSQL_RES *show_create_trigger_rs,
static int dump_trigger(FILE *sql_file, MYSQL_RES *show_create_trigger_rs,
const char *db_name,
const char *db_cl_name)
{
FILE *sql_file= md_result_file;
MYSQL_ROW row;
int db_cl_altered= FALSE;
......@@ -2864,22 +2862,28 @@ static int dump_triggers_for_table(char *table_name, char *db_name)
uint old_opt_compatible_mode= opt_compatible_mode;
MYSQL_RES *show_triggers_rs;
MYSQL_ROW row;
FILE *sql_file= md_result_file;
char db_cl_name[MY_CS_NAME_SIZE];
int ret= TRUE;
DBUG_ENTER("dump_triggers_for_table");
DBUG_PRINT("enter", ("db: %s, table_name: %s", db_name, table_name));
if (path && !(sql_file= open_sql_file_for_table(table_name,
O_WRONLY | O_APPEND)))
DBUG_RETURN(1);
/* Do not use ANSI_QUOTES on triggers in dump */
opt_compatible_mode&= ~MASK_ANSI_QUOTES;
/* Get database collation. */
if (switch_character_set_results(mysql, "binary"))
DBUG_RETURN(TRUE);
goto done;
if (fetch_db_collation(db_name, db_cl_name, sizeof (db_cl_name)))
DBUG_RETURN(TRUE);
goto done;
/* Get list of triggers. */
......@@ -2888,7 +2892,7 @@ static int dump_triggers_for_table(char *table_name, char *db_name)
quote_for_like(table_name, name_buff));
if (mysql_query_with_error_report(mysql, &show_triggers_rs, query_buff))
DBUG_RETURN(TRUE);
goto done;
/* Dump triggers. */
......@@ -2909,17 +2913,15 @@ static int dump_triggers_for_table(char *table_name, char *db_name)
provide all the necessary information to restore trigger properly.
*/
dump_trigger_old(show_triggers_rs, &row, table_name);
dump_trigger_old(sql_file, show_triggers_rs, &row, table_name);
}
else
{
MYSQL_RES *show_create_trigger_rs= mysql_store_result(mysql);
if (!show_create_trigger_rs ||
dump_trigger(show_create_trigger_rs, db_name, db_cl_name))
{
DBUG_RETURN(TRUE);
}
dump_trigger(sql_file, show_create_trigger_rs, db_name, db_cl_name))
goto done;
mysql_free_result(show_create_trigger_rs);
}
......@@ -2929,7 +2931,7 @@ static int dump_triggers_for_table(char *table_name, char *db_name)
mysql_free_result(show_triggers_rs);
if (switch_character_set_results(mysql, default_charset))
DBUG_RETURN(TRUE);
goto done;
/*
make sure to set back opt_compatible mode to
......@@ -2937,7 +2939,13 @@ static int dump_triggers_for_table(char *table_name, char *db_name)
*/
opt_compatible_mode=old_opt_compatible_mode;
DBUG_RETURN(FALSE);
ret= FALSE;
done:
if (path)
my_fclose(sql_file, MYF(0));
DBUG_RETURN(ret);
}
static void add_load_option(DYNAMIC_STRING *str, const char *option,
......@@ -4782,7 +4790,7 @@ static my_bool get_view_structure(char *table, char* db)
/* If requested, open separate .sql file for this view */
if (path)
{
if (!(sql_file= open_sql_file_for_table(table)))
if (!(sql_file= open_sql_file_for_table(table, O_WRONLY)))
DBUG_RETURN(1);
write_header(sql_file, db);
......
......@@ -4226,6 +4226,57 @@ DROP DATABASE mysqldump_test_db;
# -- End of test case for Bug#32538.
SET @@GLOBAL.CONCURRENT_INSERT = @OLD_CONCURRENT_INSERT;
Bug #34861 - mysqldump with --tab gives weird output for triggers.
CREATE TABLE t1 (f1 INT);
CREATE TRIGGER tr1 BEFORE UPDATE ON t1 FOR EACH ROW SET @f1 = 1;
CREATE PROCEDURE pr1 () SELECT "Meow";
CREATE EVENT ev1 ON SCHEDULE AT '2030-01-01 00:00:00' DO SELECT "Meow";
SHOW TRIGGERS;
Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
tr1 UPDATE t1 SET @f1 = 1 BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
SHOW EVENTS;
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
test ev1 root@localhost SYSTEM ONE TIME 2030-01-01 00:00:00 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
SELECT name,body FROM mysql.proc WHERE NAME = 'pr1';
name body
pr1 SELECT "Meow"
dump table; if anything goes to stdout, it ends up here: ---------------
drop everything
DROP EVENT ev1;
DROP TRIGGER tr1;
DROP TABLE t1;
DROP PROCEDURE pr1;
reload table; this should restore table and trigger
SHOW TRIGGERS;
Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
tr1 UPDATE t1 SET @f1 = 1 BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
SHOW EVENTS;
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
SELECT name,body FROM mysql.proc WHERE NAME = 'pr1';
name body
reload db; this should restore routines and events
SHOW TRIGGERS;
Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
tr1 UPDATE t1 SET @f1 = 1 BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
SHOW EVENTS;
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
test ev1 root@localhost SYSTEM ONE TIME 2030-01-01 00:00:00 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
SELECT name,body FROM mysql.proc WHERE NAME = 'pr1';
name body
pr1 SELECT "Meow"
cleanup
DROP EVENT IF EXISTS ev1;
DROP PROCEDURE IF EXISTS pr1;
DROP TRIGGER IF EXISTS tr1;
DROP TABLE IF EXISTS t1;
#
# End of 5.1 tests
#
......@@ -1953,6 +1953,59 @@ DROP DATABASE mysqldump_test_db;
SET @@GLOBAL.CONCURRENT_INSERT = @OLD_CONCURRENT_INSERT;
###########################################################################
--echo
--echo Bug #34861 - mysqldump with --tab gives weird output for triggers.
--echo
CREATE TABLE t1 (f1 INT);
CREATE TRIGGER tr1 BEFORE UPDATE ON t1 FOR EACH ROW SET @f1 = 1;
CREATE PROCEDURE pr1 () SELECT "Meow";
CREATE EVENT ev1 ON SCHEDULE AT '2030-01-01 00:00:00' DO SELECT "Meow";
--echo
SHOW TRIGGERS;
SHOW EVENTS;
SELECT name,body FROM mysql.proc WHERE NAME = 'pr1';
--echo
--echo dump table; if anything goes to stdout, it ends up here: ---------------
--exec $MYSQL_DUMP --compact --routines --triggers --events --result-file=$MYSQLTEST_VARDIR/tmp/test_34861.sql --tab=$MYSQLTEST_VARDIR/tmp/ test
--echo
--echo drop everything
DROP EVENT ev1;
DROP TRIGGER tr1;
DROP TABLE t1;
DROP PROCEDURE pr1;
--echo
--echo reload table; this should restore table and trigger
--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/t1.sql
SHOW TRIGGERS;
SHOW EVENTS;
SELECT name,body FROM mysql.proc WHERE NAME = 'pr1';
--echo
--echo reload db; this should restore routines and events
--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/test_34861.sql
SHOW TRIGGERS;
SHOW EVENTS;
SELECT name,body FROM mysql.proc WHERE NAME = 'pr1';
--echo
--echo cleanup
--remove_file $MYSQLTEST_VARDIR/tmp/t1.txt
--remove_file $MYSQLTEST_VARDIR/tmp/t1.sql
--remove_file $MYSQLTEST_VARDIR/tmp/test_34861.sql
--disable_warnings
DROP EVENT IF EXISTS ev1;
DROP PROCEDURE IF EXISTS pr1;
DROP TRIGGER IF EXISTS tr1;
DROP TABLE IF EXISTS t1;
--enable_warnings
###########################################################################
--echo #
......
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