From 5820f691afedb46d4c4b15ceca7298c53c34d8c2 Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Mon, 8 Sep 2025 16:21:34 +0300 Subject: [PATCH] fix: do not crash in Next if cursor stack has no pages --- core/storage/btree.rs | 5 ++++- testing/join.test | 12 +++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/core/storage/btree.rs b/core/storage/btree.rs index 8b37dc64b..3c732c8d9 100644 --- a/core/storage/btree.rs +++ b/core/storage/btree.rs @@ -1203,6 +1203,10 @@ impl BTreeCursor { } None => return Ok(IOResult::Done(false)), } + } else if self.stack.current_page == -1 { + // This can happen in nested left joins. See: + // https://github.com/tursodatabase/turso/issues/2924 + return Ok(IOResult::Done(false)); } loop { let mem_page = self.stack.top_ref(); @@ -4202,7 +4206,6 @@ impl BTreeCursor { if self.valid_state == CursorValidState::Invalid { return Ok(IOResult::Done(false)); } - loop { match self.advance_state { AdvanceState::Start => { diff --git a/testing/join.test b/testing/join.test index 44434e971..034719b1f 100755 --- a/testing/join.test +++ b/testing/join.test @@ -318,4 +318,14 @@ do_execsql_test_on_specific_db {:memory:} left-join-seek-key-regression-test { CREATE TABLE u (x INTEGER PRIMARY KEY); INSERT INTO t VALUES (1); SELECT * FROM t LEFT JOIN u ON false WHERE u.x = 1; -} {} \ No newline at end of file +} {} + +# regression test for issue 2924: calling Next on a cursor that hasn't moved yet +do_execsql_test_on_specific_db {:memory:} next-crash { + create table a(x int primary key,y); + create table b(x int primary key,y); + create table c(x int primary key,y); + insert into a values (1,1),(2,2); + select a.x, b.x, c.x from a left join b on a.y=b.x left join c on b.y=c.x; +} {1|| +2||}