Merge 'Implement RowData opcode' from meteorgan

The `RowData` opcode is required to implement #1575.
I haven't found a ideal way to test this PR independently, but I
verified its functionality while working on #1575(to be committed soon),
and it performs effectively.

Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #1756
This commit is contained in:
Jussi Saurio
2025-06-20 21:58:47 +03:00
4 changed files with 47 additions and 1 deletions

View File

@@ -1917,6 +1917,36 @@ pub fn op_blob(
Ok(InsnFunctionStepResult::Step)
}
pub fn op_row_data(
program: &Program,
state: &mut ProgramState,
insn: &Insn,
pager: &Rc<Pager>,
mv_store: Option<&Rc<MvStore>>,
) -> Result<InsnFunctionStepResult> {
let Insn::RowData { cursor_id, dest } = insn else {
unreachable!("unexpected Insn {:?}", insn)
};
let record = {
let mut cursor_ref =
must_be_btree_cursor!(*cursor_id, program.cursor_ref, state, "RowData");
let cursor = cursor_ref.as_btree_mut();
let record_option = return_if_io!(cursor.record());
let ret = record_option
.ok_or_else(|| LimboError::InternalError("RowData: cursor has no record".to_string()))?
.clone();
ret
};
let reg = &mut state.registers[*dest];
*reg = Register::Record(record);
state.pc += 1;
Ok(InsnFunctionStepResult::Step)
}
pub fn op_row_id(
program: &Program,
state: &mut ProgramState,

View File

@@ -1603,6 +1603,15 @@ pub fn insn_to_str(
0,
format!("roots={:?} message_register={}", roots, message_register),
),
Insn::RowData { cursor_id, dest } => (
"RowData",
*cursor_id as i32,
*dest as i32,
0,
Value::build_text(""),
0,
format!("r[{}] = data", *dest),
),
};
format!(
"{:<4} {:<17} {:<4} {:<4} {:<4} {:<13} {:<2} {}",

View File

@@ -510,6 +510,12 @@ pub enum Insn {
dest: usize,
},
/// Read a complete row of data from the current cursor and write it to the destination register.
RowData {
cursor_id: CursorID,
dest: usize,
},
/// Read the rowid of the current row.
RowId {
cursor_id: CursorID,
@@ -1034,6 +1040,7 @@ impl Insn {
Insn::RealAffinity { .. } => execute::op_real_affinity,
Insn::String8 { .. } => execute::op_string8,
Insn::Blob { .. } => execute::op_blob,
Insn::RowData { .. } => execute::op_row_data,
Insn::RowId { .. } => execute::op_row_id,
Insn::IdxRowId { .. } => execute::op_idx_row_id,
Insn::SeekRowid { .. } => execute::op_seek_rowid,

View File

@@ -317,7 +317,7 @@ impl ProgramState {
self.json_cache.clear()
}
pub fn get_cursor<'a>(&'a self, cursor_id: CursorID) -> std::cell::RefMut<'a, Cursor> {
pub fn get_cursor(&self, cursor_id: CursorID) -> std::cell::RefMut<Cursor> {
let cursors = self.cursors.borrow_mut();
std::cell::RefMut::map(cursors, |c| {
c.get_mut(cursor_id)