From 957fe1b44678e3bc8b6300d69ab55a6b8bcf2e1c Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Tue, 13 May 2025 08:54:25 +0300 Subject: [PATCH 1/2] Fix infinite loop when inserting multiple rows --- core/translate/insert.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/core/translate/insert.rs b/core/translate/insert.rs index 233d623c9..8a5d86f30 100644 --- a/core/translate/insert.rs +++ b/core/translate/insert.rs @@ -10,7 +10,6 @@ use crate::schema::{IndexColumn, Table}; use crate::util::normalize_ident; use crate::vdbe::builder::{ProgramBuilderOpts, QueryMode}; use crate::vdbe::insn::{IdxInsertFlags, RegisterOrLiteral}; -use crate::vdbe::BranchOffset; use crate::{ schema::{Column, Schema}, vdbe::{ @@ -137,7 +136,7 @@ pub fn translate_insert( let record_register = program.alloc_register(); let halt_label = program.allocate_label(); - let mut loop_start_offset = BranchOffset::Offset(0); + let loop_start_label = program.allocate_label(); let inserting_multiple_rows = values.len() > 1; @@ -152,7 +151,7 @@ pub fn translate_insert( start_offset: start_offset_label, }); - program.resolve_label(start_offset_label, program.offset()); + program.preassign_label_to_next_insn(start_offset_label); for (i, value) in values.iter().enumerate() { populate_column_registers( @@ -181,7 +180,7 @@ pub fn translate_insert( // Main loop // FIXME: rollback is not implemented. E.g. if you insert 2 rows and one fails to unique constraint violation, // the other row will still be inserted. - loop_start_offset = program.offset(); + program.resolve_label(loop_start_label, program.offset()); program.emit_insn(Insn::Yield { yield_reg, end_offset: halt_label, @@ -397,7 +396,7 @@ pub fn translate_insert( if inserting_multiple_rows { // For multiple rows, loop back program.emit_insn(Insn::Goto { - target_pc: loop_start_offset, + target_pc: loop_start_label, }); } From 44e282f6308f1bbce1f79e5bc2f389e1981bfd3b Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Tue, 13 May 2025 09:03:01 +0300 Subject: [PATCH 2/2] Add multi-row insert regression test --- testing/insert.test | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/testing/insert.test b/testing/insert.test index 03b967294..3ace39a8c 100755 --- a/testing/insert.test +++ b/testing/insert.test @@ -173,3 +173,10 @@ do_execsql_test_on_specific_db {:memory:} named-insert-2 { INSERT INTO test (col_b, col_d, col_c) VALUES ('1', '2', '4'); SELECT * FROM test; } {1|Empty|1|4|2} + +do_execsql_test_on_specific_db {:memory:} multi-rows { + CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, col); + INSERT INTO test (col) VALUES (1),(1); + SELECT * FROM test; +} {1|1 +2|1}