summaryrefslogtreecommitdiff
path: root/client/mysqldump.c
diff options
context:
space:
mode:
authorunknown <iggy@rolltop.ignatz42.dyndns.org>2006-10-18 18:43:51 -0400
committerunknown <iggy@rolltop.ignatz42.dyndns.org>2006-10-18 18:43:51 -0400
commit016a7d4c636de66246f443eade4a76ac75b52173 (patch)
tree12731c834ca5c11c45bad86b5b1e1334e50f3cca /client/mysqldump.c
parentc317c2d224c8d7753cf7acd238968a9a8584dbc4 (diff)
downloadmariadb-git-016a7d4c636de66246f443eade4a76ac75b52173.tar.gz
Bug#19745: mysqldump --xml produces invalid xml
The mysqldump command with both the --xml and --hex-blob options will output blob data encoded as hexBinary. The proper XML datatype is xs:hexBinary. The correct XML datatype is specified be setting the xsi_type attribute equal to xs:hexBinary for each encoded element. client/mysqldump.c: Bug#19745: mysqldump --xml produces invalid xml - Moved hex-blob code to it's own function. - Rewrote print_xml_tag function to accept zero or more attribute/value pair(s) which are appended to a separate tag name. - --xml option respects the --hex-blob option by ouputting blob data in hex encoded format. Each hex encoded field tag will also contain an xsi:type attribute with an xs:hexBinary value. - --extended-insert and --xml are mutually exclusive. Otherwise, the xml file will contain INSERT commands. - Minor comment cleanup. mysql-test/r/mysqldump.result: Bug#19745: mysqldump --xml produces invalid xml -Added results. mysql-test/t/mysqldump.test: Bug#19745: mysqldump --xml produces invalid xml -Added test.
Diffstat (limited to 'client/mysqldump.c')
-rw-r--r--client/mysqldump.c134
1 files changed, 98 insertions, 36 deletions
diff --git a/client/mysqldump.c b/client/mysqldump.c
index b3a209c6086..5929cde6af6 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -45,6 +45,7 @@
#include <m_string.h>
#include <m_ctype.h>
#include <hash.h>
+#include <stdarg.h>
#include "client_priv.h"
#include "mysql.h"
@@ -523,6 +524,8 @@ static void write_header(FILE *sql_file, char *db_name)
if (opt_xml)
{
fputs("<?xml version=\"1.0\"?>\n", sql_file);
+ /* Schema reference. Allows use of xsi:nil for NULL values and
+ xsi:type to define an element's data type. */
fputs("<mysqldump ", sql_file);
fputs("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"",
sql_file);
@@ -1123,7 +1126,7 @@ static char *quote_for_like(const char *name, char *buff)
SYNOPSIS
print_quoted_xml()
- output - output file
+ xml_file - output file
str - string to print
len - its length
@@ -1160,34 +1163,63 @@ static void print_quoted_xml(FILE *xml_file, const char *str, ulong len)
/*
- Print xml tag with one attribute.
+ Print xml tag. Optionally add attribute(s).
SYNOPSIS
- print_xml_tag1()
- xml_file - output file
- sbeg - line beginning
- stag_atr - tag and attribute
- sval - value of attribute
- send - line ending
+ print_xml_tag(xml_file, sbeg, send, tag_name, first_attribute_name,
+ ..., attribute_name_n, attribute_value_n, NullS)
+ xml_file - output file
+ sbeg - line beginning
+ send - line ending
+ tag_name - XML tag name.
+ first_attribute_name - tag and first attribute
+ first_attribute_value - (Implied) value of first attribute
+ attribute_name_n - attribute n
+ attribute_value_n - value of attribute n
DESCRIPTION
- Print tag with one attribute to the xml_file. Format is:
- sbeg<stag_atr="sval">send
+ Print XML tag with any number of attribute="value" pairs to the xml_file.
+
+ Format is:
+ sbeg<tag_name first_attribute_name="first_attribute_value" ...
+ attribute_name_n="attribute_value_n">send
NOTE
- sval MUST be a NULL terminated string.
- sval string will be qouted before output.
+ Additional arguments must be present in attribute/value pairs.
+ The last argument should be the null character pointer.
+ All attribute_value arguments MUST be NULL terminated strings.
+ All attribute_value arguments will be quoted before output.
*/
-static void print_xml_tag1(FILE * xml_file, const char* sbeg,
- const char* stag_atr, const char* sval,
- const char* send)
+static void print_xml_tag(FILE * xml_file, const char* sbeg, const char* send,
+ const char* tag_name,
+ const char* first_attribute_name, ...)
{
+ va_list arg_list;
+ char *attribute_name, *attribute_value;
+
fputs(sbeg, xml_file);
- fputs("<", xml_file);
- fputs(stag_atr, xml_file);
- fputs("\"", xml_file);
- print_quoted_xml(xml_file, sval, strlen(sval));
- fputs("\">", xml_file);
+ fputc('<', xml_file);
+ fputs(tag_name, xml_file);
+
+ va_start(arg_list, first_attribute_name);
+ attribute_name= first_attribute_name;
+ while (attribute_name != NullS)
+ {
+ attribute_value= va_arg(arg_list, char *);
+ DBUG_ASSERT(attribute_value != NullS);
+
+ fputc(' ', xml_file);
+ fputs(attribute_name, xml_file);
+ fputc('\"', xml_file);
+
+ print_quoted_xml(xml_file, attribute_value, strlen(attribute_value));
+ fputc('\"', xml_file);
+
+ attribute_name= va_arg(arg_list, char *);
+ }
+ va_end(arg_list);
+
+ fputc('>', xml_file);
fputs(send, xml_file);
check_io(xml_file);
}
@@ -1271,6 +1303,28 @@ static void print_xml_row(FILE *xml_file, const char *row_name,
}
/*
+ Print hex value for blob data.
+
+ SYNOPSIS
+ print_blob_as_hex()
+ output_file - output file
+ str - string to print
+ len - its length
+
+ DESCRIPTION
+ Print hex value for blob data.
+*/
+
+static void print_blob_as_hex(FILE *output_file, const char *str, ulong len)
+{
+ /* sakaik got the idea to to provide blob's in hex notation. */
+ char *ptr= str, *end= ptr + len;
+ for (; ptr < end ; ptr++)
+ fprintf(output_file, "%02X", *((uchar *)ptr));
+ check_io(output_file);
+}
+
+/*
dump_routines_for_db
-- retrievs list of routines for a given db, and prints out
the CREATE PROCEDURE definition into the output (the dump).
@@ -1714,7 +1768,8 @@ static uint get_table_structure(char *table, char *db, char *table_type,
if (!opt_xml)
fprintf(sql_file, "CREATE TABLE %s (\n", result_table);
else
- print_xml_tag1(sql_file, "\t", "table_structure name=", table, "\n");
+ print_xml_tag(sql_file, "\t", "\n", "table_structure", "name=", table,
+ NullS);
check_io(sql_file);
}
@@ -2283,8 +2338,8 @@ static void dump_table(char *table, char *db)
rownr=0;
init_length=(uint) insert_pat.length+4;
if (opt_xml)
- print_xml_tag1(md_result_file, "\t", "table_data name=", table, "\n");
-
+ print_xml_tag(md_result_file, "\t", "\n", "table_data", "name=", table,
+ NullS);
if (opt_autocommit)
{
fprintf(md_result_file, "set autocommit=0;\n");
@@ -2338,7 +2393,7 @@ static void dump_table(char *table, char *db)
field->type == MYSQL_TYPE_LONG_BLOB ||
field->type == MYSQL_TYPE_MEDIUM_BLOB ||
field->type == MYSQL_TYPE_TINY_BLOB)) ? 1 : 0;
- if (extended_insert)
+ if (extended_insert && !opt_xml)
{
if (i == 0)
dynstr_set(&extended_row,"(");
@@ -2427,18 +2482,25 @@ static void dump_table(char *table, char *db)
{
if (opt_xml)
{
- print_xml_tag1(md_result_file, "\t\t", "field name=",
- field->name, "");
- print_quoted_xml(md_result_file, row[i], length);
+ if (opt_hex_blob && is_blob && length)
+ {
+ /* Define xsi:type="xs:hexBinary" for hex encoded data */
+ print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
+ field->name, "xsi:type=", "xs:hexBinary", NullS);
+ print_blob_as_hex(md_result_file, row[i], length);
+ }
+ else
+ {
+ print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
+ field->name, NullS);
+ print_quoted_xml(md_result_file, row[i], length);
+ }
fputs("</field>\n", md_result_file);
}
else if (opt_hex_blob && is_blob && length)
{
- /* sakaik got the idea to to provide blob's in hex notation. */
- char *ptr= row[i], *end= ptr + length;
fputs("0x", md_result_file);
- for (; ptr < end ; ptr++)
- fprintf(md_result_file, "%02X", *((uchar *)ptr));
+ print_blob_as_hex(md_result_file, row[i], length);
}
else
unescape(md_result_file, row[i], length);
@@ -2449,8 +2511,8 @@ static void dump_table(char *table, char *db)
char *ptr= row[i];
if (opt_xml)
{
- print_xml_tag1(md_result_file, "\t\t", "field name=",
- field->name, "");
+ print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
+ field->name, NullS);
fputs(!my_isalpha(charset_info, *ptr) ? ptr: "NULL",
md_result_file);
fputs("</field>\n", md_result_file);
@@ -2781,7 +2843,7 @@ static int dump_all_tables_in_db(char *database)
if (init_dumping(database, init_dumping_tables))
return 1;
if (opt_xml)
- print_xml_tag1(md_result_file, "", "database name=", database, "\n");
+ print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NullS);
if (lock_tables)
{
DYNAMIC_STRING query;
@@ -2858,7 +2920,7 @@ static my_bool dump_all_views_in_db(char *database)
if (init_dumping(database, init_dumping_views))
return 1;
if (opt_xml)
- print_xml_tag1(md_result_file, "", "database name=", database, "\n");
+ print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NullS);
if (lock_tables)
{
DYNAMIC_STRING query;
@@ -2997,7 +3059,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
/* We shall countinue here, if --force was given */
}
if (opt_xml)
- print_xml_tag1(md_result_file, "", "database name=", db, "\n");
+ print_xml_tag(md_result_file, "", "\n", "database", "name=", db, NullS);
/* Dump each selected table */
for (pos= dump_tables; pos < end; pos++)