in pkg/datasource/sql/undo/builder/mysql_multi_delete_undo_log_builder.go [109:190]
func (u *MySQLMultiDeleteUndoLogBuilder) buildBeforeImageSQL(multiQuery []string, args []driver.Value) ([]string, []driver.Value, error) {
var (
err error
buf, param bytes.Buffer
p *types.ParseContext
tableName string
tables = make(map[string]multiDelete, len(multiQuery))
)
for _, query := range multiQuery {
p, err = parser.DoParser(query)
if err != nil {
return nil, nil, err
}
tableName = p.DeleteStmt.TableRefs.TableRefs.Left.(*ast.TableSource).Source.(*ast.TableName).Name.O
v, ok := tables[tableName]
if ok && v.clear {
continue
}
buf.WriteString("delete from ")
buf.WriteString(tableName)
if p.DeleteStmt.Where == nil {
tables[tableName] = multiDelete{sql: buf.String(), clear: true}
buf.Reset()
continue
} else {
buf.WriteString(" where ")
}
_ = p.DeleteStmt.Where.Restore(format.NewRestoreCtx(format.RestoreKeyWordUppercase, ¶m))
v, ok = tables[tableName]
if ok {
buf.Reset()
buf.WriteString(v.sql)
buf.WriteString(" or ")
}
buf.Write(param.Bytes())
tables[tableName] = multiDelete{sql: buf.String()}
buf.Reset()
param.Reset()
}
var (
items = make([]string, 0, len(tables))
values = make([]driver.Value, 0, len(tables))
selStmt = ast.SelectStmt{
SelectStmtOpts: &ast.SelectStmtOpts{},
From: p.DeleteStmt.TableRefs,
Where: p.DeleteStmt.Where,
Fields: &ast.FieldList{Fields: []*ast.SelectField{{WildCard: &ast.WildCardField{}}}},
OrderBy: p.DeleteStmt.Order,
Limit: p.DeleteStmt.Limit,
TableHints: p.DeleteStmt.TableHints,
LockInfo: &ast.SelectLockInfo{LockType: ast.SelectLockForUpdate},
}
)
for _, table := range tables {
p, _ = parser.DoParser(table.sql)
selStmt.From = p.DeleteStmt.TableRefs
selStmt.Where = p.DeleteStmt.Where
_ = selStmt.Restore(format.NewRestoreCtx(format.RestoreKeyWordUppercase, &buf))
items = append(items, buf.String())
buf.Reset()
if table.clear {
values = append(values, u.buildSelectArgs(&selStmt, nil)...)
} else {
values = append(values, u.buildSelectArgs(&selStmt, args)...)
}
}
return items, values, nil
}