Bug #119810 mysqldump add IGNORE queries for REPLACE queries on innodb_table_stats innodb_index_stats tables
Submitted: 30 Jan 0:52
Reporter: Jinyou Ma Email Updates:
Status: Open Impact on me:
None 
Category:MySQL Server: mysqldump Command-line Client Severity:S3 (Non-critical)
Version:8.0, 8.4, 9.6 OS:Any
Assigned to: CPU Architecture:Any

[30 Jan 0:52] Jinyou Ma
Description:
When dumping the mysql.innodb_table_stats, and mysql.innodb_index_stats tables with --replace option, mysqldump adds an IGNORE clause for the REPLACE command.

For example, the IGNORE is always added to both INSERT and REPLACE
```
bash-5.1# mysqldump --version
mysqldump  Ver 9.6.0 for Linux on aarch64 (MySQL Community Server - GPL)

bash-5.1# mysqldump -pmy-secret-pw  --single-transaction mysql innodb_table_stats  2> /dev/null | grep INTO | awk '{print $1,$2,$3}'
INSERT IGNORE INTO
bash-5.1# mysqldump -pmy-secret-pw --replace --single-transaction mysql innodb_table_stats  2> /dev/null | grep INTO | awk '{print $1,$2,$3}'
REPLACE IGNORE INTO
```
The reason is that the insert_option is added even if the opt_replace_into is true
```
      if (opt_replace_into)
        dynstr_append_checked(&insert_pat, "REPLACE ");
      else
        dynstr_append_checked(&insert_pat, "INSERT ");
      dynstr_append_checked(&insert_pat, insert_option);
```

After appling the path, the expected result will be: 
```
/build/runtime_output_directory/mysqldump --single-transaction mysql innodb_table_stats  2> /dev/null | grep INTO | awk '{print $1,$2,$3}'
INSERT IGNORE INTO
/build/runtime_output_directory/mysqldump --replace --single-transaction mysql innodb_table_stats  2> /dev/null  | grep INTO | awk '{print $1,$2,$3}'
REPLACE INTO `innodb_table_stats`
```

How to repeat:
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql
docker exec -it some-mysql bash
mysqldump -pmy-secret-pw --replace --single-transaction mysql innodb_table_stats  2> /dev/null | grep INTO | awk '{print $1,$2,$3}'

Suggested fix:
diff --git a/client/mysqldump.cc b/client/mysqldump.cc
index f4d1a1ea0f7..6cfbe54fc03 100644
--- a/client/mysqldump.cc
+++ b/client/mysqldump.cc
@@ -3467,9 +3467,10 @@ static uint get_table_structure(const char *table, char *db, char *table_type,
     if (write_data) {
       if (opt_replace_into)
         dynstr_append_checked(&insert_pat, "REPLACE ");
-      else
-        dynstr_append_checked(&insert_pat, "INSERT ");
-      dynstr_append_checked(&insert_pat, insert_option);
+      else {
+        dynstr_append_checked(&insert_pat, "INSERT");
+        dynstr_append_checked(&insert_pat, insert_option);
+      }
       dynstr_append_checked(&insert_pat, "INTO ");
       dynstr_append_checked(&insert_pat, opt_quoted_table);
       if (complete_insert) {
@@ -3585,9 +3586,10 @@ static uint get_table_structure(const char *table, char *db, char *table_type,
     if (write_data) {
       if (opt_replace_into)
         dynstr_append_checked(&insert_pat, "REPLACE ");
-      else
-        dynstr_append_checked(&insert_pat, "INSERT ");
-      dynstr_append_checked(&insert_pat, insert_option);
+      else {
+        dynstr_append_checked(&insert_pat, "INSERT");
+        dynstr_append_checked(&insert_pat, insert_option);
+      }
       dynstr_append_checked(&insert_pat, "INTO ");
       dynstr_append_checked(&insert_pat, result_table);
       if (complete_insert)