mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-23 17:05:36 +01:00
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:
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user