From 016a7d4c636de66246f443eade4a76ac75b52173 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Oct 2006 18:43:51 -0400 Subject: [PATCH 1/2] 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. --- client/mysqldump.c | 134 +++++++++++++++++++++++++--------- mysql-test/r/mysqldump.result | 22 ++++++ mysql-test/t/mysqldump.test | 15 ++++ 3 files changed, 135 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 #include #include +#include #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("\n", sql_file); + /* Schema reference. Allows use of xsi:nil for NULL values and + xsi:type to define an element's data type. */ fputs("send + Print XML tag with any number of attribute="value" pairs to the xml_file. + + Format is: + sbegsend 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); } @@ -1270,6 +1302,28 @@ static void print_xml_row(FILE *xml_file, const char *row_name, check_io(xml_file); } +/* + 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 @@ -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("\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("\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++) diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index ee50fc42203..54583febbc8 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -3196,5 +3196,27 @@ UNLOCK TABLES; DROP TABLE `t1`; # +# Bug #19745: mysqldump --xml produces invalid xml +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (f1 int(10), data MEDIUMBLOB); +INSERT INTO t1 VALUES(1,0xff00fef0); + + + + + + + + + + 1 + FF00FEF0 + + + + +DROP TABLE t1; +# # End of 5.0 tests # diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 6dfb24c2e75..72aad395ec0 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -1412,6 +1412,21 @@ insert into t1 values (0815, 4711, 2006); DROP TABLE `t1`; --enable_warnings +--echo # +--echo # Bug #19745: mysqldump --xml produces invalid xml +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (f1 int(10), data MEDIUMBLOB); +INSERT INTO t1 VALUES(1,0xff00fef0); + +--exec $MYSQL_DUMP --xml --hex-blob --skip-create-options test t1 + +DROP TABLE t1; + --echo # --echo # End of 5.0 tests --echo # From ca817b49cf00eebfb95e7765714a1a0db8913433 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Oct 2006 11:37:07 +0200 Subject: [PATCH 2/2] Fix for bug#23379 "wrong time value in SHOW PROCESSLIST" The value taken to be shown in SHOW PROCESSLIST is not initialized when THD is created and will be random for unauthenticated connections. To the documentor: Random value, instead of NULL, was shown, in SHOW PROCESSLIST for still non-authenticated connections. sql/sql_class.cc: Initialize time_after_lock. It is used from SHOW PROCESSLIST's code. If not initialized random value is shown for connected but still unauthenticated clients in the column Time. --- sql/sql_class.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index bd292814bfa..fc9597cba87 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -181,6 +181,7 @@ THD::THD() // Must be reset to handle error with THD's created for init of mysqld lex->current_select= 0; start_time=(time_t) 0; + time_after_lock=(time_t) 0; current_linfo = 0; slave_thread = 0; variables.pseudo_thread_id= 0;