mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-12 03:34:20 +01:00
Adjust Transaction OpCode to accept schema cookie + check if cookie changed
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 => {}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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}"),
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user