findMatchingDMLs returns ALL UPDATE/DELETE nodes in the parsed statement list that reference the target table. The single-DML form (return-on- first-match) is incorrect for backup.go's single-table-bundling path, where one backup item spans multiple same-table DMLs touching different columns; rollin
(statement, database, table string, targetCols map[string]bool)
| 127 | // columns; rolling back only the first stmt's columns leaves later |
| 128 | // columns mutated. See Codex P1 catch on PR #20345. |
| 129 | func findMatchingDMLs(statement, database, table string, targetCols map[string]bool) ([]ast.Node, error) { |
| 130 | stmtList, err := ParseTiDBOmni(statement) |
| 131 | if err != nil { |
| 132 | return nil, errors.Wrap(err, "failed to parse statement") |
| 133 | } |
| 134 | var result []ast.Node |
| 135 | for _, item := range stmtList.Items { |
| 136 | switch item.(type) { |
| 137 | case *ast.UpdateStmt, *ast.DeleteStmt: |
| 138 | if containsTable(item, database, table, targetCols) { |
| 139 | result = append(result, item) |
| 140 | } |
| 141 | default: |
| 142 | } |
| 143 | } |
| 144 | return result, nil |
| 145 | } |
| 146 | |
| 147 | func doGenerate(ctx context.Context, rCtx base.RestoreContext, sqlForComment string, nodes []ast.Node, backupItem *storepb.PriorBackupDetail_Item) (string, error) { |
| 148 | _, sourceDatabase, err := common.GetInstanceDatabaseID(backupItem.SourceTable.Database) |
no test coverage detected