Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
d8af27ef
Commit
d8af27ef
authored
Jan 10, 2012
by
Nirbhay Choubey
Browse files
Options
Browse Files
Download
Plain Diff
Merge of fix for bug#11760384 from mysql-5.1.
parents
51be2c2c
63f8c1e1
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
886 additions
and
131 deletions
+886
-131
client/mysqldump.c
client/mysqldump.c
+335
-131
mysql-test/r/mysqldump.result
mysql-test/r/mysqldump.result
+439
-0
mysql-test/t/mysqldump.test
mysql-test/t/mysqldump.test
+112
-0
No files found.
client/mysqldump.c
View file @
d8af27ef
...
@@ -77,6 +77,9 @@
...
@@ -77,6 +77,9 @@
/* Size of buffer for dump's select query */
/* Size of buffer for dump's select query */
#define QUERY_LENGTH 1536
#define QUERY_LENGTH 1536
/* Size of comment buffer. */
#define COMMENT_LENGTH 2048
/* ignore table flags */
/* ignore table flags */
#define IGNORE_NONE 0x00
/* no ignore */
#define IGNORE_NONE 0x00
/* no ignore */
#define IGNORE_DATA 0x01
/* don't dump data for this table */
#define IGNORE_DATA 0x01
/* don't dump data for this table */
...
@@ -105,7 +108,7 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0,
...
@@ -105,7 +108,7 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0,
opt_dump_triggers
=
0
,
opt_routines
=
0
,
opt_tz_utc
=
1
,
opt_dump_triggers
=
0
,
opt_routines
=
0
,
opt_tz_utc
=
1
,
opt_slave_apply
=
0
,
opt_slave_apply
=
0
,
opt_include_master_host_port
=
0
,
opt_include_master_host_port
=
0
,
opt_events
=
0
,
opt_events
=
0
,
opt_comments_used
=
0
,
opt_alltspcs
=
0
,
opt_notspcs
=
0
;
opt_alltspcs
=
0
,
opt_notspcs
=
0
;
static
my_bool
insert_pat_inited
=
0
,
debug_info_flag
=
0
,
debug_check_flag
=
0
;
static
my_bool
insert_pat_inited
=
0
,
debug_info_flag
=
0
,
debug_check_flag
=
0
;
static
ulong
opt_max_allowed_packet
,
opt_net_buffer_length
;
static
ulong
opt_max_allowed_packet
,
opt_net_buffer_length
;
...
@@ -539,6 +542,8 @@ static int dump_all_tablespaces();
...
@@ -539,6 +542,8 @@ static int dump_all_tablespaces();
static
int
dump_tablespaces_for_tables
(
char
*
db
,
char
**
table_names
,
int
tables
);
static
int
dump_tablespaces_for_tables
(
char
*
db
,
char
**
table_names
,
int
tables
);
static
int
dump_tablespaces_for_databases
(
char
**
databases
);
static
int
dump_tablespaces_for_databases
(
char
**
databases
);
static
int
dump_tablespaces
(
char
*
ts_where
);
static
int
dump_tablespaces
(
char
*
ts_where
);
static
void
print_comment
(
FILE
*
sql_file
,
my_bool
is_error
,
const
char
*
format
,
...);
/*
/*
...
@@ -633,19 +638,19 @@ static void write_header(FILE *sql_file, char *db_name)
...
@@ -633,19 +638,19 @@ static void write_header(FILE *sql_file, char *db_name)
}
}
else
if
(
!
opt_compact
)
else
if
(
!
opt_compact
)
{
{
if
(
opt_comments
)
print_comment
(
sql_file
,
0
,
{
fprintf
(
sql_file
,
"-- MySQL dump %s Distrib %s, for %s (%s)
\n
--
\n
"
,
"-- MySQL dump %s Distrib %s, for %s (%s)
\n
--
\n
"
,
DUMP_VERSION
,
MYSQL_SERVER_VERSION
,
SYSTEM_TYPE
,
MACHINE_TYPE
);
DUMP_VERSION
,
MYSQL_SERVER_VERSION
,
SYSTEM_TYPE
,
fprintf
(
sql_file
,
"-- Host: %s Database: %s
\n
"
,
MACHINE_TYPE
);
current_host
?
current_host
:
"localhost"
,
db_name
?
db_name
:
print_comment
(
sql_file
,
0
,
"-- Host: %s Database: %s
\n
"
,
""
);
current_host
?
current_host
:
"localhost"
,
fputs
(
"-- ------------------------------------------------------
\n
"
,
db_name
?
db_name
:
""
);
sql_file
);
print_comment
(
sql_file
,
0
,
fprintf
(
sql_file
,
"-- Server version
\t
%s
\n
"
,
"-- ------------------------------------------------------
\n
"
);
print_comment
(
sql_file
,
0
,
"-- Server version
\t
%s
\n
"
,
mysql_get_server_info
(
&
mysql_connection
));
mysql_get_server_info
(
&
mysql_connection
));
}
if
(
opt_set_charset
)
if
(
opt_set_charset
)
fprintf
(
sql_file
,
fprintf
(
sql_file
,
"
\n
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;"
"
\n
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;"
...
@@ -703,18 +708,16 @@ static void write_footer(FILE *sql_file)
...
@@ -703,18 +708,16 @@ static void write_footer(FILE *sql_file)
fprintf
(
sql_file
,
fprintf
(
sql_file
,
"/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
\n
"
);
"/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
\n
"
);
fputs
(
"
\n
"
,
sql_file
);
fputs
(
"
\n
"
,
sql_file
);
if
(
opt_comments
)
{
if
(
opt_dump_date
)
if
(
opt_dump_date
)
{
{
char
time_str
[
20
];
char
time_str
[
20
];
get_date
(
time_str
,
GETDATE_DATE_TIME
,
0
);
get_date
(
time_str
,
GETDATE_DATE_TIME
,
0
);
fprintf
(
sql_file
,
"-- Dump completed on %s
\n
"
,
print_comment
(
sql_file
,
0
,
"-- Dump completed on %s
\n
"
,
time_str
);
time_str
);
}
}
else
else
fprintf
(
sql_file
,
"-- Dump completed
\n
"
);
print_comment
(
sql_file
,
0
,
"-- Dump completed
\n
"
);
}
check_io
(
sql_file
);
check_io
(
sql_file
);
}
}
}
/* write_footer */
}
/* write_footer */
...
@@ -788,6 +791,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
...
@@ -788,6 +791,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
extended_insert
=
opt_drop
=
opt_lock
=
extended_insert
=
opt_drop
=
opt_lock
=
opt_disable_keys
=
opt_autocommit
=
opt_create_db
=
0
;
opt_disable_keys
=
opt_autocommit
=
opt_create_db
=
0
;
break
;
break
;
case
'i'
:
opt_comments_used
=
1
;
break
;
case
'I'
:
case
'I'
:
case
'?'
:
case
'?'
:
usage
();
usage
();
...
@@ -814,6 +820,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
...
@@ -814,6 +820,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
opt_comments
=
opt_drop
=
opt_disable_keys
=
opt_lock
=
0
;
opt_comments
=
opt_drop
=
opt_disable_keys
=
opt_lock
=
0
;
opt_set_charset
=
0
;
opt_set_charset
=
0
;
}
}
break
;
case
(
int
)
OPT_TABLES
:
case
(
int
)
OPT_TABLES
:
opt_databases
=
0
;
opt_databases
=
0
;
break
;
break
;
...
@@ -1637,20 +1644,20 @@ static char *quote_for_like(const char *name, char *buff)
...
@@ -1637,20 +1644,20 @@ static char *quote_for_like(const char *name, char *buff)
}
}
/*
/*
*
Quote and print a string.
Quote and print a string.
SYNOPSIS
@param xml_file - Output file.
print_quoted_xml()
@param str - String to print.
xml_file - output file
@param len - Its length.
str - string to print
@param is_attribute_name - A check for attribute name or value.
len - its length
DESCRIPTION
@description
Quote '<' '>' '&' '\"' chars and print a string to the xml_file.
Quote '<' '>' '&' '\"' chars and print a string to the xml_file.
*/
*/
static
void
print_quoted_xml
(
FILE
*
xml_file
,
const
char
*
str
,
ulong
len
)
static
void
print_quoted_xml
(
FILE
*
xml_file
,
const
char
*
str
,
ulong
len
,
my_bool
is_attribute_name
)
{
{
const
char
*
end
;
const
char
*
end
;
...
@@ -1669,6 +1676,14 @@ static void print_quoted_xml(FILE *xml_file, const char *str, ulong len)
...
@@ -1669,6 +1676,14 @@ static void print_quoted_xml(FILE *xml_file, const char *str, ulong len)
case
'\"'
:
case
'\"'
:
fputs
(
"""
,
xml_file
);
fputs
(
"""
,
xml_file
);
break
;
break
;
case
' '
:
/* Attribute names cannot contain spaces. */
if
(
is_attribute_name
)
{
fputs
(
"_"
,
xml_file
);
break
;
}
/* fall through */
default:
default:
fputc
(
*
str
,
xml_file
);
fputc
(
*
str
,
xml_file
);
break
;
break
;
...
@@ -1729,7 +1744,7 @@ static void print_xml_tag(FILE * xml_file, const char* sbeg,
...
@@ -1729,7 +1744,7 @@ static void print_xml_tag(FILE * xml_file, const char* sbeg,
fputs
(
attribute_name
,
xml_file
);
fputs
(
attribute_name
,
xml_file
);
fputc
(
'\"'
,
xml_file
);
fputc
(
'\"'
,
xml_file
);
print_quoted_xml
(
xml_file
,
attribute_value
,
strlen
(
attribute_value
));
print_quoted_xml
(
xml_file
,
attribute_value
,
strlen
(
attribute_value
)
,
0
);
fputc
(
'\"'
,
xml_file
);
fputc
(
'\"'
,
xml_file
);
attribute_name
=
va_arg
(
arg_list
,
char
*
);
attribute_name
=
va_arg
(
arg_list
,
char
*
);
...
@@ -1769,13 +1784,52 @@ static void print_xml_null_tag(FILE * xml_file, const char* sbeg,
...
@@ -1769,13 +1784,52 @@ static void print_xml_null_tag(FILE * xml_file, const char* sbeg,
fputs
(
"<"
,
xml_file
);
fputs
(
"<"
,
xml_file
);
fputs
(
stag_atr
,
xml_file
);
fputs
(
stag_atr
,
xml_file
);
fputs
(
"
\"
"
,
xml_file
);
fputs
(
"
\"
"
,
xml_file
);
print_quoted_xml
(
xml_file
,
sval
,
strlen
(
sval
));
print_quoted_xml
(
xml_file
,
sval
,
strlen
(
sval
)
,
0
);
fputs
(
"
\"
xsi:nil=
\"
true
\"
/>"
,
xml_file
);
fputs
(
"
\"
xsi:nil=
\"
true
\"
/>"
,
xml_file
);
fputs
(
line_end
,
xml_file
);
fputs
(
line_end
,
xml_file
);
check_io
(
xml_file
);
check_io
(
xml_file
);
}
}
/**
Print xml CDATA section.
@param xml_file - output file
@param str - string to print
@param len - length of the string
@note
This function also takes care of the presence of '[[>'
string in the str. If found, the CDATA section is broken
into two CDATA sections, <![CDATA[]]]]> and <![CDATA[>]].
*/
static
void
print_xml_cdata
(
FILE
*
xml_file
,
const
char
*
str
,
ulong
len
)
{
const
char
*
end
;
fputs
(
"<![CDATA[
\n
"
,
xml_file
);
for
(
end
=
str
+
len
;
str
!=
end
;
str
++
)
{
switch
(
*
str
)
{
case
']'
:
if
((
*
(
str
+
1
)
==
']'
)
&&
(
*
(
str
+
2
)
==
'>'
))
{
fputs
(
"]]]]><![CDATA[>"
,
xml_file
);
str
+=
2
;
continue
;
}
/* fall through */
default:
fputc
(
*
str
,
xml_file
);
break
;
}
}
fputs
(
"
\n
]]>
\n
"
,
xml_file
);
check_io
(
xml_file
);
}
/*
/*
Print xml tag with many attributes.
Print xml tag with many attributes.
...
@@ -1785,6 +1839,7 @@ static void print_xml_null_tag(FILE * xml_file, const char* sbeg,
...
@@ -1785,6 +1839,7 @@ static void print_xml_null_tag(FILE * xml_file, const char* sbeg,
row_name - xml tag name
row_name - xml tag name
tableRes - query result
tableRes - query result
row - result row
row - result row
str_create - create statement header string
DESCRIPTION
DESCRIPTION
Print tag with many attribute to the xml_file. Format is:
Print tag with many attribute to the xml_file. Format is:
...
@@ -1794,9 +1849,13 @@ static void print_xml_null_tag(FILE * xml_file, const char* sbeg,
...
@@ -1794,9 +1849,13 @@ static void print_xml_null_tag(FILE * xml_file, const char* sbeg,
*/
*/
static
void
print_xml_row
(
FILE
*
xml_file
,
const
char
*
row_name
,
static
void
print_xml_row
(
FILE
*
xml_file
,
const
char
*
row_name
,
MYSQL_RES
*
tableRes
,
MYSQL_ROW
*
row
)
MYSQL_RES
*
tableRes
,
MYSQL_ROW
*
row
,
const
char
*
str_create
)
{
{
uint
i
;
uint
i
;
my_bool
body_found
=
0
;
char
*
create_stmt_ptr
;
ulong
create_stmt_len
=
0
;
MYSQL_FIELD
*
field
;
MYSQL_FIELD
*
field
;
ulong
*
lengths
=
mysql_fetch_lengths
(
tableRes
);
ulong
*
lengths
=
mysql_fetch_lengths
(
tableRes
);
...
@@ -1806,20 +1865,110 @@ static void print_xml_row(FILE *xml_file, const char *row_name,
...
@@ -1806,20 +1865,110 @@ static void print_xml_row(FILE *xml_file, const char *row_name,
for
(
i
=
0
;
(
field
=
mysql_fetch_field
(
tableRes
));
i
++
)
for
(
i
=
0
;
(
field
=
mysql_fetch_field
(
tableRes
));
i
++
)
{
{
if
((
*
row
)[
i
])
if
((
*
row
)[
i
])
{
/* For 'create' statements, dump using CDATA. */
if
((
str_create
)
&&
(
strcmp
(
str_create
,
field
->
name
)
==
0
))
{
create_stmt_ptr
=
(
*
row
)[
i
];
create_stmt_len
=
lengths
[
i
];
body_found
=
1
;
}
else
{
{
fputc
(
' '
,
xml_file
);
fputc
(
' '
,
xml_file
);
print_quoted_xml
(
xml_file
,
field
->
name
,
field
->
name_length
);
print_quoted_xml
(
xml_file
,
field
->
name
,
field
->
name_length
,
1
);
fputs
(
"=
\"
"
,
xml_file
);
fputs
(
"=
\"
"
,
xml_file
);
print_quoted_xml
(
xml_file
,
(
*
row
)[
i
],
lengths
[
i
]
);
print_quoted_xml
(
xml_file
,
(
*
row
)[
i
],
lengths
[
i
],
0
);
fputc
(
'"'
,
xml_file
);
fputc
(
'"'
,
xml_file
);
check_io
(
xml_file
);
check_io
(
xml_file
);
}
}
}
}
}
if
(
create_stmt_len
)
{
DBUG_ASSERT
(
body_found
);
fputs
(
">
\n
"
,
xml_file
);
print_xml_cdata
(
xml_file
,
create_stmt_ptr
,
create_stmt_len
);
fprintf
(
xml_file
,
"
\t\t
</%s>
\n
"
,
row_name
);
}
else
fputs
(
" />
\n
"
,
xml_file
);
fputs
(
" />
\n
"
,
xml_file
);
check_io
(
xml_file
);
check_io
(
xml_file
);
}
}
/**
Print xml comments.
@param xml_file - output file
@param len - length of comment message
@param comment_string - comment message
@description
Print the comment message in the format:
"<!-- \n comment string \n -->\n"
@note
Any occurrence of continuous hyphens will be
squeezed to a single hyphen.
*/
static
void
print_xml_comment
(
FILE
*
xml_file
,
ulong
len
,
const
char
*
comment_string
)
{
const
char
*
end
;
fputs
(
"<!-- "
,
xml_file
);
for
(
end
=
comment_string
+
len
;
comment_string
!=
end
;
comment_string
++
)
{
/*
The string "--" (double-hyphen) MUST NOT occur within xml comments.
*/
switch
(
*
comment_string
)
{
case
'-'
:
if
(
*
(
comment_string
+
1
)
==
'-'
)
/* Only one hyphen allowed. */
break
;
default:
fputc
(
*
comment_string
,
xml_file
);
break
;
}
}
fputs
(
" -->
\n
"
,
xml_file
);
check_io
(
xml_file
);
}
/* A common printing function for xml and non-xml modes. */
static
void
print_comment
(
FILE
*
sql_file
,
my_bool
is_error
,
const
char
*
format
,
...)
{
static
char
comment_buff
[
COMMENT_LENGTH
];
va_list
args
;
/* If its an error message, print it ignoring opt_comments. */
if
(
!
is_error
&&
!
opt_comments
)
return
;
va_start
(
args
,
format
);
my_vsnprintf
(
comment_buff
,
COMMENT_LENGTH
,
format
,
args
);
va_end
(
args
);
if
(
!
opt_xml
)
{
fputs
(
comment_buff
,
sql_file
);
check_io
(
sql_file
);
return
;
}
print_xml_comment
(
sql_file
,
strlen
(
comment_buff
),
comment_buff
);
}
/*
/*
create_delimiter
create_delimiter
Generate a new (null-terminated) string that does not exist in query
Generate a new (null-terminated) string that does not exist in query
...
@@ -1886,8 +2035,8 @@ static uint dump_events_for_db(char *db)
...
@@ -1886,8 +2035,8 @@ static uint dump_events_for_db(char *db)
mysql_real_escape_string
(
mysql
,
db_name_buff
,
db
,
strlen
(
db
));
mysql_real_escape_string
(
mysql
,
db_name_buff
,
db
,
strlen
(
db
));
/* nice comments */
/* nice comments */
if
(
opt_comments
)
print_comment
(
sql_file
,
0
,
fprintf
(
sql_file
,
"
\n
--
\n
-- Dumping events for database '%s'
\n
--
\n
"
,
db
);
"
\n
--
\n
-- Dumping events for database '%s'
\n
--
\n
"
,
db
);
/*
/*
not using "mysql_query_with_error_report" because we may have not
not using "mysql_query_with_error_report" because we may have not
...
@@ -1901,6 +2050,10 @@ static uint dump_events_for_db(char *db)
...
@@ -1901,6 +2050,10 @@ static uint dump_events_for_db(char *db)
strcpy
(
delimiter
,
";"
);
strcpy
(
delimiter
,
";"
);
if
(
mysql_num_rows
(
event_list_res
)
>
0
)
if
(
mysql_num_rows
(
event_list_res
)
>
0
)
{
if
(
opt_xml
)
fputs
(
"
\t
<events>
\n
"
,
sql_file
);
else
{
{
fprintf
(
sql_file
,
"/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;
\n
"
);
fprintf
(
sql_file
,
"/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;
\n
"
);
...
@@ -1908,6 +2061,7 @@ static uint dump_events_for_db(char *db)
...
@@ -1908,6 +2061,7 @@ static uint dump_events_for_db(char *db)
if
(
fetch_db_collation
(
db_name_buff
,
db_cl_name
,
sizeof
(
db_cl_name
)))
if
(
fetch_db_collation
(
db_name_buff
,
db_cl_name
,
sizeof
(
db_cl_name
)))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
}
if
(
switch_character_set_results
(
mysql
,
"binary"
))
if
(
switch_character_set_results
(
mysql
,
"binary"
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
...
@@ -1924,6 +2078,13 @@ static uint dump_events_for_db(char *db)
...
@@ -1924,6 +2078,13 @@ static uint dump_events_for_db(char *db)
while
((
row
=
mysql_fetch_row
(
event_res
))
!=
NULL
)
while
((
row
=
mysql_fetch_row
(
event_res
))
!=
NULL
)
{
{
if
(
opt_xml
)
{
print_xml_row
(
sql_file
,
"event"
,
event_res
,
&
row
,
"Create Event"
);
continue
;
}
/*
/*
if the user has EXECUTE privilege he can see event names, but not the
if the user has EXECUTE privilege he can see event names, but not the
event body!
event body!
...
@@ -2009,8 +2170,16 @@ static uint dump_events_for_db(char *db)
...
@@ -2009,8 +2170,16 @@ static uint dump_events_for_db(char *db)
mysql_free_result
(
event_res
);
mysql_free_result
(
event_res
);
}
/* end of list of events */
}
/* end of list of events */
if
(
opt_xml
)
{
fputs
(
"
\t
</events>
\n
"
,
sql_file
);
check_io
(
sql_file
);
}
else
{
fprintf
(
sql_file
,
"DELIMITER ;
\n
"
);
fprintf
(
sql_file
,
"DELIMITER ;
\n
"
);
fprintf
(
sql_file
,
"/*!50106 SET TIME_ZONE= @save_time_zone */ ;
\n
"
);
fprintf
(
sql_file
,
"/*!50106 SET TIME_ZONE= @save_time_zone */ ;
\n
"
);
}
if
(
switch_character_set_results
(
mysql
,
default_charset
))
if
(
switch_character_set_results
(
mysql
,
default_charset
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
...
@@ -2064,6 +2233,7 @@ static uint dump_routines_for_db(char *db)
...
@@ -2064,6 +2233,7 @@ static uint dump_routines_for_db(char *db)
const
char
*
routine_type
[]
=
{
"FUNCTION"
,
"PROCEDURE"
};
const
char
*
routine_type
[]
=
{
"FUNCTION"
,
"PROCEDURE"
};
char
db_name_buff
[
NAME_LEN
*
2
+
3
],
name_buff
[
NAME_LEN
*
2
+
3
];
char
db_name_buff
[
NAME_LEN
*
2
+
3
],
name_buff
[
NAME_LEN
*
2
+
3
];
char
*
routine_name
;
char
*
routine_name
;
char
*
query_str
;
int
i
;
int
i
;
FILE
*
sql_file
=
md_result_file
;
FILE
*
sql_file
=
md_result_file
;
MYSQL_RES
*
routine_res
,
*
routine_list_res
;
MYSQL_RES
*
routine_res
,
*
routine_list_res
;
...
@@ -2078,8 +2248,8 @@ static uint dump_routines_for_db(char *db)
...
@@ -2078,8 +2248,8 @@ static uint dump_routines_for_db(char *db)
mysql_real_escape_string
(
mysql
,
db_name_buff
,
db
,
strlen
(
db
));
mysql_real_escape_string
(
mysql
,
db_name_buff
,
db
,
strlen
(
db
));
/* nice comments */
/* nice comments */
if
(
opt_comments
)
print_comment
(
sql_file
,
0
,
fprintf
(
sql_file
,
"
\n
--
\n
-- Dumping routines for database '%s'
\n
--
\n
"
,
db
);
"
\n
--
\n
-- Dumping routines for database '%s'
\n
--
\n
"
,
db
);
/*
/*
not using "mysql_query_with_error_report" because we may have not
not using "mysql_query_with_error_report" because we may have not
...
@@ -2096,6 +2266,9 @@ static uint dump_routines_for_db(char *db)
...
@@ -2096,6 +2266,9 @@ static uint dump_routines_for_db(char *db)
if
(
switch_character_set_results
(
mysql
,
"binary"
))
if
(
switch_character_set_results
(
mysql
,
"binary"
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
if
(
opt_xml
)
fputs
(
"
\t
<routines>
\n
"
,
sql_file
);
/* 0, retrieve and dump functions, 1, procedures */
/* 0, retrieve and dump functions, 1, procedures */
for
(
i
=
0
;
i
<=
1
;
i
++
)
for
(
i
=
0
;
i
<=
1
;
i
++
)
{
{
...
@@ -2131,13 +2304,25 @@ static uint dump_routines_for_db(char *db)
...
@@ -2131,13 +2304,25 @@ static uint dump_routines_for_db(char *db)
row
[
2
]
?
(
int
)
strlen
(
row
[
2
])
:
0
));
row
[
2
]
?
(
int
)
strlen
(
row
[
2
])
:
0
));
if
(
row
[
2
]
==
NULL
)
if
(
row
[
2
]
==
NULL
)
{
{
fprintf
(
sql_file
,
"
\n
-- insufficient privileges to %s
\n
"
,
query_buff
);
print_comment
(
sql_file
,
1
,
"
\n
-- insufficient privileges to %s
\n
"
,
fprintf
(
sql_file
,
"-- does %s have permissions on mysql.proc?
\n\n
"
,
current_user
);
query_buff
);
print_comment
(
sql_file
,
1
,
"-- does %s have permissions on mysql.proc?
\n\n
"
,
current_user
);
maybe_die
(
EX_MYSQLERR
,
"%s has insufficent privileges to %s!"
,
current_user
,
query_buff
);
maybe_die
(
EX_MYSQLERR
,
"%s has insufficent privileges to %s!"
,
current_user
,
query_buff
);
}
}
else
if
(
strlen
(
row
[
2
]))
else
if
(
strlen
(
row
[
2
]))
{
{
char
*
query_str
;
if
(
opt_xml
)
{
if
(
i
)
// Procedures.
print_xml_row
(
sql_file
,
"routine"
,
routine_res
,
&
row
,
"Create Procedure"
);
else
// Functions.
print_xml_row
(
sql_file
,
"routine"
,
routine_res
,
&
row
,
"Create Function"
);
continue
;
}
if
(
opt_drop
)
if
(
opt_drop
)
fprintf
(
sql_file
,
"/*!50003 DROP %s IF EXISTS %s */;
\n
"
,
fprintf
(
sql_file
,
"/*!50003 DROP %s IF EXISTS %s */;
\n
"
,
routine_type
[
i
],
routine_name
);
routine_type
[
i
],
routine_name
);
...
@@ -2217,6 +2402,12 @@ static uint dump_routines_for_db(char *db)
...
@@ -2217,6 +2402,12 @@ static uint dump_routines_for_db(char *db)
mysql_free_result
(
routine_list_res
);
mysql_free_result
(
routine_list_res
);
}
/* end of for i (0 .. 1) */
}
/* end of for i (0 .. 1) */
if
(
opt_xml
)
{
fputs
(
"
\t
</routines>
\n
"
,
sql_file
);
check_io
(
sql_file
);
}
if
(
switch_character_set_results
(
mysql
,
default_charset
))
if
(
switch_character_set_results
(
mysql
,
default_charset
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
...
@@ -2329,16 +2520,16 @@ static uint get_table_structure(char *table, char *db, char *table_type,
...
@@ -2329,16 +2520,16 @@ static uint get_table_structure(char *table, char *db, char *table_type,
write_header
(
sql_file
,
db
);
write_header
(
sql_file
,
db
);
}
}
if
(
!
opt_xml
&&
opt_comments
)
{
if
(
strcmp
(
table_type
,
"VIEW"
)
==
0
)
/* view */
if
(
strcmp
(
table_type
,
"VIEW"
)
==
0
)
/* view */
fprintf
(
sql_file
,
"
\n
--
\n
-- Temporary table structure for view %s
\n
--
\n\n
"
,
print_comment
(
sql_file
,
0
,
"
\n
--
\n
-- Temporary table structure for view %s
\n
--
\n\n
"
,
result_table
);
result_table
);
else
else
fprintf
(
sql_file
,
"
\n
--
\n
-- Table structure for table %s
\n
--
\n\n
"
,
print_comment
(
sql_file
,
0
,
"
\n
--
\n
-- Table structure for table %s
\n
--
\n\n
"
,
result_table
);
result_table
);
check_io
(
sql_file
);
}
if
(
opt_drop
)
if
(
opt_drop
)
{
{
/*
/*
...
@@ -2539,8 +2730,9 @@ static uint get_table_structure(char *table, char *db, char *table_type,
...
@@ -2539,8 +2730,9 @@ static uint get_table_structure(char *table, char *db, char *table_type,
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
write_header
(
sql_file
,
db
);
write_header
(
sql_file
,
db
);
}
}
if
(
!
opt_xml
&&
opt_comments
)
fprintf
(
sql_file
,
"
\n
--
\n
-- Table structure for table %s
\n
--
\n\n
"
,
print_comment
(
sql_file
,
0
,
"
\n
--
\n
-- Table structure for table %s
\n
--
\n\n
"
,
result_table
);
result_table
);
if
(
opt_drop
)
if
(
opt_drop
)
fprintf
(
sql_file
,
"DROP TABLE IF EXISTS %s;
\n
"
,
result_table
);
fprintf
(
sql_file
,
"DROP TABLE IF EXISTS %s;
\n
"
,
result_table
);
...
@@ -2592,7 +2784,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
...
@@ -2592,7 +2784,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
{
{
if
(
opt_xml
)
if
(
opt_xml
)
{
{
print_xml_row
(
sql_file
,
"field"
,
result
,
&
row
);
print_xml_row
(
sql_file
,
"field"
,
result
,
&
row
,
NullS
);
continue
;
continue
;
}
}
...
@@ -2664,7 +2856,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
...
@@ -2664,7 +2856,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
{
{
if
(
opt_xml
)
if
(
opt_xml
)
{
{
print_xml_row
(
sql_file
,
"key"
,
result
,
&
row
);
print_xml_row
(
sql_file
,
"key"
,
result
,
&
row
,
NullS
);
continue
;
continue
;
}
}
...
@@ -2723,7 +2915,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
...
@@ -2723,7 +2915,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
else
else
{
{
if
(
opt_xml
)
if
(
opt_xml
)
print_xml_row
(
sql_file
,
"options"
,
result
,
&
row
);
print_xml_row
(
sql_file
,
"options"
,
result
,
&
row
,
NullS
);
else
else
{
{
fputs
(
"/*!"
,
sql_file
);
fputs
(
"/*!"
,
sql_file
);
...
@@ -2767,9 +2959,19 @@ static void dump_trigger_old(FILE *sql_file, MYSQL_RES *show_triggers_rs,
...
@@ -2767,9 +2959,19 @@ static void dump_trigger_old(FILE *sql_file, MYSQL_RES *show_triggers_rs,
char
*
quoted_table_name
=
quote_name
(
table_name
,
quoted_table_name_buf
,
1
);
char
*
quoted_table_name
=
quote_name
(
table_name
,
quoted_table_name_buf
,
1
);
char
name_buff
[
NAME_LEN
*
4
+
3
];
char
name_buff
[
NAME_LEN
*
4
+
3
];
const
char
*
xml_msg
=
"
\n
Warning! mysqldump being run against old server "
"that does not
\n
support 'SHOW CREATE TRIGGERS' "
"statement. Skipping..
\n
"
;
DBUG_ENTER
(
"dump_trigger_old"
);
DBUG_ENTER
(
"dump_trigger_old"
);
if
(
opt_xml
)
{
print_xml_comment
(
sql_file
,
strlen
(
xml_msg
),
xml_msg
);
check_io
(
sql_file
);
DBUG_VOID_RETURN
;
}
fprintf
(
sql_file
,
fprintf
(
sql_file
,
"--
\n
"
"--
\n
"
"-- WARNING: old server version. "
"-- WARNING: old server version. "
...
@@ -2833,17 +3035,25 @@ static int dump_trigger(FILE *sql_file, MYSQL_RES *show_create_trigger_rs,
...
@@ -2833,17 +3035,25 @@ static int dump_trigger(FILE *sql_file, MYSQL_RES *show_create_trigger_rs,
const
char
*
db_cl_name
)
const
char
*
db_cl_name
)
{
{
MYSQL_ROW
row
;
MYSQL_ROW
row
;
char
*
query_str
;
int
db_cl_altered
=
FALSE
;
int
db_cl_altered
=
FALSE
;
DBUG_ENTER
(
"dump_trigger"
);
DBUG_ENTER
(
"dump_trigger"
);
while
((
row
=
mysql_fetch_row
(
show_create_trigger_rs
)))
while
((
row
=
mysql_fetch_row
(
show_create_trigger_rs
)))
{
{
char
*
query_str
=
cover_definer_clause
(
row
[
2
],
strlen
(
row
[
2
]),
if
(
opt_xml
)
{
print_xml_row
(
sql_file
,
"trigger"
,
show_create_trigger_rs
,
&
row
,
"SQL Original Statement"
);
check_io
(
sql_file
);
continue
;
}
query_str
=
cover_definer_clause
(
row
[
2
],
strlen
(
row
[
2
]),
C_STRING_WITH_LEN
(
"50017"
),
C_STRING_WITH_LEN
(
"50017"
),
C_STRING_WITH_LEN
(
"50003"
),
C_STRING_WITH_LEN
(
"50003"
),
C_STRING_WITH_LEN
(
" TRIGGER"
));
C_STRING_WITH_LEN
(
" TRIGGER"
));
if
(
switch_db_collation
(
sql_file
,
db_name
,
";"
,
if
(
switch_db_collation
(
sql_file
,
db_name
,
";"
,
db_cl_name
,
row
[
5
],
&
db_cl_altered
))
db_cl_name
,
row
[
5
],
&
db_cl_altered
))
DBUG_RETURN
(
TRUE
);
DBUG_RETURN
(
TRUE
);
...
@@ -2931,6 +3141,13 @@ static int dump_triggers_for_table(char *table_name, char *db_name)
...
@@ -2931,6 +3141,13 @@ static int dump_triggers_for_table(char *table_name, char *db_name)
/* Dump triggers. */
/* Dump triggers. */
if
(
!
mysql_num_rows
(
show_triggers_rs
))
goto
skip
;
if
(
opt_xml
)
print_xml_tag
(
sql_file
,
"
\t
"
,
"
\n
"
,
"triggers"
,
"name="
,
table_name
,
NullS
);
while
((
row
=
mysql_fetch_row
(
show_triggers_rs
)))
while
((
row
=
mysql_fetch_row
(
show_triggers_rs
)))
{
{
...
@@ -2963,6 +3180,13 @@ static int dump_triggers_for_table(char *table_name, char *db_name)
...
@@ -2963,6 +3180,13 @@ static int dump_triggers_for_table(char *table_name, char *db_name)
}
}
if
(
opt_xml
)
{
fputs
(
"
\t
</triggers>
\n
"
,
sql_file
);
check_io
(
sql_file
);
}
skip:
mysql_free_result
(
show_triggers_rs
);
mysql_free_result
(
show_triggers_rs
);
if
(
switch_character_set_results
(
mysql
,
default_charset
))
if
(
switch_character_set_results
(
mysql
,
default_charset
))
...
@@ -3211,34 +3435,24 @@ static void dump_table(char *table, char *db)
...
@@ -3211,34 +3435,24 @@ static void dump_table(char *table, char *db)
}
}
else
else
{
{
if
(
!
opt_xml
&&
opt_comments
)
print_comment
(
md_result_file
,
0
,
{
"
\n
--
\n
-- Dumping data for table %s
\n
--
\n
"
,
fprintf
(
md_result_file
,
"
\n
--
\n
-- Dumping data for table %s
\n
--
\n
"
,
result_table
);
result_table
);
check_io
(
md_result_file
);
}
dynstr_append_checked
(
&
query_string
,
"SELECT /*!40001 SQL_NO_CACHE */ * FROM "
);
dynstr_append_checked
(
&
query_string
,
"SELECT /*!40001 SQL_NO_CACHE */ * FROM "
);
dynstr_append_checked
(
&
query_string
,
result_table
);
dynstr_append_checked
(
&
query_string
,
result_table
);
if
(
where
)
if
(
where
)
{
{
if
(
!
opt_xml
&&
opt_comments
)
print_comment
(
md_result_file
,
0
,
"-- WHERE: %s
\n
"
,
where
);
{
fprintf
(
md_result_file
,
"-- WHERE: %s
\n
"
,
where
);
check_io
(
md_result_file
);
}
dynstr_append_checked
(
&
query_string
,
" WHERE "
);
dynstr_append_checked
(
&
query_string
,
" WHERE "
);
dynstr_append_checked
(
&
query_string
,
where
);
dynstr_append_checked
(
&
query_string
,
where
);
}
}
if
(
order_by
)
if
(
order_by
)
{
{
if
(
!
opt_xml
&&
opt_comments
)
print_comment
(
md_result_file
,
0
,
"-- ORDER BY: %s
\n
"
,
order_by
);
{
fprintf
(
md_result_file
,
"-- ORDER BY: %s
\n
"
,
order_by
);
check_io
(
md_result_file
);
}
dynstr_append_checked
(
&
query_string
,
" ORDER BY "
);
dynstr_append_checked
(
&
query_string
,
" ORDER BY "
);
dynstr_append_checked
(
&
query_string
,
order_by
);
dynstr_append_checked
(
&
query_string
,
order_by
);
}
}
...
@@ -3434,7 +3648,7 @@ static void dump_table(char *table, char *db)
...
@@ -3434,7 +3648,7 @@ static void dump_table(char *table, char *db)
{
{
print_xml_tag
(
md_result_file
,
"
\t\t
"
,
""
,
"field"
,
"name="
,
print_xml_tag
(
md_result_file
,
"
\t\t
"
,
""
,
"field"
,
"name="
,
field
->
name
,
NullS
);
field
->
name
,
NullS
);
print_quoted_xml
(
md_result_file
,
row
[
i
],
length
);
print_quoted_xml
(
md_result_file
,
row
[
i
],
length
,
0
);
}
}
fputs
(
"</field>
\n
"
,
md_result_file
);
fputs
(
"</field>
\n
"
,
md_result_file
);
}
}
...
@@ -3738,11 +3952,9 @@ static int dump_tablespaces(char* ts_where)
...
@@ -3738,11 +3952,9 @@ static int dump_tablespaces(char* ts_where)
first
=
1
;
first
=
1
;
if
(
first
)
if
(
first
)
{
{
if
(
!
opt_xml
&&
opt_comments
)
print_comment
(
md_result_file
,
0
,
"
\n
--
\n
-- Logfile group: %s
\n
--
\n
"
,
{
row
[
0
]);
fprintf
(
md_result_file
,
"
\n
--
\n
-- Logfile group: %s
\n
--
\n
"
,
row
[
0
]);
check_io
(
md_result_file
);
}
fprintf
(
md_result_file
,
"
\n
CREATE"
);
fprintf
(
md_result_file
,
"
\n
CREATE"
);
}
}
else
else
...
@@ -3810,11 +4022,7 @@ static int dump_tablespaces(char* ts_where)
...
@@ -3810,11 +4022,7 @@ static int dump_tablespaces(char* ts_where)
first
=
1
;
first
=
1
;
if
(
first
)
if
(
first
)
{
{
if
(
!
opt_xml
&&
opt_comments
)
print_comment
(
md_result_file
,
0
,
"
\n
--
\n
-- Tablespace: %s
\n
--
\n
"
,
row
[
0
]);
{
fprintf
(
md_result_file
,
"
\n
--
\n
-- Tablespace: %s
\n
--
\n
"
,
row
[
0
]);
check_io
(
md_result_file
);
}
fprintf
(
md_result_file
,
"
\n
CREATE"
);
fprintf
(
md_result_file
,
"
\n
CREATE"
);
}
}
else
else
...
@@ -4012,11 +4220,9 @@ static int init_dumping(char *database, int init_func(char*))
...
@@ -4012,11 +4220,9 @@ static int init_dumping(char *database, int init_func(char*))
*/
*/
char
quoted_database_buf
[
NAME_LEN
*
2
+
3
];
char
quoted_database_buf
[
NAME_LEN
*
2
+
3
];
char
*
qdatabase
=
quote_name
(
database
,
quoted_database_buf
,
opt_quoted
);
char
*
qdatabase
=
quote_name
(
database
,
quoted_database_buf
,
opt_quoted
);
if
(
opt_comments
)
{
print_comment
(
md_result_file
,
0
,
fprintf
(
md_result_file
,
"
\n
--
\n
-- Current Database: %s
\n
--
\n
"
,
qdatabase
);
"
\n
--
\n
-- Current Database: %s
\n
--
\n
"
,
qdatabase
);
check_io
(
md_result_file
);
}
/* Call the view or table specific function */
/* Call the view or table specific function */
init_func
(
qdatabase
);
init_func
(
qdatabase
);
...
@@ -4092,8 +4298,7 @@ static int dump_all_tables_in_db(char *database)
...
@@ -4092,8 +4298,7 @@ static int dump_all_tables_in_db(char *database)
dump_table
(
table
,
database
);
dump_table
(
table
,
database
);
my_free
(
order_by
);
my_free
(
order_by
);
order_by
=
0
;
order_by
=
0
;
if
(
opt_dump_triggers
&&
!
opt_xml
&&
if
(
opt_dump_triggers
&&
mysql_get_server_version
(
mysql
)
>=
50009
)
mysql_get_server_version
(
mysql
)
>=
50009
)
{
{
if
(
dump_triggers_for_table
(
table
,
database
))
if
(
dump_triggers_for_table
(
table
,
database
))
{
{
...
@@ -4104,14 +4309,12 @@ static int dump_all_tables_in_db(char *database)
...
@@ -4104,14 +4309,12 @@ static int dump_all_tables_in_db(char *database)
}
}
}
}
}
}
if
(
opt_events
&&
!
opt_xml
&&
if
(
opt_events
&&
mysql_get_server_version
(
mysql
)
>=
50106
)
mysql_get_server_version
(
mysql
)
>=
50106
)
{
{
DBUG_PRINT
(
"info"
,
(
"Dumping events for database %s"
,
database
));
DBUG_PRINT
(
"info"
,
(
"Dumping events for database %s"
,
database
));
dump_events_for_db
(
database
);
dump_events_for_db
(
database
);
}
}
if
(
opt_routines
&&
!
opt_xml
&&
if
(
opt_routines
&&
mysql_get_server_version
(
mysql
)
>=
50009
)
mysql_get_server_version
(
mysql
)
>=
50009
)
{
{
DBUG_PRINT
(
"info"
,
(
"Dumping routines for database %s"
,
database
));
DBUG_PRINT
(
"info"
,
(
"Dumping routines for database %s"
,
database
));
dump_routines_for_db
(
database
);
dump_routines_for_db
(
database
);
...
@@ -4352,15 +4555,13 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
...
@@ -4352,15 +4555,13 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
for
(
pos
=
dump_tables
;
pos
<
end
;
pos
++
)
for
(
pos
=
dump_tables
;
pos
<
end
;
pos
++
)
get_view_structure
(
*
pos
,
db
);
get_view_structure
(
*
pos
,
db
);
}
}
if
(
opt_events
&&
!
opt_xml
&&
if
(
opt_events
&&
mysql_get_server_version
(
mysql
)
>=
50106
)
mysql_get_server_version
(
mysql
)
>=
50106
)
{
{
DBUG_PRINT
(
"info"
,
(
"Dumping events for database %s"
,
db
));
DBUG_PRINT
(
"info"
,
(
"Dumping events for database %s"
,
db
));
dump_events_for_db
(
db
);
dump_events_for_db
(
db
);
}
}
/* obtain dump of routines (procs/functions) */
/* obtain dump of routines (procs/functions) */
if
(
opt_routines
&&
!
opt_xml
&&
if
(
opt_routines
&&
mysql_get_server_version
(
mysql
)
>=
50009
)
mysql_get_server_version
(
mysql
)
>=
50009
)
{
{
DBUG_PRINT
(
"info"
,
(
"Dumping routines for database %s"
,
db
));
DBUG_PRINT
(
"info"
,
(
"Dumping routines for database %s"
,
db
));
dump_routines_for_db
(
db
);
dump_routines_for_db
(
db
);
...
@@ -4395,8 +4596,7 @@ static int do_show_master_status(MYSQL *mysql_con)
...
@@ -4395,8 +4596,7 @@ static int do_show_master_status(MYSQL *mysql_con)
if
(
row
&&
row
[
0
]
&&
row
[
1
])
if
(
row
&&
row
[
0
]
&&
row
[
1
])
{
{
/* SHOW MASTER STATUS reports file and position */
/* SHOW MASTER STATUS reports file and position */
if
(
opt_comments
)
print_comment
(
md_result_file
,
0
,
fprintf
(
md_result_file
,
"
\n
--
\n
-- Position to start replication or point-in-time "
"
\n
--
\n
-- Position to start replication or point-in-time "
"recovery from
\n
--
\n\n
"
);
"recovery from
\n
--
\n\n
"
);
fprintf
(
md_result_file
,
fprintf
(
md_result_file
,
...
@@ -4986,12 +5186,10 @@ static my_bool get_view_structure(char *table, char* db)
...
@@ -4986,12 +5186,10 @@ static my_bool get_view_structure(char *table, char* db)
write_header
(
sql_file
,
db
);
write_header
(
sql_file
,
db
);
}
}
if
(
!
opt_xml
&&
opt_comments
)
print_comment
(
sql_file
,
0
,
{
"
\n
--
\n
-- Final view structure for view %s
\n
--
\n\n
"
,
fprintf
(
sql_file
,
"
\n
--
\n
-- Final view structure for view %s
\n
--
\n\n
"
,
result_table
);
result_table
);
check_io
(
sql_file
);
}
/* Table might not exist if this view was dumped with --tab. */
/* Table might not exist if this view was dumped with --tab. */
fprintf
(
sql_file
,
"/*!50001 DROP TABLE IF EXISTS %s*/;
\n
"
,
opt_quoted_table
);
fprintf
(
sql_file
,
"/*!50001 DROP TABLE IF EXISTS %s*/;
\n
"
,
opt_quoted_table
);
if
(
opt_drop
)
if
(
opt_drop
)
...
@@ -5188,6 +5386,12 @@ int main(int argc, char **argv)
...
@@ -5188,6 +5386,12 @@ int main(int argc, char **argv)
exit
(
exit_code
);
exit
(
exit_code
);
}
}
/*
Disable comments in xml mode if 'comments' option is not explicitly used.
*/
if
(
opt_xml
&&
!
opt_comments_used
)
opt_comments
=
0
;
if
(
log_error_file
)
if
(
log_error_file
)
{
{
if
(
!
(
stderror_file
=
freopen
(
log_error_file
,
"a+"
,
stderr
)))
if
(
!
(
stderror_file
=
freopen
(
log_error_file
,
"a+"
,
stderr
)))
...
...
mysql-test/r/mysqldump.result
View file @
d8af27ef
...
@@ -4628,6 +4628,445 @@ ALTER DATABASE `test-database` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
...
@@ -4628,6 +4628,445 @@ ALTER DATABASE `test-database` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
DROP DATABASE `test-database`;
DROP DATABASE `test-database`;
USE test;
USE test;
#
#
# BUG#11760384 : 52792: mysqldump in XML mode does not dump routines.
#
CREATE DATABASE BUG52792;
USE BUG52792;
CREATE TABLE t1 (c1 INT, c2 VARCHAR(20));
CREATE TABLE t2 (c1 INT);
INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb'), (3, 'ccc');
INSERT INTO t2 VALUES (1),(2),(3);
# Stored Procedures.
CREATE PROCEDURE simpleproc1 (OUT param1 INT)
BEGIN
SELECT COUNT(*) INTO param1 FROM t1;
END//
CREATE PROCEDURE simpleproc2 (OUT param1 INT)
BEGIN
SELECT COUNT(*) INTO param1 FROM t2;
END//
# Events.
CREATE EVENT e1 ON SCHEDULE EVERY 1 SECOND DO DROP DATABASE BUG52792;
CREATE EVENT e2 ON SCHEDULE EVERY 1 SECOND DO DROP DATABASE BUG52792;
# Functions.
CREATE FUNCTION `hello1` (s CHAR(20))
RETURNS CHAR(50) DETERMINISTIC
RETURN CONCAT('Hello, ' ,s ,'!');
CREATE FUNCTION `hello2` (s CHAR(20))
RETURNS CHAR(50) DETERMINISTIC
RETURN CONCAT(']]>, ' , s ,'!');
# Triggers.
CREATE TRIGGER trig1 BEFORE INSERT ON t2
FOR EACH ROW BEGIN
INSERT INTO t2 VALUES(1);
END;
|
CREATE TRIGGER trig2 AFTER INSERT ON t2
FOR EACH ROW BEGIN
INSERT INTO t2 VALUES(1, ']]>');
INSERT INTO t2 VALUES(2, '<![CDATA]]>');
INSERT INTO t2 VALUES(3, '<![CDATA[');
INSERT INTO t2 VALUES(4, '< > & \ " _');
END;
|
# Views
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE VIEW v2 AS SELECT * FROM t2;
# Dumping BUG52792 database in xml format.
# Running 'replace_regex on timestamp'
<?xml version="1.0"?>
<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<database name="BUG52792">
<table_structure name="t1">
<field Field="c1" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
<field Field="c2" Type="varchar(20)" Null="YES" Key="" Extra="" Comment="" />
<options Name="t1" Engine="MyISAM" Version="10" Row_format="Dynamic" Rows="3" Avg_row_length="20" Data_length="60" Max_data_length="281474976710655" Index_length="1024" Data_free="0" Create_time="--TIME--" Update_time="--TIME--" Collation="latin1_swedish_ci" Create_options="" Comment="" />
</table_structure>
<table_data name="t1">
<row>
<field name="c1">1</field>
<field name="c2">aaa</field>
</row>
<row>
<field name="c1">2</field>
<field name="c2">bbb</field>
</row>
<row>
<field name="c1">3</field>
<field name="c2">ccc</field>
</row>
</table_data>
<table_structure name="t2">
<field Field="c1" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
<options Name="t2" Engine="MyISAM" Version="10" Row_format="Fixed" Rows="3" Avg_row_length="7" Data_length="21" Max_data_length="1970324836974591" Index_length="1024" Data_free="0" Create_time="--TIME--" Update_time="--TIME--" Collation="latin1_swedish_ci" Create_options="" Comment="" />
</table_structure>
<table_data name="t2">
<row>
<field name="c1">1</field>
</row>
<row>
<field name="c1">2</field>
</row>
<row>
<field name="c1">3</field>
</row>
</table_data>
<triggers name="t2">
<trigger Trigger="trig1" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` TRIGGER trig1 BEFORE INSERT ON t2
FOR EACH ROW BEGIN
INSERT INTO t2 VALUES(1);
END
]]>
</trigger>
<trigger Trigger="trig2" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` TRIGGER trig2 AFTER INSERT ON t2
FOR EACH ROW BEGIN
INSERT INTO t2 VALUES(1, ']]]]><![CDATA[>');
INSERT INTO t2 VALUES(2, '<![CDATA]]]]><![CDATA[>');
INSERT INTO t2 VALUES(3, '<![CDATA[');
INSERT INTO t2 VALUES(4, '< > & \ " _');
END
]]>
</trigger>
</triggers>
<table_structure name="v1">
<field Field="c1" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
<field Field="c2" Type="varchar(20)" Null="YES" Key="" Extra="" Comment="" />
<options Name="v1" Comment="VIEW" />
</table_structure>
<table_structure name="v2">
<field Field="c1" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
<options Name="v2" Comment="VIEW" />
</table_structure>
<events>
<event Event="e1" sql_mode="" time_zone="SYSTEM" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` EVENT `e1` ON SCHEDULE EVERY 1 SECOND STARTS '--TIME--' ON COMPLETION NOT PRESERVE ENABLE DO DROP DATABASE BUG52792
]]>
</event>
<event Event="e2" sql_mode="" time_zone="SYSTEM" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` EVENT `e2` ON SCHEDULE EVERY 1 SECOND STARTS '--TIME--' ON COMPLETION NOT PRESERVE ENABLE DO DROP DATABASE BUG52792
]]>
</event>
</events>
<routines>
<routine Function="hello1" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` FUNCTION `hello1`(s CHAR(20)) RETURNS char(50) CHARSET latin1
DETERMINISTIC
RETURN CONCAT('Hello, ' ,s ,'!')
]]>
</routine>
<routine Function="hello2" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` FUNCTION `hello2`(s CHAR(20)) RETURNS char(50) CHARSET latin1
DETERMINISTIC
RETURN CONCAT(']]]]><![CDATA[>, ' , s ,'!')
]]>
</routine>
<routine Procedure="simpleproc1" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` PROCEDURE `simpleproc1`(OUT param1 INT)
BEGIN
SELECT COUNT(*) INTO param1 FROM t1;
END
]]>
</routine>
<routine Procedure="simpleproc2" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` PROCEDURE `simpleproc2`(OUT param1 INT)
BEGIN
SELECT COUNT(*) INTO param1 FROM t2;
END
]]>
</routine>
</routines>
</database>
</mysqldump>
# Dumping BUG52792 database in xml format with comments.
# Running 'replace_regex on timestamp'
<?xml version="1.0"?>
<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<database name="BUG52792">
<!--
-
- Table structure for table `t1`
-
-->
<table_structure name="t1">
<field Field="c1" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
<field Field="c2" Type="varchar(20)" Null="YES" Key="" Extra="" Comment="" />
<options Name="t1" Engine="MyISAM" Version="10" Row_format="Dynamic" Rows="3" Avg_row_length="20" Data_length="60" Max_data_length="281474976710655" Index_length="1024" Data_free="0" Create_time="--TIME--" Update_time="--TIME--" Collation="latin1_swedish_ci" Create_options="" Comment="" />
</table_structure>
<!--
-
- Dumping data for table `t1`
-
-->
<table_data name="t1">
<row>
<field name="c1">1</field>
<field name="c2">aaa</field>
</row>
<row>
<field name="c1">2</field>
<field name="c2">bbb</field>
</row>
<row>
<field name="c1">3</field>
<field name="c2">ccc</field>
</row>
</table_data>
<!--
-
- Table structure for table `t2`
-
-->
<table_structure name="t2">
<field Field="c1" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
<options Name="t2" Engine="MyISAM" Version="10" Row_format="Fixed" Rows="3" Avg_row_length="7" Data_length="21" Max_data_length="1970324836974591" Index_length="1024" Data_free="0" Create_time="--TIME--" Update_time="--TIME--" Collation="latin1_swedish_ci" Create_options="" Comment="" />
</table_structure>
<!--
-
- Dumping data for table `t2`
-
-->
<table_data name="t2">
<row>
<field name="c1">1</field>
</row>
<row>
<field name="c1">2</field>
</row>
<row>
<field name="c1">3</field>
</row>
</table_data>
<triggers name="t2">
<trigger Trigger="trig1" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` TRIGGER trig1 BEFORE INSERT ON t2
FOR EACH ROW BEGIN
INSERT INTO t2 VALUES(1);
END
]]>
</trigger>
<trigger Trigger="trig2" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` TRIGGER trig2 AFTER INSERT ON t2
FOR EACH ROW BEGIN
INSERT INTO t2 VALUES(1, ']]]]><![CDATA[>');
INSERT INTO t2 VALUES(2, '<![CDATA]]]]><![CDATA[>');
INSERT INTO t2 VALUES(3, '<![CDATA[');
INSERT INTO t2 VALUES(4, '< > & \ " _');
END
]]>
</trigger>
</triggers>
<!--
-
- Table structure for table `v1`
-
-->
<table_structure name="v1">
<field Field="c1" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
<field Field="c2" Type="varchar(20)" Null="YES" Key="" Extra="" Comment="" />
<options Name="v1" Comment="VIEW" />
</table_structure>
<!--
-
- Table structure for table `v2`
-
-->
<table_structure name="v2">
<field Field="c1" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
<options Name="v2" Comment="VIEW" />
</table_structure>
<!--
-
- Dumping events for database 'BUG52792'
-
-->
<events>
<event Event="e1" sql_mode="" time_zone="SYSTEM" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` EVENT `e1` ON SCHEDULE EVERY 1 SECOND STARTS '--TIME--' ON COMPLETION NOT PRESERVE ENABLE DO DROP DATABASE BUG52792
]]>
</event>
<event Event="e2" sql_mode="" time_zone="SYSTEM" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` EVENT `e2` ON SCHEDULE EVERY 1 SECOND STARTS '--TIME--' ON COMPLETION NOT PRESERVE ENABLE DO DROP DATABASE BUG52792
]]>
</event>
</events>
<!--
-
- Dumping routines for database 'BUG52792'
-
-->
<routines>
<routine Function="hello1" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` FUNCTION `hello1`(s CHAR(20)) RETURNS char(50) CHARSET latin1
DETERMINISTIC
RETURN CONCAT('Hello, ' ,s ,'!')
]]>
</routine>
<routine Function="hello2" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` FUNCTION `hello2`(s CHAR(20)) RETURNS char(50) CHARSET latin1
DETERMINISTIC
RETURN CONCAT(']]]]><![CDATA[>, ' , s ,'!')
]]>
</routine>
<routine Procedure="simpleproc1" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` PROCEDURE `simpleproc1`(OUT param1 INT)
BEGIN
SELECT COUNT(*) INTO param1 FROM t1;
END
]]>
</routine>
<routine Procedure="simpleproc2" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` PROCEDURE `simpleproc2`(OUT param1 INT)
BEGIN
SELECT COUNT(*) INTO param1 FROM t2;
END
]]>
</routine>
</routines>
</database>
</mysqldump>
# Test to check 'Insufficient privileges' error.
GRANT ALL PRIVILEGES ON BUG52792.* TO user1;
# Running 'replace_regex on timestamp'
<?xml version="1.0"?>
<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<database name="BUG52792">
<table_structure name="t1">
<field Field="c1" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
<field Field="c2" Type="varchar(20)" Null="YES" Key="" Extra="" Comment="" />
<options Name="t1" Engine="MyISAM" Version="10" Row_format="Dynamic" Rows="3" Avg_row_length="20" Data_length="60" Max_data_length="281474976710655" Index_length="1024" Data_free="0" Create_time="--TIME--" Update_time="--TIME--" Collation="latin1_swedish_ci" Create_options="" Comment="" />
</table_structure>
<table_data name="t1">
<row>
<field name="c1">1</field>
<field name="c2">aaa</field>
</row>
<row>
<field name="c1">2</field>
<field name="c2">bbb</field>
</row>
<row>
<field name="c1">3</field>
<field name="c2">ccc</field>
</row>
</table_data>
<table_structure name="t2">
<field Field="c1" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
<options Name="t2" Engine="MyISAM" Version="10" Row_format="Fixed" Rows="3" Avg_row_length="7" Data_length="21" Max_data_length="1970324836974591" Index_length="1024" Data_free="0" Create_time="--TIME--" Update_time="--TIME--" Collation="latin1_swedish_ci" Create_options="" Comment="" />
</table_structure>
<table_data name="t2">
<row>
<field name="c1">1</field>
</row>
<row>
<field name="c1">2</field>
</row>
<row>
<field name="c1">3</field>
</row>
</table_data>
<triggers name="t2">
<trigger Trigger="trig1" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` TRIGGER trig1 BEFORE INSERT ON t2
FOR EACH ROW BEGIN
INSERT INTO t2 VALUES(1);
END
]]>
</trigger>
<trigger Trigger="trig2" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` TRIGGER trig2 AFTER INSERT ON t2
FOR EACH ROW BEGIN
INSERT INTO t2 VALUES(1, ']]]]><![CDATA[>');
INSERT INTO t2 VALUES(2, '<![CDATA]]]]><![CDATA[>');
INSERT INTO t2 VALUES(3, '<![CDATA[');
INSERT INTO t2 VALUES(4, '< > & \ " _');
END
]]>
</trigger>
</triggers>
<table_structure name="v1">
<field Field="c1" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
<field Field="c2" Type="varchar(20)" Null="YES" Key="" Extra="" Comment="" />
<options Name="v1" Comment="VIEW" />
</table_structure>
<table_structure name="v2">
<field Field="c1" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
<options Name="v2" Comment="VIEW" />
</table_structure>
<events>
<event Event="e1" sql_mode="" time_zone="SYSTEM" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` EVENT `e1` ON SCHEDULE EVERY 1 SECOND STARTS '--TIME--' ON COMPLETION NOT PRESERVE ENABLE DO DROP DATABASE BUG52792
]]>
</event>
<event Event="e2" sql_mode="" time_zone="SYSTEM" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` EVENT `e2` ON SCHEDULE EVERY 1 SECOND STARTS '--TIME--' ON COMPLETION NOT PRESERVE ENABLE DO DROP DATABASE BUG52792
]]>
</event>
</events>
<routines>
<!--
- insufficient privileges to SHOW CREATE FUNCTION `hello1`
-->
<!-- - does user1 have permissions on mysql.proc?
-->
DROP USER user1;
DROP DATABASE BUG52792;
# UTF-8
CREATE DATABASE BUG52792;
USE BUG52792;
SET NAMES utf8;
CREATE FUNCTION `straße` ( c1 CHAR(20))
RETURNS CHAR(50) DETERMINISTIC
RETURN CONCAT(']]>, ', s, '!');
<?xml version="1.0"?>
<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<database name="BUG52792">
<routines>
<routine Function="straße" sql_mode="" character_set_client="utf8" collation_connection="utf8_general_ci" Database_Collation="latin1_swedish_ci">
<![CDATA[
CREATE DEFINER=`root`@`localhost` FUNCTION `straße`( c1 CHAR(20)) RETURNS char(50) CHARSET latin1
DETERMINISTIC
RETURN CONCAT(']]]]><![CDATA[>, ', s, '!')
]]>
</routine>
</routines>
</database>
</mysqldump>
DROP DATABASE BUG52792;
USE test;
#
# End of 5.1 tests
# End of 5.1 tests
#
#
#
#
...
...
mysql-test/t/mysqldump.test
View file @
d8af27ef
...
@@ -2201,6 +2201,118 @@ DROP DATABASE `test-database`;
...
@@ -2201,6 +2201,118 @@ DROP DATABASE `test-database`;
# Switching back to test database.
# Switching back to test database.
USE
test
;
USE
test
;
--
echo
#
--
echo
# BUG#11760384 : 52792: mysqldump in XML mode does not dump routines.
--
echo
#
CREATE
DATABASE
BUG52792
;
USE
BUG52792
;
CREATE
TABLE
t1
(
c1
INT
,
c2
VARCHAR
(
20
));
CREATE
TABLE
t2
(
c1
INT
);
INSERT
INTO
t1
VALUES
(
1
,
'aaa'
),
(
2
,
'bbb'
),
(
3
,
'ccc'
);
INSERT
INTO
t2
VALUES
(
1
),(
2
),(
3
);
--
echo
# Stored Procedures.
DELIMITER
//;
CREATE
PROCEDURE
simpleproc1
(
OUT
param1
INT
)
BEGIN
SELECT
COUNT
(
*
)
INTO
param1
FROM
t1
;
END
//
DELIMITER
;
//
DELIMITER
//;
CREATE
PROCEDURE
simpleproc2
(
OUT
param1
INT
)
BEGIN
SELECT
COUNT
(
*
)
INTO
param1
FROM
t2
;
END
//
DELIMITER
;
//
--
echo
# Events.
CREATE
EVENT
e1
ON
SCHEDULE
EVERY
1
SECOND
DO
DROP
DATABASE
BUG52792
;
CREATE
EVENT
e2
ON
SCHEDULE
EVERY
1
SECOND
DO
DROP
DATABASE
BUG52792
;
--
echo
# Functions.
CREATE
FUNCTION
`
hello1
` (s CHAR(20))
RETURNS CHAR(50) DETERMINISTIC
RETURN CONCAT('Hello, ' ,s ,'!');
CREATE FUNCTION `
hello2
` (s CHAR(20))
RETURNS CHAR(50) DETERMINISTIC
RETURN CONCAT(']]>, ' , s ,'!');
--echo # Triggers.
DELIMITER |;
CREATE TRIGGER trig1 BEFORE INSERT ON t2
FOR EACH ROW BEGIN
INSERT INTO t2 VALUES(1);
END;
|
DELIMITER ;|
DELIMITER |;
CREATE TRIGGER trig2 AFTER INSERT ON t2
FOR EACH ROW BEGIN
INSERT INTO t2 VALUES(1, ']]>');
INSERT INTO t2 VALUES(2, '<![CDATA]]>');
INSERT INTO t2 VALUES(3, '<![CDATA[');
INSERT INTO t2 VALUES(4, '< > & \ " _');
END;
|
DELIMITER ;|
--echo # Views
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE VIEW v2 AS SELECT * FROM t2;
--echo
--echo # Dumping BUG52792 database in xml format.
--echo
--echo # Running 'replace_regex on timestamp'
--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/--TIME--/
--exec $MYSQL_DUMP --user=root --compact -R -E --triggers -X BUG52792
--echo
--echo # Dumping BUG52792 database in xml format with comments.
--echo
--echo # Running 'replace_regex on timestamp'
--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/--TIME--/
--exec $MYSQL_DUMP --comments --user=root -R -E --triggers -X BUG52792
--echo
--echo # Test to check 'Insufficient privileges' error.
--echo
GRANT ALL PRIVILEGES ON BUG52792.* TO user1;
connect (conn_1, localhost, user1, , BUG52792, $MASTER_MYPORT, $MASTER_MYSOCK);
connection conn_1;
--echo # Running 'replace_regex on timestamp'
--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/--TIME--/
--error 2
--exec $MYSQL_DUMP --user=user1 -R -E --triggers -X BUG52792
connection default;
disconnect conn_1;
DROP USER user1;
DROP DATABASE BUG52792;
--echo # UTF-8
CREATE DATABASE BUG52792;
USE BUG52792;
SET NAMES utf8;
CREATE FUNCTION `
straße
`
(
c1
CHAR
(
20
))
RETURNS
CHAR
(
50
)
DETERMINISTIC
RETURN
CONCAT
(
']]>, '
,
s
,
'!'
);
--
exec
$MYSQL_DUMP
--
character
-
sets
-
dir
=
$CHARSETSDIR
--
skip
-
comments
--
default
-
character
-
set
=
utf8
--
compatible
=
mysql323
-
R
-
X
BUG52792
DROP
DATABASE
BUG52792
;
USE
test
;
--
echo
#
--
echo
#
--
echo
# End of 5.1 tests
--
echo
# End of 5.1 tests
--
echo
#
--
echo
#
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment