matrixorigin / matrixorigin/matrixone

[Bug]: LEAVE / ITERATE ignored inside REPEAT and WHILE procedures (only LOOP works)

Open
#26,904 1 comment 0 reactions 1 assignee Claimed by @iamlinjunhong View on GitHub
deferred kind/bug
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.