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 {
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 rowid = {
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 {
state.deferred_seek = Some(deferred_seek);
state.deferred_seeks[*cursor_id] = Some(deferred_seek);
return Ok(InsnFunctionStepResult::IO);
}
}
@ -1925,7 +1925,7 @@ pub fn op_row_id(
let Insn::RowId { cursor_id, dest } = insn else {
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 rowid = {
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 {
state.deferred_seek = Some(deferred_seek);
state.deferred_seeks[*cursor_id] = Some(deferred_seek);
return Ok(InsnFunctionStepResult::IO);
}
}
@ -2058,7 +2058,7 @@ pub fn op_deferred_seek(
else {
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;
Ok(InsnFunctionStepResult::Step)
}

View file

@ -267,7 +267,7 @@ pub struct ProgramState {
registers: Vec<Register>,
pub(crate) result_row: Option<Row>,
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)
/// Indicate whether an [Insn::Once] instruction at a given program counter position has already been executed, well, once.
once: SmallVec<u32, 4>,
@ -292,7 +292,7 @@ impl ProgramState {
registers,
result_row: None,
last_compare: None,
deferred_seek: None,
deferred_seeks: vec![None; max_cursors],
ended_coroutine: Bitfield::new(),
once: SmallVec::<u32, 4>::new(),
regex_cache: RegexCache::new(),
@ -337,7 +337,7 @@ impl ProgramState {
.iter_mut()
.for_each(|r| *r = Register::Value(Value::Null));
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.regex_cache.like.clear();
self.interrupted = false;