Fix: allow DeferredSeek on more than one cursor per program

This commit is contained in:
Jussi Saurio
2025-05-29 16:02:32 +03:00
parent 968eeea75d
commit 69133b3b2e
2 changed files with 8 additions and 8 deletions

View File

@@ -1369,7 +1369,7 @@ pub fn op_column(
else { else {
unreachable!("unexpected Insn {:?}", insn) unreachable!("unexpected Insn {:?}", insn)
}; };
if let Some((index_cursor_id, table_cursor_id)) = state.deferred_seek.take() { if let Some((index_cursor_id, table_cursor_id)) = state.deferred_seeks[*cursor_id].take() {
let deferred_seek = { let deferred_seek = {
let rowid = { let rowid = {
let mut index_cursor = state.get_cursor(index_cursor_id); let mut index_cursor = state.get_cursor(index_cursor_id);
@@ -1384,7 +1384,7 @@ pub fn op_column(
} }
}; };
if let Some(deferred_seek) = deferred_seek { if let Some(deferred_seek) = deferred_seek {
state.deferred_seek = Some(deferred_seek); state.deferred_seeks[*cursor_id] = Some(deferred_seek);
return Ok(InsnFunctionStepResult::IO); return Ok(InsnFunctionStepResult::IO);
} }
} }
@@ -1925,7 +1925,7 @@ pub fn op_row_id(
let Insn::RowId { cursor_id, dest } = insn else { let Insn::RowId { cursor_id, dest } = insn else {
unreachable!("unexpected Insn {:?}", insn) unreachable!("unexpected Insn {:?}", insn)
}; };
if let Some((index_cursor_id, table_cursor_id)) = state.deferred_seek.take() { if let Some((index_cursor_id, table_cursor_id)) = state.deferred_seeks[*cursor_id].take() {
let deferred_seek = { let deferred_seek = {
let rowid = { let rowid = {
let mut index_cursor = state.get_cursor(index_cursor_id); let mut index_cursor = state.get_cursor(index_cursor_id);
@@ -1946,7 +1946,7 @@ pub fn op_row_id(
} }
}; };
if let Some(deferred_seek) = deferred_seek { if let Some(deferred_seek) = deferred_seek {
state.deferred_seek = Some(deferred_seek); state.deferred_seeks[*cursor_id] = Some(deferred_seek);
return Ok(InsnFunctionStepResult::IO); return Ok(InsnFunctionStepResult::IO);
} }
} }
@@ -2058,7 +2058,7 @@ pub fn op_deferred_seek(
else { else {
unreachable!("unexpected Insn {:?}", insn) unreachable!("unexpected Insn {:?}", insn)
}; };
state.deferred_seek = Some((*index_cursor_id, *table_cursor_id)); state.deferred_seeks[*table_cursor_id] = Some((*index_cursor_id, *table_cursor_id));
state.pc += 1; state.pc += 1;
Ok(InsnFunctionStepResult::Step) Ok(InsnFunctionStepResult::Step)
} }

View File

@@ -267,7 +267,7 @@ pub struct ProgramState {
registers: Vec<Register>, registers: Vec<Register>,
pub(crate) result_row: Option<Row>, pub(crate) result_row: Option<Row>,
last_compare: Option<std::cmp::Ordering>, last_compare: Option<std::cmp::Ordering>,
deferred_seek: Option<(CursorID, CursorID)>, deferred_seeks: Vec<Option<(CursorID, CursorID)>>,
ended_coroutine: Bitfield<4>, // flag to indicate that a coroutine has ended (key is the yield register. currently we assume that the yield register is always between 0-255, YOLO) ended_coroutine: Bitfield<4>, // flag to indicate that a coroutine has ended (key is the yield register. currently we assume that the yield register is always between 0-255, YOLO)
/// Indicate whether an [Insn::Once] instruction at a given program counter position has already been executed, well, once. /// Indicate whether an [Insn::Once] instruction at a given program counter position has already been executed, well, once.
once: SmallVec<u32, 4>, once: SmallVec<u32, 4>,
@@ -292,7 +292,7 @@ impl ProgramState {
registers, registers,
result_row: None, result_row: None,
last_compare: None, last_compare: None,
deferred_seek: None, deferred_seeks: vec![None; max_cursors],
ended_coroutine: Bitfield::new(), ended_coroutine: Bitfield::new(),
once: SmallVec::<u32, 4>::new(), once: SmallVec::<u32, 4>::new(),
regex_cache: RegexCache::new(), regex_cache: RegexCache::new(),
@@ -337,7 +337,7 @@ impl ProgramState {
.iter_mut() .iter_mut()
.for_each(|r| *r = Register::Value(Value::Null)); .for_each(|r| *r = Register::Value(Value::Null));
self.last_compare = None; self.last_compare = None;
self.deferred_seek = None; self.deferred_seeks.iter_mut().for_each(|s| *s = None);
self.ended_coroutine.0 = [0; 4]; self.ended_coroutine.0 = [0; 4];
self.regex_cache.like.clear(); self.regex_cache.like.clear();
self.interrupted = false; self.interrupted = false;