From 6d4e542522c8d09f10fecb5624436b20b84cb238 Mon Sep 17 00:00:00 2001 From: Ihor Andrianov Date: Wed, 16 Jul 2025 14:56:10 +0300 Subject: [PATCH 1/2] last set clause wins --- core/translate/update.rs | 49 +++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/core/translate/update.rs b/core/translate/update.rs index 30dd91d64..1d60eccc3 100644 --- a/core/translate/update.rs +++ b/core/translate/update.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use std::rc::Rc; use crate::schema::{BTreeTable, Column, Type}; @@ -141,32 +142,28 @@ pub fn prepare_update_plan( col_used_mask: ColumnUsedMask::default(), }]; let mut table_references = TableReferences::new(joined_tables, vec![]); - let set_clauses = body - .sets - .iter_mut() - .map(|set| { - let ident = normalize_ident(set.col_names[0].0.as_str()); - let col_index = table - .columns() - .iter() - .enumerate() - .find_map(|(i, col)| { - col.name - .as_ref() - .filter(|name| name.eq_ignore_ascii_case(&ident)) - .map(|_| i) - }) - .ok_or_else(|| { - crate::LimboError::ParseError(format!( - "column '{}' not found in table '{}'", - ident, table_name.0 - )) - })?; - let _ = bind_column_references(&mut set.expr, &mut table_references, None); - Ok((col_index, set.expr.clone())) - }) - .collect::, crate::LimboError>>()?; + let column_lookup: HashMap = table + .columns() + .iter() + .enumerate() + .filter_map(|(i, col)| col.name.as_ref().map(|name| (name.to_lowercase(), i))) + .collect(); + let mut set_clauses = Vec::with_capacity(body.sets.len()); + for set in &mut body.sets { + let ident = normalize_ident(set.col_names[0].0.as_str()); + let Some(col_index) = column_lookup.get(&ident) else { + bail_parse_error!("Parse error: no such column: {}", ident); + }; + + let _ = bind_column_references(&mut set.expr, &mut table_references, None); + + if let Some(idx) = set_clauses.iter().position(|(idx, _)| *idx == *col_index) { + set_clauses[idx].1 = set.expr.clone(); + } else { + set_clauses.push((*col_index, set.expr.clone())); + } + } let mut result_columns = vec![]; if let Some(returning) = &mut body.returning { @@ -334,7 +331,7 @@ pub fn prepare_update_plan( Ok(Plan::Update(UpdatePlan { table_references, - set_clauses, + set_clauses: set_clauses, where_clause, returning: Some(result_columns), order_by, From 37dd5da436dc95655139d0365a9f598ef73fa59a Mon Sep 17 00:00:00 2001 From: Ihor Andrianov Date: Wed, 16 Jul 2025 15:05:06 +0300 Subject: [PATCH 2/2] clippy --- core/translate/update.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/translate/update.rs b/core/translate/update.rs index 1d60eccc3..023b77601 100644 --- a/core/translate/update.rs +++ b/core/translate/update.rs @@ -149,6 +149,7 @@ pub fn prepare_update_plan( .enumerate() .filter_map(|(i, col)| col.name.as_ref().map(|name| (name.to_lowercase(), i))) .collect(); + let mut set_clauses = Vec::with_capacity(body.sets.len()); for set in &mut body.sets { let ident = normalize_ident(set.col_names[0].0.as_str()); @@ -331,7 +332,7 @@ pub fn prepare_update_plan( Ok(Plan::Update(UpdatePlan { table_references, - set_clauses: set_clauses, + set_clauses, where_clause, returning: Some(result_columns), order_by,