Remove SeekOp::EQ and encode eq_only in LE&GE - needed for iteration direction aware equality seeks

This commit is contained in:
Jussi Saurio 2025-06-05 10:56:47 +03:00
parent ae6a943e43
commit 2bac140d73
8 changed files with 150 additions and 78 deletions

View file

@ -1352,7 +1352,10 @@ pub fn op_column(
};
let mut table_cursor = state.get_cursor(table_cursor_id);
let table_cursor = table_cursor.as_btree_mut();
match table_cursor.seek(SeekKey::TableRowId(rowid.unwrap()), SeekOp::EQ)? {
match table_cursor.seek(
SeekKey::TableRowId(rowid.unwrap()),
SeekOp::GE { eq_only: true },
)? {
CursorResult::Ok(_) => None,
CursorResult::IO => Some((index_cursor_id, table_cursor_id)),
}
@ -1914,7 +1917,7 @@ pub fn op_row_id(
};
let mut table_cursor = state.get_cursor(table_cursor_id);
let table_cursor = table_cursor.as_btree_mut();
match table_cursor.seek(SeekKey::TableRowId(rowid), SeekOp::EQ)? {
match table_cursor.seek(SeekKey::TableRowId(rowid), SeekOp::GE { eq_only: true })? {
CursorResult::Ok(_) => None,
CursorResult::IO => Some((index_cursor_id, table_cursor_id)),
}
@ -2000,7 +2003,9 @@ pub fn op_seek_rowid(
};
match rowid {
Some(rowid) => {
let found = return_if_io!(cursor.seek(SeekKey::TableRowId(rowid), SeekOp::EQ));
let found = return_if_io!(
cursor.seek(SeekKey::TableRowId(rowid), SeekOp::GE { eq_only: true })
);
if !found {
target_pc.to_offset_int()
} else {
@ -2046,6 +2051,7 @@ pub fn op_seek(
num_regs,
target_pc,
is_index,
..
}
| Insn::SeekGT {
cursor_id,
@ -2060,6 +2066,7 @@ pub fn op_seek(
num_regs,
target_pc,
is_index,
..
}
| Insn::SeekLT {
cursor_id,
@ -2076,19 +2083,22 @@ pub fn op_seek(
"target_pc should be an offset, is: {:?}",
target_pc
);
let eq_only = match insn {
Insn::SeekGE { eq_only, .. } | Insn::SeekLE { eq_only, .. } => *eq_only,
_ => false,
};
let op = match insn {
Insn::SeekGE { .. } => SeekOp::GE,
Insn::SeekGE { eq_only, .. } => SeekOp::GE { eq_only: *eq_only },
Insn::SeekGT { .. } => SeekOp::GT,
Insn::SeekLE { .. } => SeekOp::LE,
Insn::SeekLE { eq_only, .. } => SeekOp::LE { eq_only: *eq_only },
Insn::SeekLT { .. } => SeekOp::LT,
_ => unreachable!("unexpected Insn {:?}", insn),
};
let op_name = match op {
SeekOp::GE => "SeekGE",
SeekOp::GE { .. } => "SeekGE",
SeekOp::GT => "SeekGT",
SeekOp::LE => "SeekLE",
SeekOp::LE { .. } => "SeekLE",
SeekOp::LT => "SeekLT",
_ => unreachable!("unexpected SeekOp {:?}", op),
};
if *is_index {
let found = {
@ -3928,7 +3938,9 @@ pub fn op_idx_delete(
{
let mut cursor = state.get_cursor(*cursor_id);
let cursor = cursor.as_btree_mut();
return_if_io!(cursor.seek(SeekKey::IndexKey(&record), SeekOp::EQ));
return_if_io!(
cursor.seek(SeekKey::IndexKey(&record), SeekOp::GE { eq_only: true })
);
tracing::debug!(
"op_idx_delete(seek={}, record={} rowid={:?})",
&record,
@ -4151,7 +4163,8 @@ pub fn op_no_conflict(
return Ok(InsnFunctionStepResult::Step);
}
let conflict = return_if_io!(cursor.seek(SeekKey::IndexKey(record), SeekOp::EQ));
let conflict =
return_if_io!(cursor.seek(SeekKey::IndexKey(record), SeekOp::GE { eq_only: true }));
drop(cursor_ref);
if !conflict {
state.pc = target_pc.to_offset_int();
@ -4925,10 +4938,10 @@ pub fn op_found(
}
};
return_if_io!(cursor.seek(SeekKey::IndexKey(&record), SeekOp::EQ))
return_if_io!(cursor.seek(SeekKey::IndexKey(&record), SeekOp::GE { eq_only: true }))
} else {
let record = make_record(&state.registers, record_reg, num_regs);
return_if_io!(cursor.seek(SeekKey::IndexKey(&record), SeekOp::EQ))
return_if_io!(cursor.seek(SeekKey::IndexKey(&record), SeekOp::GE { eq_only: true }))
}
};