// Do implements plan.Plan Do interface, acquiring locks. func (r *SelectLockPlan) Do(ctx context.Context, f plan.RowIterFunc) error { return r.Src.Do(ctx, func(rid interface{}, in []interface{}) (bool, error) { var rowKeys *RowKeyList if in != nil && len(in) > 0 { t := in[len(in)-1] switch vt := t.(type) { case *RowKeyList: rowKeys = vt // Remove row key list from data tail in = in[:len(in)-1] } } if rowKeys != nil && r.Lock == coldef.SelectLockForUpdate { forupdate.SetForUpdate(ctx) txn, err := ctx.GetTxn(false) if err != nil { return false, errors.Trace(err) } for _, k := range rowKeys.Keys { err = txn.LockKeys([]byte(k.Key)) if err != nil { return false, errors.Trace(err) } } } return f(rid, in) }) }
// Next implements Executor Next interface. func (e *SelectLockExec) Next() (*Row, error) { row, err := e.Src.Next() if err != nil { return nil, errors.Trace(err) } if row == nil { return nil, nil } if len(row.RowKeys) != 0 && e.Lock == ast.SelectLockForUpdate { forupdate.SetForUpdate(e.ctx) for _, k := range row.RowKeys { err = k.Tbl.LockRow(e.ctx, k.Handle, true) if err != nil { return nil, errors.Trace(err) } } } return row, nil }
// Next implements plan.Plan Next interface. func (r *SelectLockPlan) Next(ctx context.Context) (row *plan.Row, err error) { row, err = r.Src.Next(ctx) if row == nil || err != nil { return nil, errors.Trace(err) } if len(row.RowKeys) != 0 && r.Lock == coldef.SelectLockForUpdate { forupdate.SetForUpdate(ctx) txn, err := ctx.GetTxn(false) if err != nil { return nil, errors.Trace(err) } for _, k := range row.RowKeys { err = txn.LockKeys(kv.Key(k.Key)) if err != nil { return nil, errors.Trace(err) } } } return }
// Next implements Executor Next interface. func (e *SelectLockExec) Next() (*Row, error) { row, err := e.Src.Next() if err != nil { return nil, errors.Trace(err) } if row == nil { return nil, nil } if len(row.RowKeys) != 0 && e.Lock == ast.SelectLockForUpdate { forupdate.SetForUpdate(e.ctx) txn, err := e.ctx.GetTxn(false) if err != nil { return nil, errors.Trace(err) } for _, k := range row.RowKeys { err = txn.LockKeys([]byte(k.Key)) if err != nil { return nil, errors.Trace(err) } } } return row, nil }
// Next implements the Executor Next interface. func (e *SelectLockExec) Next() (*Row, error) { row, err := e.Src.Next() if err != nil { return nil, errors.Trace(err) } if row == nil { return nil, nil } if len(row.RowKeys) != 0 && e.Lock == ast.SelectLockForUpdate { forupdate.SetForUpdate(e.ctx) txn, err := e.ctx.GetTxn(false) if err != nil { return nil, errors.Trace(err) } for _, k := range row.RowKeys { lockKey := tablecodec.EncodeRowKeyWithHandle(k.Tbl.Meta().ID, k.Handle) err = txn.LockKeys(lockKey) if err != nil { return nil, errors.Trace(err) } } } return row, nil }