Do not count DELETEs occuring in an UPDATE stmt as separate changes

This commit is contained in:
Jussi Saurio
2025-10-14 16:11:43 +03:00
parent 0173d31c04
commit 87434b8a72
9 changed files with 23 additions and 5 deletions

View File

@@ -97,6 +97,7 @@ pub fn translate_analyze(
program.emit_insn(Insn::Delete {
cursor_id,
table_name: "sqlite_stat1".to_string(),
is_part_of_update: false,
});
program.emit_insn(Insn::Next {
cursor_id,

View File

@@ -859,6 +859,7 @@ fn emit_delete_insns(
program.emit_insn(Insn::Delete {
cursor_id: main_table_cursor_id,
table_name: table_name.to_string(),
is_part_of_update: false,
});
if let Some(index) = iteration_index {
@@ -867,6 +868,7 @@ fn emit_delete_insns(
program.emit_insn(Insn::Delete {
cursor_id: iteration_index_cursor,
table_name: index.name.clone(),
is_part_of_update: false,
});
}
}
@@ -1690,6 +1692,7 @@ fn emit_update_insns(
program.emit_insn(Insn::Delete {
cursor_id: target_table_cursor_id,
table_name: table_name.to_string(),
is_part_of_update: true,
});
}

View File

@@ -595,6 +595,7 @@ pub fn translate_drop_index(
program.emit_insn(Insn::Delete {
cursor_id: sqlite_schema_cursor_id,
table_name: "sqlite_schema".to_string(),
is_part_of_update: false,
});
program.resolve_label(next_label, program.offset());

View File

@@ -745,6 +745,7 @@ pub fn translate_drop_table(
program.emit_insn(Insn::Delete {
cursor_id: sqlite_schema_cursor_id_0,
table_name: SQLITE_TABLEID.to_string(),
is_part_of_update: false,
});
program.resolve_label(next_label, program.offset());
@@ -945,6 +946,7 @@ pub fn translate_drop_table(
program.emit_insn(Insn::Delete {
cursor_id: sqlite_schema_cursor_id_1,
table_name: SQLITE_TABLEID.to_string(),
is_part_of_update: false,
});
program.emit_insn(Insn::Insert {
cursor: sqlite_schema_cursor_id_1,
@@ -1005,6 +1007,7 @@ pub fn translate_drop_table(
program.emit_insn(Insn::Delete {
cursor_id: seq_cursor_id,
table_name: "sqlite_sequence".to_string(),
is_part_of_update: false,
});
program.resolve_label(continue_loop_label, program.offset());

View File

@@ -726,6 +726,7 @@ pub fn emit_upsert(
program.emit_insn(Insn::Delete {
cursor_id: tbl_cursor_id,
table_name: table.get_name().to_string(),
is_part_of_update: true,
});
program.emit_insn(Insn::Insert {
cursor: tbl_cursor_id,

View File

@@ -113,6 +113,7 @@ pub fn translate_create_materialized_view(
program.emit_insn(Insn::Delete {
cursor_id: view_cursor_id,
table_name: normalized_view_name.clone(),
is_part_of_update: false,
});
program.emit_insn(Insn::Next {
cursor_id: view_cursor_id,
@@ -409,6 +410,7 @@ pub fn translate_drop_view(
program.emit_insn(Insn::Delete {
cursor_id: sqlite_schema_cursor_id,
table_name: "sqlite_schema".to_string(),
is_part_of_update: false,
});
program.resolve_label(skip_delete_label, program.offset());

View File

@@ -6046,7 +6046,8 @@ pub fn op_delete(
load_insn!(
Delete {
cursor_id,
table_name
table_name,
is_part_of_update,
},
insn
);
@@ -6131,9 +6132,13 @@ pub fn op_delete(
}
state.op_delete_state.sub_state = OpDeleteSubState::MaybeCaptureRecord;
if !is_part_of_update {
// DELETEs do not count towards the total changes if they are part of an UPDATE statement,
// i.e. the DELETE and subsequent INSERT of a row are the same "change".
program
.n_change
.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
}
state.pc += 1;
Ok(InsnFunctionStepResult::Step)
}

View File

@@ -1141,7 +1141,7 @@ pub fn insn_to_row(
flag.0 as u16,
format!("intkey=r[{key_reg}] data=r[{record_reg}]"),
),
Insn::Delete { cursor_id, table_name } => (
Insn::Delete { cursor_id, table_name, .. } => (
"Delete",
*cursor_id as i32,
0,

View File

@@ -791,6 +791,8 @@ pub enum Insn {
Delete {
cursor_id: CursorID,
table_name: String,
/// Whether the DELETE is part of an UPDATE statement. If so, it doesn't count towards the change counter.
is_part_of_update: bool,
},
/// If P5 is not zero, then raise an SQLITE_CORRUPT_INDEX error if no matching index entry