From dc231abb2e0fe81cb1e96ab32febe7749c5794c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20Francoeur?= Date: Mon, 29 Sep 2025 17:18:19 -0400 Subject: [PATCH] fix self-insert bug --- core/translate/emitter.rs | 1 + core/translate/insert.rs | 7 +++++-- core/translate/plan.rs | 12 ++++++++++-- core/vdbe/builder.rs | 2 ++ testing/insert.test | 8 ++++++++ 5 files changed, 26 insertions(+), 4 deletions(-) diff --git a/core/translate/emitter.rs b/core/translate/emitter.rs index 37afee10e..3f57bc7ac 100644 --- a/core/translate/emitter.rs +++ b/core/translate/emitter.rs @@ -286,6 +286,7 @@ pub fn emit_query<'a>( // Allocate registers for result columns if t_ctx.reg_result_cols_start.is_none() { t_ctx.reg_result_cols_start = Some(program.alloc_registers(plan.result_columns.len())); + program.reg_result_cols_start = t_ctx.reg_result_cols_start } // Initialize cursors and other resources needed for query execution diff --git a/core/translate/insert.rs b/core/translate/insert.rs index 9c931276a..95a75c118 100644 --- a/core/translate/insert.rs +++ b/core/translate/insert.rs @@ -332,7 +332,7 @@ pub fn translate_insert( }; program.emit_insn(Insn::MakeRecord { - start_reg: yield_reg + 1, + start_reg: program.reg_result_cols_start.unwrap_or(yield_reg + 1), count: result.num_result_cols, dest_reg: record_reg, index_name: None, @@ -434,10 +434,13 @@ pub fn translate_insert( let conflict_rowid_reg = program.alloc_register(); if inserting_multiple_rows { + let select_result_start_reg = program + .reg_result_cols_start + .unwrap_or(yield_reg_opt.unwrap() + 1); translate_rows_multiple( &mut program, &insertion, - yield_reg_opt.unwrap() + 1, + select_result_start_reg, resolver, &temp_table_ctx, )?; diff --git a/core/translate/plan.rs b/core/translate/plan.rs index a7fd42dba..e8c1e66e4 100644 --- a/core/translate/plan.rs +++ b/core/translate/plan.rs @@ -719,8 +719,16 @@ impl TableReferences { } pub fn contains_table(&self, table: &Table) -> bool { - self.joined_tables.iter().any(|t| t.table == *table) - || self.outer_query_refs.iter().any(|t| t.table == *table) + self.joined_tables + .iter() + .map(|t| &t.table) + .chain(self.outer_query_refs.iter().map(|t| &t.table)) + .any(|t| match t { + Table::FromClauseSubquery(subquery_table) => { + subquery_table.plan.table_references.contains_table(table) + } + _ => t == table, + }) } pub fn extend(&mut self, other: TableReferences) { diff --git a/core/vdbe/builder.rs b/core/vdbe/builder.rs index 26bfd4adc..a0dff9cb4 100644 --- a/core/vdbe/builder.rs +++ b/core/vdbe/builder.rs @@ -123,6 +123,7 @@ pub struct ProgramBuilder { /// Current parent explain address, if any. current_parent_explain_idx: Option, pub param_ctx: ParamState, + pub(crate) reg_result_cols_start: Option, } #[derive(Debug, Clone)] @@ -209,6 +210,7 @@ impl ProgramBuilder { query_mode, current_parent_explain_idx: None, param_ctx: ParamState::default(), + reg_result_cols_start: None, } } diff --git a/testing/insert.test b/testing/insert.test index 4346b2031..1cd07bb15 100755 --- a/testing/insert.test +++ b/testing/insert.test @@ -650,3 +650,11 @@ do_execsql_test_on_specific_db {:memory:} set-explicit-null-default-value { SELECT * FROM t; } {1|2 1|} + +do_execsql_test_on_specific_db {:memory:} insert-select-nested-subquery { + CREATE TABLE t (x); + INSERT INTO T VALUES (1); + INSERT INTO T SELECT * FROM (SELECT * FROM t); + SELECT * FROM t; +} {1 +1}