Adjust Transaction OpCode to accept schema cookie + check if cookie changed

This commit is contained in:
pedrocarlo
2025-07-21 22:27:42 -03:00
parent f8eb4ba14d
commit c567636deb
6 changed files with 31 additions and 8 deletions

View File

@@ -123,7 +123,9 @@ pub fn translate_inner(
ast::Stmt::Attach { expr, db_name, key } => {
attach::translate_attach(&expr, &db_name, &key, schema, syms, program)?
}
ast::Stmt::Begin(tx_type, tx_name) => translate_tx_begin(tx_type, tx_name, program)?,
ast::Stmt::Begin(tx_type, tx_name) => {
translate_tx_begin(tx_type, tx_name, &schema, program)?
}
ast::Stmt::Commit(tx_name) => translate_tx_commit(tx_name, program)?,
ast::Stmt::CreateIndex {
unique,

View File

@@ -1,3 +1,4 @@
use crate::schema::Schema;
use crate::translate::{ProgramBuilder, ProgramBuilderOpts};
use crate::vdbe::insn::Insn;
use crate::Result;
@@ -6,6 +7,7 @@ use turso_sqlite3_parser::ast::{Name, TransactionType};
pub fn translate_tx_begin(
tx_type: Option<TransactionType>,
_tx_name: Option<Name>,
schema: &Schema,
mut program: ProgramBuilder,
) -> Result<ProgramBuilder> {
program.extend(&ProgramBuilderOpts {
@@ -22,7 +24,11 @@ pub fn translate_tx_begin(
});
}
TransactionType::Immediate | TransactionType::Exclusive => {
program.emit_insn(Insn::Transaction { db: 0, write: true });
program.emit_insn(Insn::Transaction {
db: 0,
write: true,
schema_cookie: schema.schema_version,
});
// TODO: Emit transaction instruction on temporary tables when we support them.
program.emit_insn(Insn::AutoCommit {
auto_commit: false,

View File

@@ -771,8 +771,13 @@ impl ProgramBuilder {
TransactionMode::Read => self.emit_insn(Insn::Transaction {
db: 0,
write: false,
schema_cookie: 0, // TODO: placeholder until we have epilogue being called only in one place
}),
TransactionMode::Write => self.emit_insn(Insn::Transaction {
db: 0,
write: true,
schema_cookie: 0, // TODO: placeholder until we have epilogue being called only in one place
}),
TransactionMode::Write => self.emit_insn(Insn::Transaction { db: 0, write: true }),
TransactionMode::None => {}
}

View File

@@ -1989,9 +1989,18 @@ pub fn op_transaction(
_pager: &Rc<Pager>,
mv_store: Option<&Arc<MvStore>>,
) -> Result<InsnFunctionStepResult> {
let Insn::Transaction { db, write } = insn else {
let Insn::Transaction {
db,
write,
schema_cookie,
} = insn
else {
unreachable!("unexpected Insn {:?}", insn)
};
let header_schema_cookie = header_accessor::get_schema_cookie(pager)?;
if header_schema_cookie != *schema_cookie {
return Err(LimboError::SchemaUpdated);
}
let conn = program.connection.clone();
if *write && conn._db.open_flags.contains(OpenFlags::ReadOnly) {
return Err(LimboError::ReadOnly);

View File

@@ -647,11 +647,11 @@ pub fn insn_to_str(
0,
"".to_string(),
),
Insn::Transaction { db, write } => (
Insn::Transaction { db, write , schema_cookie} => (
"Transaction",
*db as i32,
*write as i32,
0,
*schema_cookie as i32,
Value::build_text(""),
0,
format!("iDb={db} write={write}"),

View File

@@ -459,8 +459,9 @@ pub enum Insn {
/// Start a transaction.
Transaction {
db: usize, // p1
write: bool, // p2
db: usize, // p1
write: bool, // p2
schema_cookie: u32, // p3
},
/// Set database auto-commit mode and potentially rollback.