Пример #1
0
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)
}
Пример #2
0
// 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
}
Пример #3
0
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
}
Пример #4
0
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
}