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