mirror of
https://github.com/tursodatabase/limbo.git
synced 2025-08-04 01:58:16 +00:00
SeekRowid VM instruction
This commit is contained in:
parent
d965998cdf
commit
97dfae437c
3 changed files with 61 additions and 0 deletions
|
@ -270,6 +270,10 @@ impl ProgramBuilder {
|
|||
} => {
|
||||
*end_offset = to_offset;
|
||||
}
|
||||
Insn::SeekRowid { target_pc, .. } => {
|
||||
assert!(*target_pc < 0);
|
||||
*target_pc = to_offset;
|
||||
}
|
||||
_ => {
|
||||
todo!("missing resolve_label for {:?}", insn);
|
||||
}
|
||||
|
|
|
@ -383,6 +383,28 @@ pub fn insn_to_str(program: &Program, addr: InsnReference, insn: &Insn, indent:
|
|||
.unwrap_or(format!("cursor {}", cursor_id).as_str())
|
||||
),
|
||||
),
|
||||
Insn::SeekRowid {
|
||||
cursor_id,
|
||||
src_reg,
|
||||
target_pc,
|
||||
} => (
|
||||
"SeekRowid",
|
||||
*cursor_id as i32,
|
||||
*src_reg as i32,
|
||||
*target_pc as i32,
|
||||
OwnedValue::Text(Rc::new("".to_string())),
|
||||
0,
|
||||
format!(
|
||||
"if (r[{}]!={}.rowid) goto {}",
|
||||
src_reg,
|
||||
&program.cursor_ref[*cursor_id]
|
||||
.1
|
||||
.as_ref()
|
||||
.map(|x| x.get_name())
|
||||
.unwrap_or(format!("cursor {}", cursor_id).as_str()),
|
||||
target_pc
|
||||
),
|
||||
),
|
||||
Insn::DecrJumpZero { reg, target_pc } => (
|
||||
"DecrJumpZero",
|
||||
*reg as i32,
|
||||
|
|
|
@ -222,6 +222,13 @@ pub enum Insn {
|
|||
dest: usize,
|
||||
},
|
||||
|
||||
// Seek to a rowid in the cursor. If not found, jump to the given PC. Otherwise, continue to the next instruction.
|
||||
SeekRowid {
|
||||
cursor_id: CursorID,
|
||||
src_reg: usize,
|
||||
target_pc: BranchOffset,
|
||||
},
|
||||
|
||||
// Decrement the given register and jump to the given PC if the result is zero.
|
||||
DecrJumpZero {
|
||||
reg: usize,
|
||||
|
@ -779,6 +786,34 @@ impl Program {
|
|||
}
|
||||
state.pc += 1;
|
||||
}
|
||||
Insn::SeekRowid {
|
||||
cursor_id,
|
||||
src_reg,
|
||||
target_pc,
|
||||
} => {
|
||||
let cursor = cursors.get_mut(cursor_id).unwrap();
|
||||
let rowid = match &state.registers[*src_reg] {
|
||||
OwnedValue::Integer(rowid) => *rowid as u64,
|
||||
_ => {
|
||||
return Err(LimboError::InternalError(
|
||||
"SeekRowid: the value in the register is not an integer".into(),
|
||||
));
|
||||
}
|
||||
};
|
||||
match cursor.seek_rowid(rowid)? {
|
||||
CursorResult::Ok(found) => {
|
||||
if !found {
|
||||
state.pc = *target_pc;
|
||||
} else {
|
||||
state.pc += 1;
|
||||
}
|
||||
}
|
||||
CursorResult::IO => {
|
||||
// If there is I/O, the instruction is restarted.
|
||||
return Ok(StepResult::IO);
|
||||
}
|
||||
}
|
||||
}
|
||||
Insn::DecrJumpZero { reg, target_pc } => {
|
||||
assert!(*target_pc >= 0);
|
||||
match state.registers[*reg] {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue