Merge 'Implement BEGIN DEFERRED' from Diego Reis

As explained in [docs](https://sqlite.org/lang_transaction.html):
> "DEFERRED means that the transaction does not actually start until the
database is first accessed. Internally, the BEGIN DEFERRED statement
merely sets a flag on the database connection that turns off the
automatic commit that would normally occur when the last statement
finishes. This causes the transaction that is automatically started to
persist until an explicit COMMIT or ROLLBACK or until a rollback is
provoked by an error or an ON CONFLICT ROLLBACK clause. If the first
statement after BEGIN DEFERRED is a SELECT, then a read transaction is
started. Subsequent write statements will upgrade the transaction to a
write transaction if possible, or return SQLITE_BUSY. If the first
statement after BEGIN DEFERRED is a write statement, then a write
transaction is started. "
The transaction upgrade `read -> write` is already handled by the VDBE
in `Transaction`.
closes #1001

Reviewed-by: Pere Diaz Bou <pere-altea@homail.com>

Closes #1133
This commit is contained in:
Pekka Enberg
2025-03-17 16:02:28 +02:00
4 changed files with 11 additions and 6 deletions

View File

@@ -1,6 +1,6 @@
use crate::translate::{ProgramBuilder, ProgramBuilderOpts};
use crate::vdbe::insn::Insn;
use crate::{bail_parse_error, QueryMode, Result};
use crate::{QueryMode, Result};
use limbo_sqlite3_parser::ast::{Name, TransactionType};
pub fn translate_tx_begin(
@@ -18,7 +18,10 @@ pub fn translate_tx_begin(
let tx_type = tx_type.unwrap_or(TransactionType::Deferred);
match tx_type {
TransactionType::Deferred => {
bail_parse_error!("BEGIN DEFERRED not supported yet");
program.emit_insn(Insn::AutoCommit {
auto_commit: false,
rollback: false,
});
}
TransactionType::Immediate | TransactionType::Exclusive => {
program.emit_insn(Insn::Transaction { write: true });

View File

@@ -599,7 +599,7 @@ pub fn insn_to_str(
0,
OwnedValue::build_text(""),
0,
"".to_string(),
format!("write={}", write),
),
Insn::Goto { target_pc } => (
"Goto",

View File

@@ -1263,9 +1263,7 @@ impl Program {
}
}
if updated {
connection
.transaction_state
.replace(new_transaction_state.clone());
connection.transaction_state.replace(new_transaction_state);
}
}
state.pc += 1;

View File

@@ -10,3 +10,7 @@ do_execsql_test basic-tx-1 {
do_execsql_test basic-tx-2 {
BEGIN EXCLUSIVE; END
} {}
do_execsql_test basic-tx-3 {
BEGIN DEFERRED; END
} {}