--- mysql-5.0.75.orig/client/mysqldump.c 2008-12-18 09:19:31.000000000 -0800 +++ mysql-5.0.75.superdump/client/mysqldump.c 2009-01-16 13:01:03.000000000 -0800 @@ -93,7 +93,10 @@ opt_autocommit=0,opt_disable_keys=1,opt_xml=0, opt_delete_master_logs=0, tty_password=0, opt_single_transaction=0, opt_comments= 0, opt_compact= 0, - opt_hex_blob=0, opt_order_by_primary=0, opt_ignore=0, + opt_hex_blob=0, + opt_order_by_primary=0, + opt_order_by_consistent=0, + opt_ignore=0, opt_complete_insert= 0, opt_drop_database= 0, opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1; static ulong opt_max_allowed_packet, opt_net_buffer_length; @@ -353,6 +356,9 @@ {"opt", OPT_OPTIMIZE, "Same as --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys. Enabled by default, disable with --skip-opt.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"order-by-consistent", OPT_ORDER_BY_CONSISTENT, + "Sorts each table's rows by primary key, or first unique key, if such a key exists, or by all columns if it does not exist.", + (gptr*) &opt_order_by_consistent, (gptr*) &opt_order_by_consistent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"order-by-primary", OPT_ORDER_BY_PRIMARY, "Sorts each table's rows by primary key, or first unique key, if such a key exists. Useful when dumping a MyISAM table to be loaded into an InnoDB table, but will make the dump itself take considerably longer.", (gptr*) &opt_order_by_primary, (gptr*) &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -469,6 +475,7 @@ static int dump_all_databases(); static char *quote_name(const char *name, char *buff, my_bool force); char check_if_ignore_table(const char *table_name, char *table_type); +static char *all_fields(const char *table_name); static char *primary_key_fields(const char *table_name); static my_bool get_view_structure(char *table, char* db); static my_bool dump_all_views_in_db(char *database); @@ -578,6 +585,18 @@ sql_file); fprintf(sql_file, "-- Server version\t%s\n", mysql_get_server_info(&mysql_connection)); + if (opt_comments) + { + if (opt_dump_date) + { + char time_str[20]; + get_date(time_str, GETDATE_DATE_TIME|GETDATE_FIXEDLENGTH, 0); + fprintf(sql_file, "-- Dump started at %s\n", + time_str); + } + else + fprintf(sql_file, "-- Dump completed\n"); + } } if (opt_set_charset) fprintf(sql_file, @@ -641,8 +660,8 @@ if (opt_dump_date) { char time_str[20]; - get_date(time_str, GETDATE_DATE_TIME, 0); - fprintf(sql_file, "-- Dump completed on %s\n", + get_date(time_str, GETDATE_DATE_TIME|GETDATE_FIXEDLENGTH, 0); + fprintf(sql_file, "-- Dump completed at %s\n", time_str); } else @@ -1712,8 +1731,11 @@ result_table= quote_name(table, table_buff, 1); opt_quoted_table= quote_name(table, table_buff2, 0); - if (opt_order_by_primary) + if (opt_order_by_primary || opt_order_by_consistent) order_by= primary_key_fields(result_table); + + if (!order_by && opt_order_by_consistent) + order_by= all_fields(result_table); if (!opt_xml && !mysql_query_with_error_report(mysql, 0, query_buff)) { @@ -1894,7 +1916,7 @@ } else { - dynstr_append_checked(&insert_pat, " VALUES "); + dynstr_append_checked(&insert_pat, "\nVALUES\n"); if (!extended_insert) dynstr_append_checked(&insert_pat, "("); } @@ -2138,7 +2160,7 @@ } if (complete_insert) { - dynstr_append_checked(&insert_pat, ") VALUES "); + dynstr_append_checked(&insert_pat, ")\nVALUES\n"); if (!extended_insert) dynstr_append_checked(&insert_pat, "("); } @@ -2746,7 +2768,7 @@ if (total_length + row_length < opt_net_buffer_length) { total_length+= row_length; - fputc(',',md_result_file); /* Always row break */ + fputs(",\n",md_result_file); /* Always row break */ fputs(extended_row.str,md_result_file); } else @@ -2763,11 +2785,14 @@ } else if (!opt_xml) { - fputs(");\n", md_result_file); + fputs(")\n;\n", md_result_file); check_io(md_result_file); } } + if(rownr == 0 && !opt_xml) + fprintf(md_result_file, "-- No data in table %s\n\n", result_table); + /* XML - close table tag and supress regular output */ if (opt_xml) fputs("\t\n", md_result_file); @@ -3568,6 +3593,84 @@ DBUG_RETURN(result); } +/* + Get string of comma-separated field names + + SYNOPSIS + char *all_fields(const char *table_name) + RETURNS pointer to allocated buffer (must be freed by caller) + table_name quoted table name + + DESCRIPTION + Use SHOW COLUMNS FROM table_name, allocate a buffer to hold the + field names, and then build that string and return the pointer + to that buffer. +*/ + +static char *all_fields(const char *table_name) +{ + MYSQL_RES *res= NULL; + MYSQL_ROW row; + /* SHOW KEYS FROM + table name * 2 (escaped) + 2 quotes + \0 */ + char show_keys_buff[15 + NAME_LEN * 2 + 3]; + uint result_length= 0; + char *result= 0; + char buff[NAME_LEN * 2 + 3]; + char *quoted_field; + + my_snprintf(show_keys_buff, sizeof(show_keys_buff), + "SHOW COLUMNS FROM %s", table_name); + if (mysql_query(mysql, show_keys_buff) || + !(res= mysql_store_result(mysql))) + { + fprintf(stderr, "Warning: Couldn't read columns from table %s;" + " records are NOT sorted (%s)\n", + table_name, mysql_error(mysql)); + /* Don't exit, because it's better to print out unsorted records */ + goto cleanup; + } + + /* + * Figure out the length of the ORDER BY clause result. + * Note that SHOW KEYS is ordered: a PRIMARY key is always the first + * row, and UNIQUE keys come before others. So we only need to check + * the first key, not all keys. + */ + while ((row= mysql_fetch_row(res))) + { + quoted_field= quote_name(row[0], buff, 0); + result_length+= strlen(quoted_field) + 1; /* + 1 for ',' or \0 */ + } + + /* Build the ORDER BY clause result */ + if (result_length) + { + char *end; + /* result (terminating \0 is already in result_length) */ + result= my_malloc(result_length + 10, MYF(MY_WME)); + if (!result) + { + fprintf(stderr, "Error: Not enough memory to store ORDER BY clause\n"); + goto cleanup; + } + + mysql_data_seek(res, 0); + row= mysql_fetch_row(res); + quoted_field= quote_name(row[0], buff, 0); + end= strmov(result, quoted_field); + while ((row= mysql_fetch_row(res))) + { + quoted_field= quote_name(row[0], buff, 0); + end= strxmov(end, ",", quoted_field, NullS); + } + } + +cleanup: + if (res) + mysql_free_result(res); + + return result; +} /* Get string of comma-separated primary key field names