diff --git a/core/translate/emitter.rs b/core/translate/emitter.rs index 0d48fd8d0..0068f7c34 100644 --- a/core/translate/emitter.rs +++ b/core/translate/emitter.rs @@ -1067,6 +1067,10 @@ fn emit_update_insns( }); } + if has_user_provided_rowid { + program.emit_insn(Insn::Delete { cursor_id }); + } + program.emit_insn(Insn::Insert { cursor: cursor_id, key_reg: rowid_set_clause_reg.unwrap_or(beg), diff --git a/core/translate/optimizer/mod.rs b/core/translate/optimizer/mod.rs index 0d718b17b..ba0e12f81 100644 --- a/core/translate/optimizer/mod.rs +++ b/core/translate/optimizer/mod.rs @@ -116,9 +116,6 @@ fn optimize_update_plan(plan: &mut UpdatePlan, schema: &Schema) -> Result<()> { plan.contains_constant_false_condition = true; return Ok(()); } - if let Some(ephemeral_plan) = &mut plan.ephemeral_plan { - optimize_select_plan(ephemeral_plan, schema)?; - } let _ = optimize_table_access( schema, &mut plan.table_references, diff --git a/core/translate/update.rs b/core/translate/update.rs index 9df50c30b..2f95b49d6 100644 --- a/core/translate/update.rs +++ b/core/translate/update.rs @@ -1,7 +1,8 @@ use std::rc::Rc; use crate::schema::{BTreeTable, Column, Type}; -use crate::translate::plan::{Operation, QueryDestination, SelectPlan}; +use crate::translate::optimizer::optimize_select_plan; +use crate::translate::plan::{Operation, QueryDestination, Search, SelectPlan}; use crate::vdbe::builder::CursorType; use crate::{ bail_parse_error, @@ -171,7 +172,6 @@ pub fn prepare_update_plan( }) .collect::, crate::LimboError>>()?; - let mut where_clause = vec![]; let mut result_columns = vec![]; if let Some(returning) = &mut body.returning { for rc in returning.iter_mut() { @@ -210,7 +210,8 @@ pub fn prepare_update_plan( accum || columns[*idx].is_rowid_alias }); - let (ephemeral_plan, where_clause) = if rowid_alias_used { + let (ephemeral_plan, mut where_clause) = if rowid_alias_used { + let mut where_clause = vec![]; let internal_id = program.table_reference_counter.next(); let joined_tables = vec![JoinedTable { @@ -260,7 +261,7 @@ pub fn prepare_update_plan( let temp_cursor_id = program.alloc_cursor_id(CursorType::BTreeTable(table.clone())); - let ephemeral_plan = SelectPlan { + let mut ephemeral_plan = SelectPlan { table_references, result_columns: vec![ResultSetColumn { expr: Expr::RowId { @@ -285,8 +286,23 @@ pub fn prepare_update_plan( distinctness: super::plan::Distinctness::NonDistinct, values: vec![], }; - (Some(ephemeral_plan), vec![]) + + optimize_select_plan(&mut ephemeral_plan, schema)?; + let table = ephemeral_plan + .table_references + .joined_tables() + .first() + .unwrap(); + if matches!(table.op, Operation::Search(Search::RowidEq { .. })) { + (None, vec![]) + } else { + (Some(ephemeral_plan), vec![]) + } } else { + (None, vec![]) + }; + + if ephemeral_plan.is_none() { // Parse the WHERE clause parse_where( body.where_clause.as_ref().map(|w| *w.clone()), @@ -294,7 +310,6 @@ pub fn prepare_update_plan( Some(&result_columns), &mut where_clause, )?; - (None, where_clause) }; // Parse the LIMIT/OFFSET clause