func (d *ddl) deleteTableData(ctx context.Context, t table.Table) error { // Remove data err := t.Truncate(ctx) if err != nil { return errors.Trace(err) } txn, err := ctx.GetTxn(false) if err != nil { return errors.Trace(err) } // Remove indices for _, v := range t.Indices() { if v != nil && v.X != nil { if err = v.X.Drop(txn); err != nil { return errors.Trace(err) } } } // Remove auto ID key err = txn.Delete([]byte(meta.AutoIDKey(t.TableID()))) // Auto ID meta is created when the first time used, so it may not exist. if errors2.ErrorEqual(err, kv.ErrNotExist) { return nil } return errors.Trace(err) }
// Exec implements the stmt.Statement Exec interface. func (s *DeleteStmt) Exec(ctx context.Context) (_ rset.Recordset, err error) { if s.MultiTable && len(s.TableIdents) == 0 { return nil, nil } p, err := s.plan(ctx) if err != nil { return nil, errors.Trace(err) } if p == nil { return nil, nil } defer p.Close() tblIDMap := make(map[int64]bool, len(s.TableIdents)) // Get table alias map. tblNames := make(map[string]string) if s.MultiTable { // Delete from multiple tables should consider table ident list. fs := p.GetFields() for _, f := range fs { if f.TableName != f.OrgTableName { tblNames[f.TableName] = f.OrgTableName } else { tblNames[f.TableName] = f.TableName } } for _, t := range s.TableIdents { // Consider DBName. oname, ok := tblNames[t.Name.O] if !ok { return nil, errors.Errorf("Unknown table '%s' in MULTI DELETE", t.Name.O) } t.Name.O = oname t.Name.L = strings.ToLower(oname) var tbl table.Table tbl, err = getTable(ctx, t) if err != nil { return nil, errors.Trace(err) } tblIDMap[tbl.TableID()] = true } } rowKeyMap := make(map[string]table.Table) for { row, err1 := p.Next(ctx) if err1 != nil { return nil, errors.Trace(err1) } if row == nil { break } for _, entry := range row.RowKeys { if s.MultiTable { tid := entry.Tbl.TableID() if _, ok := tblIDMap[tid]; !ok { continue } } rowKeyMap[entry.Key] = entry.Tbl } } for k, t := range rowKeyMap { handle, err := util.DecodeHandleFromRowKey(k) if err != nil { return nil, errors.Trace(err) } data, err := t.Row(ctx, handle) if err != nil { return nil, errors.Trace(err) } err = s.removeRow(ctx, t, handle, data) if err != nil { return nil, errors.Trace(err) } } return nil, nil }
func (s *DeleteStmt) execMultiTable(ctx context.Context) (_ rset.Recordset, err error) { log.Info("Delete from multi-table") if len(s.TableIdents) == 0 { return nil, nil } p, err := s.indexPlan(ctx) if err != nil { return nil, errors.Trace(err) } if p == nil { return nil, nil } tblIDMap := make(map[int64]bool, len(s.TableIdents)) // Get table alias map. fs := p.GetFields() tblAliasMap := make(map[string]string) for _, f := range fs { if f.TableName != f.OrgTableName { tblAliasMap[f.TableName] = f.OrgTableName } } for _, t := range s.TableIdents { // Consider DBName. oname, ok := tblAliasMap[t.Name.O] if ok { t.Name.O = oname t.Name.L = strings.ToLower(oname) } var tbl table.Table tbl, err = getTable(ctx, t) if err != nil { return nil, errors.Trace(err) } tblIDMap[tbl.TableID()] = true } rowKeyMap := make(map[string]table.Table) err = p.Do(ctx, func(_ interface{}, in []interface{}) (bool, error) { // Generate ids for coming deletion. var rowKeys *plans.RowKeyList if in != nil && len(in) > 0 { t := in[len(in)-1] switch vt := t.(type) { case *plans.RowKeyList: rowKeys = vt } } if rowKeys != nil { for _, entry := range rowKeys.Keys { tid := entry.Tbl.TableID() if _, ok := tblIDMap[tid]; !ok { continue } rowKeyMap[entry.Key] = entry.Tbl } } return true, nil }) if err != nil { return nil, errors.Trace(err) } for k, t := range rowKeyMap { id, err := util.DecodeHandleFromRowKey(k) if err != nil { return nil, errors.Trace(err) } data, err := t.Row(ctx, id) if err != nil { return nil, errors.Trace(err) } err = s.removeRow(ctx, t, id, data) if err != nil { return nil, errors.Trace(err) } } return nil, nil }
func (s *DeleteStmt) execMultiTable(ctx context.Context) (_ rset.Recordset, err error) { log.Info("Delete from multi-table") if len(s.TableIdents) == 0 { return nil, nil } p, err := s.indexPlan(ctx) if err != nil { return nil, errors.Trace(err) } if p == nil { return nil, nil } defer p.Close() tblIDMap := make(map[int64]bool, len(s.TableIdents)) // Get table alias map. fs := p.GetFields() tblAliasMap := make(map[string]string) for _, f := range fs { if f.TableName != f.OrgTableName { tblAliasMap[f.TableName] = f.OrgTableName } } for _, t := range s.TableIdents { // Consider DBName. oname, ok := tblAliasMap[t.Name.O] if ok { t.Name.O = oname t.Name.L = strings.ToLower(oname) } var tbl table.Table tbl, err = getTable(ctx, t) if err != nil { return nil, errors.Trace(err) } tblIDMap[tbl.TableID()] = true } rowKeyMap := make(map[string]table.Table) for { row, err1 := p.Next(ctx) if err1 != nil { return nil, errors.Trace(err1) } if row == nil { break } for _, entry := range row.RowKeys { tid := entry.Tbl.TableID() if _, ok := tblIDMap[tid]; !ok { continue } rowKeyMap[entry.Key] = entry.Tbl } } for k, t := range rowKeyMap { id, err := util.DecodeHandleFromRowKey(k) if err != nil { return nil, errors.Trace(err) } data, err := t.Row(ctx, id) if err != nil { return nil, errors.Trace(err) } err = s.removeRow(ctx, t, id, data) if err != nil { return nil, errors.Trace(err) } } return nil, nil }