diff --git a/client/mysql.cc b/client/mysql.cc index 1e235c8a34d..9591ffb096a 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -158,7 +158,8 @@ static my_bool ignore_errors=0,wait_flag=0,quick=0, default_pager_set= 0, opt_sigint_ignore= 0, auto_vertical_output= 0, show_warnings= 0, executing_query= 0, - ignore_spaces= 0, opt_binhex= 0, opt_progress_reports; + ignore_spaces= 0, opt_binhex= 0, opt_progress_reports, + opt_print_query_on_error; static my_bool debug_info_flag, debug_check_flag, batch_abort_on_error; static my_bool column_types_flag; static my_bool preserve_comments= 0; @@ -237,6 +238,7 @@ static int com_quit(String *str,char*), com_prompt(String *str, char*), com_delimiter(String *str, char*), com_warnings(String *str, char*), com_nowarnings(String *str, char*), com_sandbox(String *str, char*); +static void print_query_to_stderr(String *buffer); #ifdef USE_POPEN static int com_nopager(String *str, char*), com_pager(String *str, char*), @@ -1659,6 +1661,10 @@ static struct my_option my_long_options[] = #endif "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").", &opt_mysql_port, &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"print-query-on-error", 0, + "Print the query if there was an error. Is only enabled in --batch mode if verbose is not set (as then the query would be printed anyway)", + &opt_print_query_on_error, &opt_print_query_on_error, 0, GET_BOOL, NO_ARG, + 1, 0, 0, 0, 0, 0}, {"progress-reports", 0, "Get progress reports for long running commands (like ALTER TABLE)", &opt_progress_reports, &opt_progress_reports, 0, GET_BOOL, NO_ARG, 1, 0, @@ -3086,6 +3092,11 @@ int mysql_real_query_for_lazy(const char *buf, size_t length) int error; if (!mysql_real_query(&mysql,buf,(ulong)length)) return 0; + if (opt_print_query_on_error) + { + String query(buf, length, charset_info); + (void) print_query_to_stderr(&query); + } error= put_error(&mysql); if (mysql_errno(&mysql) != CR_SERVER_GONE_ERROR || retry > 1 || !opt_reconnect) @@ -3291,7 +3302,6 @@ static int com_charset(String *, char *line) 1 if fatal error */ - static int com_go(String *buffer, char *) { char buff[200]; /* about 110 chars used so far */ @@ -3363,6 +3373,8 @@ static int com_go(String *buffer, char *) { if (!(result=mysql_use_result(&mysql)) && mysql_field_count(&mysql)) { + if (opt_print_query_on_error) + print_query_to_stderr(buffer); error= put_error(&mysql); goto end; } @@ -3416,7 +3428,11 @@ static int com_go(String *buffer, char *) (long) mysql_num_rows(result) == 1 ? "row" : "rows"); end_pager(); if (mysql_errno(&mysql)) + { + if (opt_print_query_on_error) + print_query_to_stderr(buffer); error= put_error(&mysql); + } } } else if (mysql_affected_rows(&mysql) == ~(ulonglong) 0) @@ -3443,13 +3459,21 @@ static int com_go(String *buffer, char *) put_info("",INFO_RESULT); // Empty row if (result && !mysql_eof(result)) /* Something wrong when using quick */ + { + if (opt_print_query_on_error) + print_query_to_stderr(buffer); error= put_error(&mysql); + } else if (unbuffered) fflush(stdout); mysql_free_result(result); } while (!(err= mysql_next_result(&mysql))); if (err >= 1) + { + if (opt_print_query_on_error) + print_query_to_stderr(buffer); error= put_error(&mysql); + } end: @@ -4375,14 +4399,35 @@ static int com_shell(String *, char *line) #endif +static void print_query(String *buffer, FILE *file) +{ + tee_puts("--------------", file); + (void) tee_fputs(buffer->c_ptr(), file); + if (!buffer->length() || (*buffer)[buffer->length()-1] != '\n') + tee_putc('\n', file); + tee_puts("--------------\n", file); +} + + +/* + Print query to stderr in batch mode if verbose is not set +*/ + +static void print_query_to_stderr(String *buffer) +{ + if ((status.batch || in_com_source) && !verbose) + { + fflush(stdout); + print_query(buffer, stderr); + fflush(stderr); + } +} + + static int com_print(String *buffer,char *) { - tee_puts("--------------", stdout); - (void) tee_fputs(buffer->c_ptr(), stdout); - if (!buffer->length() || (*buffer)[buffer->length()-1] != '\n') - tee_putc('\n', stdout); - tee_puts("--------------\n", stdout); - return 0; /* If empty buffer */ + print_query(buffer, stdout); + return 0; } @@ -5117,8 +5162,9 @@ put_info(const char *str,INFO_TYPE info_type, uint error, const char *sqlstate) static int put_error(MYSQL *con) { - return put_info(mysql_error(con), INFO_ERROR, mysql_errno(con), - mysql_sqlstate(con)); + DBUG_ENTER("put_error"); + DBUG_RETURN(put_info(mysql_error(con), INFO_ERROR, + mysql_errno(con), mysql_sqlstate(con))); } diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index b303ffd099a..f81cff2797c 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -628,7 +628,7 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res, { my_close(fd, MYF(MY_WME)); my_delete(query_file_path, MYF(0)); - die("Failed to write to '%s'", query_file_path); + die("Failed to write query to '%s'", query_file_path); } } @@ -637,7 +637,7 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res, { my_close(fd, MYF(MY_WME)); my_delete(query_file_path, MYF(0)); - die("Failed to write to '%s'", query_file_path); + die("Failed to write query to '%s'", query_file_path); } ret= run_tool(mysql_path, @@ -647,6 +647,7 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res, "--batch", /* Turns off pager etc. */ force ? "--force": "--skip-force", opt_verbose >= 5 ? "--verbose" : "", + "--print-query-on-error", ds_res || opt_silent ? "--silent": "", "<", query_file_path, @@ -1085,18 +1086,6 @@ static char* get_line(char* line) return line; } - -/* Print the current line to stderr */ -static void print_line(char* line) -{ - while (*line && *line != '\n') - { - fputc(*line, stderr); - line++; - } - fputc('\n', stderr); -} - static my_bool from_before_10_1() { my_bool ret= TRUE; @@ -1308,16 +1297,21 @@ static int check_slave_repositories(void) static int run_sql_fix_privilege_tables(void) { - int found_real_errors= 0; + int found_real_errors= 0, query_started= 0; const char **query_ptr; + const char *end; DYNAMIC_STRING ds_script; DYNAMIC_STRING ds_result; + DYNAMIC_STRING ds_query; DBUG_ENTER("run_sql_fix_privilege_tables"); - if (init_dynamic_string(&ds_script, "", 65536, 1024)) + if (init_dynamic_string(&ds_script, "", 96*1024, 8196)) die("Out of memory"); - if (init_dynamic_string(&ds_result, "", 512, 512)) + if (init_dynamic_string(&ds_result, "", 1024, 1024)) + die("Out of memory"); + + if (init_dynamic_string(&ds_query, "", 1024, 1024)) die("Out of memory"); verbose("Phase %d/%d: Running 'mysql_fix_privilege_tables'", @@ -1346,22 +1340,46 @@ static int run_sql_fix_privilege_tables(void) "Unknown column" and "Duplicate key name" since they just indicate the system tables are already up to date */ - char *line= ds_result.str; + const char *line= ds_result.str; do { + size_t length; + end= strchr(line, '\n'); + if (!end) + end= strend(line); + else + end++; /* Include end \n */ + length= (size_t) (end - line); + if (!is_expected_error(line)) { /* Something unexpected failed, dump error line to screen */ found_real_errors++; - print_line(line); + if (ds_query.length) + fwrite(ds_query.str, sizeof(char), ds_query.length, stderr); + fwrite(line, sizeof(char), length, stderr); + query_started= 0; } else if (strncmp(line, "WARNING", 7) == 0) { - print_line(line); + fwrite(line, sizeof(char), length, stderr); + query_started= 0; } - } while ((line= get_line(line)) && *line); + else if (!strncmp(line, "--------------\n", 16)) + { + /* mariadb separates query from the error with a line of '-' */ + if (!query_started++) + ds_query.length= 0; /* Truncate */ + else + query_started= 0; /* End of query */ + } + else if (query_started) + { + dynstr_append_mem(&ds_query, line, length); + } + } while (*(line= end)); } - + dynstr_free(&ds_query); dynstr_free(&ds_result); dynstr_free(&ds_script); DBUG_RETURN(found_real_errors); diff --git a/mysql-test/main/mysqldump.result b/mysql-test/main/mysqldump.result index 1541a4e6f72..1f59f31b7c8 100644 --- a/mysql-test/main/mysqldump.result +++ b/mysql-test/main/mysqldump.result @@ -6413,9 +6413,13 @@ j integer INSERT INTO t VALUES (1,1),(2,2),(3,3),(4,4); # Dump database 1 # Restore from database 1 to database 2 -ERROR 1100 (HY000) at line 46: Table 'seq_t_i' was not locked with LOCK TABLES SETVAL(`seq_t_i`, 1, 0) 1 +-------------- +INSERT INTO `t` VALUES (1,1),(2,2),(3,3),(4,4) +-------------- + +ERROR 1100 (HY000) at line 46: Table 'seq_t_i' was not locked with LOCK TABLES DROP DATABASE IF EXISTS test1; DROP DATABASE IF EXISTS test2; #