func replaceRow(ctx context.Context, t table.Table, handle int64, replaceRow []interface{}) error { row, err := t.Row(ctx, handle) if err != nil { return errors.Trace(err) } result := 0 isReplace := false touched := make(map[int]bool, len(row)) for i, val := range row { result, err = types.Compare(val, replaceRow[i]) if err != nil { return errors.Trace(err) } if result != 0 { touched[i] = true isReplace = true } } if isReplace { variable.GetSessionVars(ctx).AddAffectedRows(1) if err = t.UpdateRecord(ctx, handle, row, replaceRow, touched); err != nil { return errors.Trace(err) } } return nil }
func (s *DeleteStmt) tryDeleteUsingIndex(ctx context.Context, t table.Table) (bool, error) { log.Info("try delete with index", ctx) p, err := s.indexPlan(ctx) if p == nil || err != nil { return false, errors.Trace(err) } var rowKeys []*plan.RowKeyEntry for { row, err1 := p.Next(ctx) if err1 != nil { return false, errors.Trace(err1) } if row == nil { break } rowKeys = append(rowKeys, row.RowKeys...) } var cnt uint64 for _, rowKey := range rowKeys { if s.Limit != nil && cnt >= s.Limit.Count { break } handle, err := util.DecodeHandleFromRowKey(rowKey.Key) if err != nil { return false, errors.Trace(err) } data, err := t.Row(ctx, handle) if err != nil { return false, err } log.Infof("try delete with index id:%d, ctx:%s", handle, ctx) ok, err := s.hitWhere(ctx, t, data) if err != nil { return false, errors.Trace(err) } if !ok { return true, nil } err = s.removeRow(ctx, t, handle, data) if err != nil { return false, err } cnt++ } return true, nil }
func (s *DeleteStmt) tryDeleteUsingIndex(ctx context.Context, t table.Table) (bool, error) { log.Info("try delete with index", ctx) p, err := s.indexPlan(ctx) if err != nil { return false, err } if p != nil { var ids []int64 err := p.Do(ctx, func(id interface{}, _ []interface{}) (bool, error) { // Generate ids for coming deletion. ids = append(ids, id.(int64)) return true, nil }) if err != nil { return false, err } var cnt uint64 for _, id := range ids { if s.Limit != nil && cnt >= s.Limit.Count { break } data, err := t.Row(ctx, id) if err != nil { return false, err } log.Infof("try delete with index id:%d, ctx:%s", id, ctx) ok, err := s.hitWhere(ctx, t, data) if err != nil { return false, errors.Trace(err) } if !ok { return true, nil } err = s.removeRow(ctx, t, id, data) if err != nil { return false, err } cnt++ } return true, nil } return false, nil }
func execOnDuplicateUpdate(ctx context.Context, t table.Table, row []interface{}, h int64, cols map[int]*expression.Assignment) error { // On duplicate key update the duplicate row. // Evaluate the updated value. // TODO: report rows affected and last insert id. data, err := t.Row(ctx, h) if err != nil { return errors.Trace(err) } toUpdateArgs := map[interface{}]interface{}{} toUpdateArgs[expression.ExprEvalValuesFunc] = func(name string) (interface{}, error) { c, err1 := findColumnByName(t, name) if err1 != nil { return nil, errors.Trace(err1) } return row[c.Offset], nil } if err = updateRecord(ctx, h, data, t, cols, toUpdateArgs, 0, true); err != nil { return errors.Trace(err) } return nil }
func (s *UpdateStmt) tryUpdateUsingIndex(ctx context.Context, t table.Table) (bool, error) { log.Info("update using index") p, err := s.indexPlan(ctx) if p == nil { return false, err } var handles []int64 p.Do(ctx, func(id interface{}, _ []interface{}) (more bool, err error) { // Record handle ids for updating. handles = append(handles, id.(int64)) return true, nil }) tcols, err := getUpdateColumns(t, s.List) if err != nil { return false, err } var cnt uint64 for _, id := range handles { data, err := t.Row(ctx, id) if err != nil { return false, err } log.Info("updating ", id) if s.Limit != nil && cnt >= s.Limit.Count { break } err = updateRecord(ctx, id, data, t, tcols, s.List, nil) if err != nil { return false, err } cnt++ } return true, nil }