Merge 'vdbe: Disallow checkpointing in transaction' from Jussi Saurio

Closes #2358

Reviewed-by: Preston Thorpe (@PThorpe92)

Closes #2365
This commit is contained in:
Jussi Saurio
2025-07-31 16:12:49 +03:00
3 changed files with 12 additions and 0 deletions

View File

@@ -55,6 +55,8 @@ pub enum LimboError {
IntegerOverflow,
#[error("Schema is locked for write")]
SchemaLocked,
#[error("Runtime error: database table is locked")]
TableLocked,
#[error("Error: Resource is read-only")]
ReadOnly,
#[error("Database is busy")]

View File

@@ -334,6 +334,13 @@ pub fn op_checkpoint(
else {
unreachable!("unexpected Insn {:?}", insn)
};
if !program.connection.auto_commit.get() {
// TODO: sqlite returns "Runtime error: database table is locked (6)" when a table is in use
// when a checkpoint is attempted. We don't have table locks, so return TableLocked for any
// attempt to checkpoint in an interactive transaction. This does not end the transaction,
// however.
return Err(LimboError::TableLocked);
}
let result = program.connection.checkpoint(*checkpoint_mode);
match result {
Ok(CheckpointResult {

View File

@@ -757,7 +757,10 @@ pub fn handle_program_error(
err: &LimboError,
) -> Result<()> {
match err {
// Transaction errors, e.g. trying to start a nested transaction, do not cause a rollback.
LimboError::TxError(_) => {}
// Table locked errors, e.g. trying to checkpoint in an interactive transaction, do not cause a rollback.
LimboError::TableLocked => {}
_ => {
let state = connection.transaction_state.get();
if let TransactionState::Write { schema_did_change } = state {