Lock may not be pushed down to point get / batch point get in some cases
- Dominant language
- Go
- Stars
- 40.5k
- Forks
- 6.2k
- PR merge metrics
- PR metrics pending
Description
## Bug Report

The condition `len(p.Children()) > 1` can skip some cases even point get/batch point get exists.
For example, in the query statment `select * from t where id=1 for update union all select * from t where id = 2 for update`, the lock cannot be pushed down to point get as union all has two children.
If the lock is not pushed down to point get/batch point get, keys will not be locked in `lockKeyIfNeeded` (if the lock is push down to the point get/ batch point get, we should lock the keys here even though they are not exists).
Below is a case that can be easily reproduced.
### 1. Minimal reproduce step (Required)
```
store, _, clean := testkit.CreateMockStoreAndDomain(t)
defer clean()
tk := testkit.NewTestKit(t, store)
tk2 := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk2.MustExec("use test")
tk.MustExec("create table t (id int primary key, v int)")
tk.MustExec("begin pessimistic")
tk.MustExec("select * from t where id=1 for update union all select * from t where id = 2 for update")
tk2.MustExec("insert into t values (1, 1), (2,2)")
tk.MustExec("rollback")
```
### 2. What did you expect to see? (Required)
The test complets.
### 3. What did you see instead (Required)
Blocked at the final 2 line.
### 4. What is your TiDB version? (Required)
cd731af05a5446bb8dcba83f0e163176c75f5cea
Contributor guide
Assessment
This issue has not been assessed yet.