mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-17 08:34:19 +01:00
make query_start method to return bool - if result will have some rows or not
This commit is contained in:
@@ -87,7 +87,9 @@ pub trait IndexMethodCursor {
|
||||
/// For example, for 2 patterns ["SELECT * FROM {table} LIMIT ?", "SELECT * FROM {table} WHERE x = ?"], query_start(...) call can have following arguments:
|
||||
/// - [Integer(0), Integer(10)] - pattern "SELECT * FROM {table} LIMIT ?" was chosen with LIMIT parameter equals to 10
|
||||
/// - [Integer(1), Text("turso")] - pattern "SELECT * FROM {table} WHERE x = ?" was chosen with equality comparison equals to "turso"
|
||||
fn query_start(&mut self, values: &[Register]) -> Result<IOResult<()>>;
|
||||
///
|
||||
/// Returns false if query will produce no rows (similar to VFilter/Rewind op codes)
|
||||
fn query_start(&mut self, values: &[Register]) -> Result<IOResult<bool>>;
|
||||
|
||||
/// Moves cursor to the next response row
|
||||
/// Returns false if query exhausted all rows
|
||||
|
||||
@@ -151,7 +151,6 @@ pub struct VectorSparseInvertedIndexMethodCursor {
|
||||
delete_state: VectorSparseInvertedIndexDeleteState,
|
||||
search_state: VectorSparseInvertedIndexSearchState,
|
||||
search_result: VecDeque<(i64, f64)>,
|
||||
search_row: Option<(i64, f64)>,
|
||||
}
|
||||
|
||||
impl IndexMethod for VectorSparseInvertedIndexMethod {
|
||||
@@ -199,7 +198,6 @@ impl VectorSparseInvertedIndexMethodCursor {
|
||||
scratch_cursor: None,
|
||||
main_btree: None,
|
||||
search_result: VecDeque::new(),
|
||||
search_row: None,
|
||||
create_state: VectorSparseInvertedIndexCreateState::Init,
|
||||
insert_state: VectorSparseInvertedIndexInsertState::Init,
|
||||
delete_state: VectorSparseInvertedIndexDeleteState::Init,
|
||||
@@ -459,7 +457,7 @@ impl IndexMethodCursor for VectorSparseInvertedIndexMethodCursor {
|
||||
}
|
||||
}
|
||||
|
||||
fn query_start(&mut self, values: &[Register]) -> Result<IOResult<()>> {
|
||||
fn query_start(&mut self, values: &[Register]) -> Result<IOResult<bool>> {
|
||||
let Some(scratch) = &mut self.scratch_cursor else {
|
||||
return Err(LimboError::InternalError(
|
||||
"cursor must be opened".to_string(),
|
||||
@@ -521,7 +519,7 @@ impl IndexMethodCursor for VectorSparseInvertedIndexMethodCursor {
|
||||
continue;
|
||||
}
|
||||
let position = p[*idx];
|
||||
let key = ImmutableRecord::from_values(&[Value::Integer(position as i64)], 2);
|
||||
let key = ImmutableRecord::from_values(&[Value::Integer(position as i64)], 1);
|
||||
self.search_state = VectorSparseInvertedIndexSearchState::Seek {
|
||||
collected: collected.take(),
|
||||
positions: positions.take(),
|
||||
@@ -551,7 +549,7 @@ impl IndexMethodCursor for VectorSparseInvertedIndexMethodCursor {
|
||||
limit: *limit,
|
||||
};
|
||||
}
|
||||
SeekResult::TryAdvance => {
|
||||
SeekResult::TryAdvance | SeekResult::NotFound => {
|
||||
self.search_state = VectorSparseInvertedIndexSearchState::Next {
|
||||
collected: collected.take(),
|
||||
positions: positions.take(),
|
||||
@@ -560,9 +558,6 @@ impl IndexMethodCursor for VectorSparseInvertedIndexMethodCursor {
|
||||
limit: *limit,
|
||||
};
|
||||
}
|
||||
SeekResult::NotFound => {
|
||||
return Err(LimboError::Corrupt("inverted index corrupted".to_string()))
|
||||
}
|
||||
}
|
||||
}
|
||||
VectorSparseInvertedIndexSearchState::Read {
|
||||
@@ -637,7 +632,7 @@ impl IndexMethodCursor for VectorSparseInvertedIndexMethodCursor {
|
||||
let Some(rowid) = rowids.as_ref().unwrap().last() else {
|
||||
let distances = distances.take().unwrap();
|
||||
self.search_result = distances.iter().map(|(d, i)| (*i, d.0)).collect();
|
||||
return Ok(IOResult::Done(()));
|
||||
return Ok(IOResult::Done(!self.search_result.is_empty()));
|
||||
};
|
||||
let result = return_if_io!(
|
||||
main.seek(SeekKey::TableRowId(*rowid), SeekOp::GE { eq_only: true })
|
||||
@@ -709,17 +704,17 @@ impl IndexMethodCursor for VectorSparseInvertedIndexMethodCursor {
|
||||
}
|
||||
|
||||
fn query_rowid(&mut self) -> Result<IOResult<Option<i64>>> {
|
||||
let result = self.search_row.as_ref().unwrap();
|
||||
let result = self.search_result.front().unwrap();
|
||||
Ok(IOResult::Done(Some(result.0)))
|
||||
}
|
||||
|
||||
fn query_column(&mut self, _: usize) -> Result<IOResult<Value>> {
|
||||
let result = self.search_row.as_ref().unwrap();
|
||||
let result = self.search_result.front().unwrap();
|
||||
Ok(IOResult::Done(Value::Float(result.1)))
|
||||
}
|
||||
|
||||
fn query_next(&mut self) -> Result<IOResult<bool>> {
|
||||
self.search_row = self.search_result.pop_front();
|
||||
Ok(IOResult::Done(self.search_row.is_some()))
|
||||
let _ = self.search_result.pop_front();
|
||||
Ok(IOResult::Done(!self.search_result.is_empty()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -720,10 +720,7 @@ pub fn open_loop(
|
||||
cursor_id: index_cursor_id.expect("IndexMethod requires a index cursor"),
|
||||
start_reg,
|
||||
count_reg: query.arguments.len() + 1,
|
||||
});
|
||||
program.emit_insn(Insn::Next {
|
||||
cursor_id: index_cursor_id.expect("IndexMethod requires a index cursor"),
|
||||
pc_if_next: loop_end,
|
||||
pc_if_empty: loop_end,
|
||||
});
|
||||
program.preassign_label_to_next_insn(loop_start);
|
||||
if let Some(table_cursor_id) = table_cursor_id {
|
||||
|
||||
@@ -819,6 +819,9 @@ impl ProgramBuilder {
|
||||
Insn::IdxLT { target_pc, .. } => {
|
||||
resolve(target_pc, "IdxLT");
|
||||
}
|
||||
Insn::IndexMethodQuery { pc_if_empty, .. } => {
|
||||
resolve(pc_if_empty, "IndexMethodQuery");
|
||||
}
|
||||
Insn::IsNull { reg: _, target_pc } => {
|
||||
resolve(target_pc, "IsNull");
|
||||
}
|
||||
|
||||
@@ -7248,6 +7248,7 @@ pub fn op_index_method_query(
|
||||
cursor_id,
|
||||
start_reg,
|
||||
count_reg,
|
||||
pc_if_empty,
|
||||
},
|
||||
insn
|
||||
);
|
||||
@@ -7260,8 +7261,12 @@ pub fn op_index_method_query(
|
||||
}
|
||||
let cursor = state.cursors[*cursor_id].as_mut().unwrap();
|
||||
let cursor = cursor.as_index_method_mut();
|
||||
return_if_io!(cursor.query_start(&state.registers[*start_reg..*start_reg + *count_reg]));
|
||||
state.pc += 1;
|
||||
let has_rows = return_if_io!(cursor.query_start(&state.registers[*start_reg..*start_reg + *count_reg]));
|
||||
if !has_rows {
|
||||
state.pc = pc_if_empty.as_offset_int();
|
||||
} else {
|
||||
state.pc += 1;
|
||||
}
|
||||
Ok(InsnFunctionStepResult::Step)
|
||||
}
|
||||
|
||||
|
||||
@@ -895,6 +895,7 @@ pub enum Insn {
|
||||
cursor_id: CursorID,
|
||||
start_reg: usize,
|
||||
count_reg: usize,
|
||||
pc_if_empty: BranchOffset,
|
||||
},
|
||||
|
||||
/// Deletes an entire database table or index whose root page in the database file is given by P1.
|
||||
|
||||
Reference in New Issue
Block a user