matrixorigin / matrixorigin/matrixone
[Bug]: LEAVE / ITERATE ignored inside REPEAT and WHILE procedures (only LOOP works)
- Dominant language
- Go
- Stars
- 1.9k
- Forks
- 311
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 768
Description
## Body
```markdown
### Is there an existing issue for the same bug?
- [x] I searched open/closed issues for procedure `LEAVE`, `ITERATE`, `REPEAT`, `WHILE`.
- Related (different symptom): #10477 — `REPEAT`/`UNTIL` used to exit early (`v1=6` instead of `11`). That counting bug is fixed on current `main`; this issue is about **control-flow status** (`LEAVE`/`ITERATE`) not being honored inside `REPEAT`/`WHILE`.
### Branch Name
main
### Commit ID
8be242b25
### Other Environment Information
- Local LOG/TN/CN (`mo-service -launch ./etc/launch/launch.toml`)
- `127.0.0.1:6001`, user `dump`
### Actual Behavior
`LEAVE` / `ITERATE` are accepted syntactically inside labeled `REPEAT` / `WHILE`, but they have **no runtime effect**. Only labeled `LOOP` honors them.
**LEAVE in REPEAT** (expect early exit at 3; actually runs until `UNTIL`):
```sql
DROP PROCEDURE IF EXISTS case_leave_in_repeat;
CREATE PROCEDURE case_leave_in_repeat() 'begin declare v1 int default 0; label1: repeat set v1 = v1 + 1; if v1 >= 3 THEN leave label1; end if; until v1 > 100 end repeat label1; select v1 as leave_in_repeat_v1; end';
CALL case_leave_in_repeat();
-- got: 101
-- expected: 3
```
**ITERATE in REPEAT** (expect sum of odds `1+3+5=9`; actually sums all):
```sql
DROP PROCEDURE IF EXISTS case_iter_in_repeat;
CREATE PROCEDURE case_iter_in_repeat() 'begin declare v1 int default 0; declare s int default 0; label1: repeat set v1 = v1 + 1; if v1 % 2 = 0 THEN iterate label1; end if; set s = s + v1; until v1 >= 6 end repeat label1; select v1 as iter_v1, s as iter_sum; end';
CALL case_iter_in_repeat();
-- got: iter_v1=6, iter_sum=21
-- expected: iter_sum=9
```
**LEAVE in WHILE** (expect 3; actually finishes the while):
```sql
DROP PROCEDURE IF EXISTS case_leave_in_while;
CREATE PROCEDURE case_leave_in_while() 'begin declare v1 int default 0; label1: while v1 < 100 do set v1 = v1 + 1; if v1 >= 3 THEN leave label1; end if; end while label1; select v1 as leave_in_while_v1; end';
CALL case_leave_in_while();
-- got: 100
-- expected: 3
```
**Control: LEAVE in LOOP works:**
```sql
DROP PROCEDURE IF EXISTS case_leave_in_loop;
CREATE PROCEDURE case_leave_in_loop() 'begin declare v1 int default 0; label1: loop set v1 = v1 + 1; if v1 >= 3 THEN leave label1; end if; end loop label1; select v1 as leave_in_loop_v1; end';
CALL case_leave_in_loop();
-- got: 3 (OK)
```
### Expected Behavior
MySQL-compatible procedure semantics:
- `LEAVE label` exits the matching labeled `LOOP` / `REPEAT` / `WHILE`.
- `ITERATE label` continues the next iteration of the matching labeled loop construct.
### Controls
| Construct | `LEAVE` | `ITERATE` |
|-----------|---------|-----------|
| `LOOP` | OK | OK (existing BVT) |
| `REPEAT` | ignored | ignored |
| `WHILE` | ignored | ignored |
```
Contributor guide
Assessment
This issue has not been assessed yet.