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, ...@@ -75,7 +75,7 @@ static ulong find_set(TYPELIB *lib, const char *x, uint length,
char **err_pos, uint *err_len); char **err_pos, uint *err_len);
static char *field_escape(char *to,const char *from,uint length); 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, lock_tables=1,ignore_errors=0,flush_logs=0,
opt_drop=1,opt_keywords=0,opt_lock=1,opt_compress=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, 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, ...@@ -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_autocommit=0,opt_disable_keys=1,opt_xml=0,
opt_delete_master_logs=0, tty_password=0, opt_delete_master_logs=0, tty_password=0,
opt_single_transaction=0, opt_comments= 0, opt_compact= 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 ulong opt_max_allowed_packet, opt_net_buffer_length;
static MYSQL mysql_connection,*sock=0; 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, *current_host=0,*path=0,*fields_terminated=0,
*lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0, *lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0,
*where=0, *order_by=0, *where=0, *order_by=0,
...@@ -178,8 +180,9 @@ static struct my_option my_long_options[] = ...@@ -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", "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, (gptr*) &opt_compact, (gptr*) &opt_compact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0}, 0, 0},
{"complete-insert", 'c', "Use complete insert statements.", (gptr*) &cFlag, {"complete-insert", 'c', "Use complete insert statements.",
(gptr*) &cFlag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, (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.", {"compress", 'C', "Use compression in server/client protocol.",
(gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0}, 0, 0, 0},
...@@ -1082,7 +1085,7 @@ static void print_xml_row(FILE *xml_file, const char *row_name, ...@@ -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. CREATE statement and fills out insert_pat.
RETURN RETURN
...@@ -1095,23 +1098,31 @@ static uint getTableStructure(char *table, char* db) ...@@ -1095,23 +1098,31 @@ static uint getTableStructure(char *table, char* db)
MYSQL_ROW row; MYSQL_ROW row;
my_bool init=0; my_bool init=0;
uint numFields; uint numFields;
char *strpos, *result_table, *opt_quoted_table; char *result_table, *opt_quoted_table;
const char *delayed; const char *delayed;
char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3]; char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3];
char table_buff2[NAME_LEN*2+3]; char table_buff2[NAME_LEN*2+3];
char query_buff[512];
FILE *sql_file = md_result_file; FILE *sql_file = md_result_file;
DBUG_ENTER("getTableStructure"); 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 " : ""; delayed= opt_delayed ? " DELAYED " : "";
if (verbose) if (verbose)
fprintf(stderr, "-- Retrieving table structure for table %s...\n", table); 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", "SET OPTION SQL_QUOTE_SHOW_CREATE=%d",
(opt_quoted || opt_keywords)); (opt_quoted || opt_keywords));
if (!create_options) 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); result_table= quote_name(table, table_buff, 1);
opt_quoted_table= quote_name(table, table_buff2, 0); opt_quoted_table= quote_name(table, table_buff2, 0);
...@@ -1119,7 +1130,7 @@ static uint getTableStructure(char *table, char* db) ...@@ -1119,7 +1130,7 @@ static uint getTableStructure(char *table, char* db)
if (opt_order_by_primary) if (opt_order_by_primary)
order_by = primary_key_fields(opt_quoted_table); 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 */ /* using SHOW CREATE statement */
if (!tFlag) if (!tFlag)
...@@ -1165,9 +1176,9 @@ static uint getTableStructure(char *table, char* db) ...@@ -1165,9 +1176,9 @@ static uint getTableStructure(char *table, char* db)
check_io(sql_file); check_io(sql_file);
mysql_free_result(tableRes); 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); result_table);
if (mysql_query_with_error_report(sock, &tableRes, insert_pat)) if (mysql_query_with_error_report(sock, &tableRes, query_buff))
{ {
if (path) if (path)
my_fclose(sql_file, MYF(MY_WME)); my_fclose(sql_file, MYF(MY_WME));
...@@ -1175,28 +1186,32 @@ static uint getTableStructure(char *table, char* db) ...@@ -1175,28 +1186,32 @@ static uint getTableStructure(char *table, char* db)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
if (cFlag) dynstr_append_mem(&insert_pat, "INSERT ", 7);
my_snprintf(insert_pat, sizeof(insert_pat), "INSERT %sINTO %s (", dynstr_append(&insert_pat, delayed);
delayed, opt_quoted_table); 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 else
{ {
my_snprintf(insert_pat, sizeof(insert_pat), "INSERT %sINTO %s VALUES ", dynstr_append_mem(&insert_pat, " VALUES ", 8);
delayed, opt_quoted_table);
if (!extended_insert) if (!extended_insert)
strcat(insert_pat,"("); dynstr_append_mem(&insert_pat, "(", 1);
} }
strpos=strend(insert_pat);
while ((row=mysql_fetch_row(tableRes))) while ((row=mysql_fetch_row(tableRes)))
{ {
if (init) if (init)
{ {
if (cFlag) if (opt_complete_insert)
strpos=strmov(strpos,", "); dynstr_append_mem(&insert_pat, ", ", 2);
} }
init=1; init=1;
if (cFlag) if (opt_complete_insert)
strpos=strmov(strpos,quote_name(row[SHOW_FIELDNAME], name_buff, 0)); dynstr_append(&insert_pat,
quote_name(row[SHOW_FIELDNAME], name_buff, 0));
} }
numFields = (uint) mysql_num_rows(tableRes); numFields = (uint) mysql_num_rows(tableRes);
mysql_free_result(tableRes); mysql_free_result(tableRes);
...@@ -1208,9 +1223,9 @@ static uint getTableStructure(char *table, char* db) ...@@ -1208,9 +1223,9 @@ static uint getTableStructure(char *table, char* db)
"%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n", "%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n",
my_progname, mysql_error(sock)); 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); 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); safe_exit(EX_MYSQLERR);
DBUG_RETURN(0); DBUG_RETURN(0);
...@@ -1243,18 +1258,22 @@ static uint getTableStructure(char *table, char* db) ...@@ -1243,18 +1258,22 @@ static uint getTableStructure(char *table, char* db)
print_xml_tag1(sql_file, "\t", "table_structure name=", table, "\n"); print_xml_tag1(sql_file, "\t", "table_structure name=", table, "\n");
check_io(sql_file); check_io(sql_file);
} }
if (cFlag)
my_snprintf(insert_pat, sizeof(insert_pat), "INSERT %sINTO %s (", dynstr_append_mem(&insert_pat, "INSERT ", 7);
delayed, result_table); 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 else
{ {
my_snprintf(insert_pat, sizeof(insert_pat), "INSERT %sINTO %s VALUES ", dynstr_append_mem(&insert_pat, " VALUES ", 8);
delayed, result_table);
if (!extended_insert) if (!extended_insert)
strcat(insert_pat,"("); dynstr_append_mem(&insert_pat, "(", 1);
} }
strpos=strend(insert_pat);
while ((row=mysql_fetch_row(tableRes))) while ((row=mysql_fetch_row(tableRes)))
{ {
ulong *lengths=mysql_fetch_lengths(tableRes); ulong *lengths=mysql_fetch_lengths(tableRes);
...@@ -1265,12 +1284,13 @@ static uint getTableStructure(char *table, char* db) ...@@ -1265,12 +1284,13 @@ static uint getTableStructure(char *table, char* db)
fputs(",\n",sql_file); fputs(",\n",sql_file);
check_io(sql_file); check_io(sql_file);
} }
if (cFlag) if (opt_complete_insert)
strpos=strmov(strpos,", "); dynstr_append_mem(&insert_pat, ", ", 2);
} }
init=1; init=1;
if (cFlag) if (opt_complete_insert)
strpos=strmov(strpos,quote_name(row[SHOW_FIELDNAME], name_buff, 0)); dynstr_append(&insert_pat,
quote_name(row[SHOW_FIELDNAME], name_buff, 0));
if (!tFlag) if (!tFlag)
{ {
if (opt_xml) if (opt_xml)
...@@ -1423,11 +1443,11 @@ static uint getTableStructure(char *table, char* db) ...@@ -1423,11 +1443,11 @@ static uint getTableStructure(char *table, char* db)
check_io(sql_file); check_io(sql_file);
} }
} }
if (cFlag) if (opt_complete_insert)
{ {
strpos=strmov(strpos,") VALUES "); dynstr_append_mem(&insert_pat, ") VALUES ", 9);
if (!extended_insert) if (!extended_insert)
strpos=strmov(strpos,"("); dynstr_append_mem(&insert_pat, "(", 1);
} }
if (sql_file != md_result_file) if (sql_file != md_result_file)
{ {
...@@ -1650,7 +1670,7 @@ static void dumpTable(uint numFields, char *table) ...@@ -1650,7 +1670,7 @@ static void dumpTable(uint numFields, char *table)
total_length= opt_net_buffer_length; /* Force row break */ total_length= opt_net_buffer_length; /* Force row break */
row_break=0; row_break=0;
rownr=0; rownr=0;
init_length=(uint) strlen(insert_pat)+4; init_length=(uint) insert_pat.length+4;
if (opt_xml) if (opt_xml)
print_xml_tag1(md_result_file, "\t", "table_data name=", table, "\n"); print_xml_tag1(md_result_file, "\t", "table_data name=", table, "\n");
...@@ -1667,7 +1687,7 @@ static void dumpTable(uint numFields, char *table) ...@@ -1667,7 +1687,7 @@ static void dumpTable(uint numFields, char *table)
rownr++; rownr++;
if (!extended_insert && !opt_xml) if (!extended_insert && !opt_xml)
{ {
fputs(insert_pat,md_result_file); fputs(insert_pat.str,md_result_file);
check_io(md_result_file); check_io(md_result_file);
} }
mysql_field_seek(res,0); mysql_field_seek(res,0);
...@@ -1864,7 +1884,7 @@ static void dumpTable(uint numFields, char *table) ...@@ -1864,7 +1884,7 @@ static void dumpTable(uint numFields, char *table)
fputs(";\n", md_result_file); fputs(";\n", md_result_file);
row_break=1; /* This is first row */ 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); fputs(extended_row.str,md_result_file);
total_length = row_length+init_length; total_length = row_length+init_length;
} }
...@@ -2557,6 +2577,8 @@ int main(int argc, char **argv) ...@@ -2557,6 +2577,8 @@ int main(int argc, char **argv)
my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR)); my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
if (extended_insert) if (extended_insert)
dynstr_free(&extended_row); dynstr_free(&extended_row);
if (insert_pat_inited)
dynstr_free(&insert_pat);
my_end(0); my_end(0);
return(first_error); return(first_error);
} /* main */ } /* 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