Exemplo n.º 1
0
func (s *DeleteStmt) hitWhere(ctx context.Context, fields []*field.ResultField, data []interface{}) (bool, error) {
	if s.Where == nil {
		return true, nil
	}
	m := map[interface{}]interface{}{}
	m[expression.ExprEvalIdentFunc] = func(name string) (interface{}, error) {
		return plans.GetIdentValue(name, fields, data, field.DefaultFieldFlag)
	}

	ok, err := expression.EvalBoolExpr(ctx, s.Where, m)
	if err != nil {
		return false, errors.Trace(err)
	}
	return ok, nil
}
Exemplo n.º 2
0
// Exec implements the stmt.Statement Exec interface.
func (s *UpdateStmt) Exec(ctx context.Context) (_ rset.Recordset, err error) {
	p, err := s.plan(ctx)
	if err != nil {
		return nil, errors.Trace(err)
	}
	defer p.Close()
	updatedRowKeys := make(map[string]bool)

	// Get table alias map.
	fs := p.GetFields()

	columns, err0 := getUpdateColumns(s.List, fs)
	if err0 != nil {
		return nil, errors.Trace(err0)
	}

	m := map[interface{}]interface{}{}
	var records []*plan.Row
	for {
		row, err1 := p.Next(ctx)
		if err1 != nil {
			return nil, errors.Trace(err1)
		}
		if row == nil {
			break
		}
		if len(row.RowKeys) == 0 {
			// Nothing to update
			continue
		}
		records = append(records, row)
	}

	for _, row := range records {
		rowData := row.Data

		// Set EvalIdentFunc
		m[expression.ExprEvalIdentFunc] = func(name string) (interface{}, error) {
			return plans.GetIdentValue(name, p.GetFields(), rowData, field.DefaultFieldFlag)
		}

		// Update rows
		offset := 0
		for _, entry := range row.RowKeys {
			tbl := entry.Tbl
			k := entry.Key
			lastOffset := offset
			offset += len(tbl.Cols())
			data := rowData[lastOffset:offset]

			_, ok := updatedRowKeys[k]
			if ok {
				// Each matching row is updated once, even if it matches the conditions multiple times.
				continue
			}
			// Update row
			handle, err2 := util.DecodeHandleFromRowKey(k)
			if err2 != nil {
				return nil, errors.Trace(err2)
			}

			err2 = updateRecord(ctx, handle, data, tbl, columns, m, lastOffset, false)
			if err2 != nil {
				return nil, errors.Trace(err2)
			}

			updatedRowKeys[k] = true
		}
	}
	return nil, nil
}
Exemplo n.º 3
0
// Exec implements the stmt.Statement Exec interface.
func (s *UpdateStmt) Exec(ctx context.Context) (_ rset.Recordset, err error) {
	p, err := s.plan(ctx)
	if err != nil {
		return nil, errors.Trace(err)
	}
	defer p.Close()
	updatedRowKeys := make(map[string]bool)
	for {
		row, err1 := p.Next(ctx)
		if err1 != nil {
			return nil, errors.Trace(err1)
		}
		if row == nil {
			break
		}
		rowData := row.Data
		if len(row.RowKeys) == 0 {
			// Nothing to update
			return nil, nil
		}
		// Set EvalIdentFunc
		m := make(map[interface{}]interface{})
		m[expressions.ExprEvalIdentFunc] = func(name string) (interface{}, error) {
			return plans.GetIdentValue(name, p.GetFields(), rowData, field.DefaultFieldFlag)
		}
		// Update rows
		start := 0
		for _, entry := range row.RowKeys {
			tbl := entry.Tbl
			k := entry.Key
			_, ok := updatedRowKeys[k]
			if ok {
				// Each matching row is updated once, even if it matches the conditions multiple times.
				continue
			}
			// Update row
			handle, err2 := util.DecodeHandleFromRowKey(k)
			if err2 != nil {
				return nil, errors.Trace(err2)
			}
			end := start + len(tbl.Cols())
			data := rowData[start:end]
			start = end
			tcols, err2 := getUpdateColumns(tbl, s.List, s.MultipleTable)
			if err2 != nil {
				return nil, errors.Trace(err2)
			}
			if len(tcols) == 0 {
				// Nothing to update for this table.
				continue
			}
			// Get data in the table
			err2 = updateRecord(ctx, handle, data, tbl, tcols, s.List, nil, m)
			if err2 != nil {
				return nil, errors.Trace(err2)
			}
			updatedRowKeys[k] = true
		}
	}
	return nil, nil
}