Commit 04f9561a authored by unknown's avatar unknown

Fix crash in mysqldump -c triggered by tables with a large number of long

field names. (Bug #10286)


client/mysqldump.c:
  Use a DYNAMIC_STRING for the 'INSERT ...' pattern so we can handle
  an arbitrary number of fields. Also rename the internal cFlag to 
  opt_complete_insert so it is clear what it does.
mysql-test/t/mysqldump.test:
  Add regression test for 10286
mysql-test/r/mysqldump.result:
  Update results
parent 04b938c9
......@@ -75,7 +75,7 @@ static ulong find_set(TYPELIB *lib, const char *x, uint length,
char **err_pos, uint *err_len);
static char *field_escape(char *to,const char *from,uint length);
static my_bool verbose=0,tFlag=0,cFlag=0,dFlag=0,quick= 1, extended_insert= 1,
static my_bool verbose=0,tFlag=0,dFlag=0,quick= 1, extended_insert= 1,
lock_tables=1,ignore_errors=0,flush_logs=0,
opt_drop=1,opt_keywords=0,opt_lock=1,opt_compress=0,
opt_delayed=0,create_options=1,opt_quoted=0,opt_databases=0,
......@@ -83,10 +83,12 @@ static my_bool verbose=0,tFlag=0,cFlag=0,dFlag=0,quick= 1, extended_insert= 1,
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_hex_blob=0, opt_order_by_primary=0, opt_complete_insert= 0;
static ulong opt_max_allowed_packet, opt_net_buffer_length;
static MYSQL mysql_connection,*sock=0;
static char insert_pat[12 * 1024],*opt_password=0,*current_user=0,
static my_bool insert_pat_inited=0;
static DYNAMIC_STRING insert_pat;
static char *opt_password=0,*current_user=0,
*current_host=0,*path=0,*fields_terminated=0,
*lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0,
*where=0, *order_by=0,
......@@ -178,8 +180,9 @@ static struct my_option my_long_options[] =
"Give less verbose output (useful for debugging). Disables structure comments and header/footer constructs. Enables options --skip-add-drop-table --no-set-names --skip-disable-keys --skip-add-locks",
(gptr*) &opt_compact, (gptr*) &opt_compact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
{"complete-insert", 'c', "Use complete insert statements.", (gptr*) &cFlag,
(gptr*) &cFlag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"complete-insert", 'c', "Use complete insert statements.",
(gptr*) &opt_complete_insert, (gptr*) &opt_complete_insert, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
{"compress", 'C', "Use compression in server/client protocol.",
(gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0},
......@@ -1082,7 +1085,7 @@ static void print_xml_row(FILE *xml_file, const char *row_name,
/*
getStructure -- retrievs database structure, prints out corresponding
getTableStructure -- retrievs database structure, prints out corresponding
CREATE statement and fills out insert_pat.
RETURN
......@@ -1095,23 +1098,31 @@ static uint getTableStructure(char *table, char* db)
MYSQL_ROW row;
my_bool init=0;
uint numFields;
char *strpos, *result_table, *opt_quoted_table;
char *result_table, *opt_quoted_table;
const char *delayed;
char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3];
char table_buff2[NAME_LEN*2+3];
char query_buff[512];
FILE *sql_file = md_result_file;
DBUG_ENTER("getTableStructure");
if (!insert_pat_inited)
{
insert_pat_inited= init_dynamic_string(&insert_pat, "", 1024, 1024);
}
else
dynstr_set(&insert_pat, "");
delayed= opt_delayed ? " DELAYED " : "";
if (verbose)
fprintf(stderr, "-- Retrieving table structure for table %s...\n", table);
my_snprintf(insert_pat, sizeof(insert_pat),
my_snprintf(query_buff, sizeof(query_buff),
"SET OPTION SQL_QUOTE_SHOW_CREATE=%d",
(opt_quoted || opt_keywords));
if (!create_options)
strmov(strend(insert_pat), "/*!40102 ,SQL_MODE=concat(@@sql_mode, _utf8 ',NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS') */");
strmov(strend(query_buff), "/*!40102 ,SQL_MODE=concat(@@sql_mode, _utf8 ',NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS') */");
result_table= quote_name(table, table_buff, 1);
opt_quoted_table= quote_name(table, table_buff2, 0);
......@@ -1119,7 +1130,7 @@ static uint getTableStructure(char *table, char* db)
if (opt_order_by_primary)
order_by = primary_key_fields(opt_quoted_table);
if (!opt_xml && !mysql_query_with_error_report(sock, 0, insert_pat))
if (!opt_xml && !mysql_query_with_error_report(sock, 0, query_buff))
{
/* using SHOW CREATE statement */
if (!tFlag)
......@@ -1165,9 +1176,9 @@ static uint getTableStructure(char *table, char* db)
check_io(sql_file);
mysql_free_result(tableRes);
}
my_snprintf(insert_pat, sizeof(insert_pat), "show fields from %s",
my_snprintf(query_buff, sizeof(query_buff), "show fields from %s",
result_table);
if (mysql_query_with_error_report(sock, &tableRes, insert_pat))
if (mysql_query_with_error_report(sock, &tableRes, query_buff))
{
if (path)
my_fclose(sql_file, MYF(MY_WME));
......@@ -1175,28 +1186,32 @@ static uint getTableStructure(char *table, char* db)
DBUG_RETURN(0);
}
if (cFlag)
my_snprintf(insert_pat, sizeof(insert_pat), "INSERT %sINTO %s (",
delayed, opt_quoted_table);
dynstr_append_mem(&insert_pat, "INSERT ", 7);
dynstr_append(&insert_pat, delayed);
dynstr_append_mem(&insert_pat, "INTO ", 5);
dynstr_append(&insert_pat, opt_quoted_table);
if (opt_complete_insert)
{
dynstr_append_mem(&insert_pat, " (", 2);
}
else
{
my_snprintf(insert_pat, sizeof(insert_pat), "INSERT %sINTO %s VALUES ",
delayed, opt_quoted_table);
dynstr_append_mem(&insert_pat, " VALUES ", 8);
if (!extended_insert)
strcat(insert_pat,"(");
dynstr_append_mem(&insert_pat, "(", 1);
}
strpos=strend(insert_pat);
while ((row=mysql_fetch_row(tableRes)))
{
if (init)
{
if (cFlag)
strpos=strmov(strpos,", ");
if (opt_complete_insert)
dynstr_append_mem(&insert_pat, ", ", 2);
}
init=1;
if (cFlag)
strpos=strmov(strpos,quote_name(row[SHOW_FIELDNAME], name_buff, 0));
if (opt_complete_insert)
dynstr_append(&insert_pat,
quote_name(row[SHOW_FIELDNAME], name_buff, 0));
}
numFields = (uint) mysql_num_rows(tableRes);
mysql_free_result(tableRes);
......@@ -1208,9 +1223,9 @@ static uint getTableStructure(char *table, char* db)
"%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n",
my_progname, mysql_error(sock));
my_snprintf(insert_pat, sizeof(insert_pat), "show fields from %s",
my_snprintf(query_buff, sizeof(query_buff), "show fields from %s",
result_table);
if (mysql_query_with_error_report(sock, &tableRes, insert_pat))
if (mysql_query_with_error_report(sock, &tableRes, query_buff))
{
safe_exit(EX_MYSQLERR);
DBUG_RETURN(0);
......@@ -1243,18 +1258,22 @@ static uint getTableStructure(char *table, char* db)
print_xml_tag1(sql_file, "\t", "table_structure name=", table, "\n");
check_io(sql_file);
}
if (cFlag)
my_snprintf(insert_pat, sizeof(insert_pat), "INSERT %sINTO %s (",
delayed, result_table);
dynstr_append_mem(&insert_pat, "INSERT ", 7);
dynstr_append(&insert_pat, delayed);
dynstr_append_mem(&insert_pat, "INTO ", 5);
dynstr_append(&insert_pat, result_table);
if (opt_complete_insert)
{
dynstr_append_mem(&insert_pat, " (", 2);
}
else
{
my_snprintf(insert_pat, sizeof(insert_pat), "INSERT %sINTO %s VALUES ",
delayed, result_table);
dynstr_append_mem(&insert_pat, " VALUES ", 8);
if (!extended_insert)
strcat(insert_pat,"(");
dynstr_append_mem(&insert_pat, "(", 1);
}
strpos=strend(insert_pat);
while ((row=mysql_fetch_row(tableRes)))
{
ulong *lengths=mysql_fetch_lengths(tableRes);
......@@ -1265,12 +1284,13 @@ static uint getTableStructure(char *table, char* db)
fputs(",\n",sql_file);
check_io(sql_file);
}
if (cFlag)
strpos=strmov(strpos,", ");
if (opt_complete_insert)
dynstr_append_mem(&insert_pat, ", ", 2);
}
init=1;
if (cFlag)
strpos=strmov(strpos,quote_name(row[SHOW_FIELDNAME], name_buff, 0));
if (opt_complete_insert)
dynstr_append(&insert_pat,
quote_name(row[SHOW_FIELDNAME], name_buff, 0));
if (!tFlag)
{
if (opt_xml)
......@@ -1423,11 +1443,11 @@ static uint getTableStructure(char *table, char* db)
check_io(sql_file);
}
}
if (cFlag)
if (opt_complete_insert)
{
strpos=strmov(strpos,") VALUES ");
dynstr_append_mem(&insert_pat, ") VALUES ", 9);
if (!extended_insert)
strpos=strmov(strpos,"(");
dynstr_append_mem(&insert_pat, "(", 1);
}
if (sql_file != md_result_file)
{
......@@ -1650,7 +1670,7 @@ static void dumpTable(uint numFields, char *table)
total_length= opt_net_buffer_length; /* Force row break */
row_break=0;
rownr=0;
init_length=(uint) strlen(insert_pat)+4;
init_length=(uint) insert_pat.length+4;
if (opt_xml)
print_xml_tag1(md_result_file, "\t", "table_data name=", table, "\n");
......@@ -1667,7 +1687,7 @@ static void dumpTable(uint numFields, char *table)
rownr++;
if (!extended_insert && !opt_xml)
{
fputs(insert_pat,md_result_file);
fputs(insert_pat.str,md_result_file);
check_io(md_result_file);
}
mysql_field_seek(res,0);
......@@ -1864,7 +1884,7 @@ static void dumpTable(uint numFields, char *table)
fputs(";\n", md_result_file);
row_break=1; /* This is first row */
fputs(insert_pat,md_result_file);
fputs(insert_pat.str,md_result_file);
fputs(extended_row.str,md_result_file);
total_length = row_length+init_length;
}
......@@ -2557,6 +2577,8 @@ err:
my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
if (extended_insert)
dynstr_free(&extended_row);
if (insert_pat_inited)
dynstr_free(&insert_pat);
my_end(0);
return(first_error);
} /* main */
This diff is collapsed.
This diff is collapsed.
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