Fix: check deferred FK violations before committing to WAL

DEFERRED was a bit too deferred - it allowed the dirty pages to be
written out to WAL before checking for violations, resulting in the
violations effectively being committed even though the transaction
ended up aborting
This commit is contained in:
Jussi Saurio
2025-10-20 14:00:49 +03:00
parent bebe230b05
commit 10532544dc

View File

@@ -2165,21 +2165,21 @@ pub fn halt(
let auto_commit = program.connection.auto_commit.load(Ordering::SeqCst);
tracing::trace!("halt(auto_commit={})", auto_commit);
if auto_commit {
let res = program.commit_txn(pager.clone(), state, mv_store, false);
if res.is_ok()
&& program.connection.foreign_keys_enabled()
// In autocommit mode, a statement that leaves deferred violations must fail here.
if program.connection.foreign_keys_enabled()
&& program
.connection
.fk_deferred_violations
.swap(0, Ordering::AcqRel)
> 0
{
// In autocommit mode, a statement that leaves deferred violations must fail here.
return Err(LimboError::Constraint(
"foreign key constraint failed".to_string(),
));
}
res.map(Into::into)
program
.commit_txn(pager.clone(), state, mv_store, false)
.map(Into::into)
} else {
Ok(InsnFunctionStepResult::Done)
}