implement rollback translation

This commit is contained in:
Pere Diaz Bou
2025-06-19 11:39:10 +02:00
parent 325aa320ba
commit d66c683a4c
3 changed files with 52 additions and 4 deletions

View File

@@ -26,6 +26,7 @@ pub(crate) mod plan;
pub(crate) mod planner;
pub(crate) mod pragma;
pub(crate) mod result_row;
pub(crate) mod rollback;
pub(crate) mod schema;
pub(crate) mod select;
pub(crate) mod subquery;
@@ -43,6 +44,7 @@ use alter::translate_alter_table;
use index::{translate_create_index, translate_drop_index};
use insert::translate_insert;
use limbo_sqlite3_parser::ast::{self, Delete, Insert};
use rollback::translate_rollback;
use schema::{translate_create_table, translate_create_virtual_table, translate_drop_table};
use select::translate_select;
use std::rc::Rc;
@@ -183,7 +185,10 @@ pub fn translate_inner(
}
ast::Stmt::Reindex { .. } => bail_parse_error!("REINDEX not supported yet"),
ast::Stmt::Release(_) => bail_parse_error!("RELEASE not supported yet"),
ast::Stmt::Rollback { .. } => bail_parse_error!("ROLLBACK not supported yet"),
ast::Stmt::Rollback {
tx_name,
savepoint_name,
} => translate_rollback(query_mode, schema, syms, program, tx_name, savepoint_name)?,
ast::Stmt::Savepoint(_) => bail_parse_error!("SAVEPOINT not supported yet"),
ast::Stmt::Select(select) => {
translate_select(

View File

@@ -0,0 +1,31 @@
use limbo_sqlite3_parser::ast::Name;
use crate::{
schema::Schema,
translate::emitter::TransactionMode,
vdbe::{
builder::{ProgramBuilder, QueryMode},
insn::Insn,
},
Result, SymbolTable,
};
pub fn translate_rollback(
_query_mode: QueryMode,
_schema: &Schema,
_syms: &SymbolTable,
mut program: ProgramBuilder,
txn_name: Option<Name>,
savepoint_name: Option<Name>,
) -> Result<ProgramBuilder> {
assert!(
txn_name.is_none() && savepoint_name.is_none(),
"txn_name and savepoint not supported yet"
);
program.emit_insn(Insn::AutoCommit {
auto_commit: true,
rollback: true,
});
program.epilogue_maybe_rollback(TransactionMode::None, true);
Ok(program)
}

View File

@@ -335,10 +335,14 @@ impl ProgramBuilder {
self.emit_insn(Insn::ResultRow { start_reg, count });
}
fn emit_halt(&mut self) {
fn emit_halt(&mut self, rollback: bool) {
self.emit_insn(Insn::Halt {
err_code: 0,
description: String::new(),
description: if rollback {
"rollback".to_string()
} else {
String::new()
},
});
}
@@ -745,8 +749,16 @@ impl ProgramBuilder {
/// Note that although these are the final instructions, typically an SQLite
/// query will jump to the Transaction instruction via init_label.
pub fn epilogue(&mut self, txn_mode: TransactionMode) {
self.epilogue_maybe_rollback(txn_mode, false);
}
/// Clean up and finalize the program, resolving any remaining labels
/// Note that although these are the final instructions, typically an SQLite
/// query will jump to the Transaction instruction via init_label.
/// "rollback" flag is used to determine if halt should rollback the transaction.
pub fn epilogue_maybe_rollback(&mut self, txn_mode: TransactionMode, rollback: bool) {
if self.nested_level == 0 {
self.emit_halt();
self.emit_halt(rollback);
self.preassign_label_to_next_insn(self.init_label);
match txn_mode {