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 }
// 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 }
// 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 }