core/mvcc: fix new rowid

next rowid was being tracked globally for all tables and restarted to 0
every time database was opened
This commit is contained in:
Pere Diaz Bou
2025-08-04 12:17:03 +02:00
parent 83a658d3d6
commit f26e442597
4 changed files with 47 additions and 3 deletions

View File

@@ -130,4 +130,25 @@ impl<Clock: LogicalClock> MvccLazyCursor<Clock> {
pub fn rewind(&mut self) {
self.current_pos = CursorPosition::BeforeFirst;
}
pub fn last(&mut self) {
let last_rowid = self.db.get_last_rowid(self.table_id);
if let Some(last_rowid) = last_rowid {
self.current_pos = CursorPosition::Loaded(RowID {
table_id: self.table_id,
row_id: last_rowid,
});
} else {
self.current_pos = CursorPosition::BeforeFirst;
}
}
pub fn get_next_rowid(&mut self) -> i64 {
self.last();
match self.current_pos {
CursorPosition::Loaded(id) => id.row_id + 1,
CursorPosition::BeforeFirst => i64::MIN,
CursorPosition::End => i64::MAX,
}
}
}

View File

@@ -15,6 +15,7 @@ use parking_lot::RwLock;
use std::collections::HashSet;
use std::fmt::Debug;
use std::marker::PhantomData;
use std::ops::Bound;
use std::rc::Rc;
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
@@ -1222,6 +1223,18 @@ impl<Clock: LogicalClock> MvStore<Clock> {
}
Ok(())
}
pub fn get_last_rowid(&self, table_id: u64) -> Option<i64> {
let last_rowid = self
.rows
.upper_bound(Bound::Included(&RowID {
table_id,
row_id: i64::MAX,
}))
.map(|entry| Some(entry.key().row_id))
.unwrap_or(None);
last_rowid
}
}
/// A write-write conflict happens when transaction T_current attempts to update a

View File

@@ -5496,6 +5496,10 @@ impl BTreeCursor {
self.pager
.do_allocate_page(page_type, offset, BtreePageAllocMode::Any)
}
pub fn get_mvcc_cursor(&self) -> Rc<RefCell<MvCursor>> {
self.mv_cursor.as_ref().unwrap().clone()
}
}
#[derive(Debug, thiserror::Error)]

View File

@@ -15,6 +15,7 @@ use crate::util::{normalize_ident, IOExt as _};
use crate::vdbe::insn::InsertFlags;
use crate::vdbe::registers_to_ref_values;
use crate::vector::{vector_concat, vector_slice};
use crate::MvCursor;
use crate::{
error::{
LimboError, SQLITE_CONSTRAINT, SQLITE_CONSTRAINT_NOTNULL, SQLITE_CONSTRAINT_PRIMARYKEY,
@@ -61,8 +62,7 @@ use crate::{
};
use crate::{
info, turso_assert, BufferPool, MvCursor, OpenFlags, RefValue, Row, StepResult,
TransactionState,
info, turso_assert, BufferPool, OpenFlags, RefValue, Row, StepResult, TransactionState,
};
use super::{
@@ -5481,7 +5481,13 @@ pub fn op_new_rowid(
};
if let Some(mv_store) = mv_store {
let rowid = mv_store.get_next_rowid();
let rowid = {
let mut cursor = state.get_cursor(*cursor);
let cursor = cursor.as_btree_mut();
let mvcc_cursor = cursor.get_mvcc_cursor();
let mut mvcc_cursor = RefCell::borrow_mut(&mvcc_cursor);
mvcc_cursor.get_next_rowid()
};
state.registers[*rowid_reg] = Register::Value(Value::Integer(rowid));
state.pc += 1;
return Ok(InsnFunctionStepResult::Step);