diff --git a/core/translate/emitter.rs b/core/translate/emitter.rs index 4169ba617..79db8361b 100644 --- a/core/translate/emitter.rs +++ b/core/translate/emitter.rs @@ -824,7 +824,7 @@ fn emit_update_insns( program.emit_insn(Insn::Copy { src_reg: beg, dst_reg: beg + 1, - amount: 0, + extra_amount: 0, }) } @@ -941,14 +941,14 @@ fn emit_update_insns( program.emit_insn(Insn::Copy { src_reg: idx_cols_start_reg + col.pos_in_table, dst_reg: idx_start_reg + i, - amount: 0, + extra_amount: 0, }); } // last register is the rowid program.emit_insn(Insn::Copy { src_reg: rowid_reg, dst_reg: idx_start_reg + num_cols, - amount: 0, + extra_amount: 0, }); // this record will be inserted into the index later @@ -1247,7 +1247,7 @@ pub fn emit_cdc_patch_record( program.emit_insn(Insn::Copy { src_reg: rowid_reg, dst_reg: columns_reg + rowid_alias_position, - amount: 0, + extra_amount: 0, }); program.emit_insn(Insn::MakeRecord { start_reg: columns_reg, @@ -1274,7 +1274,7 @@ pub fn emit_cdc_full_record( program.emit_insn(Insn::Copy { src_reg: rowid_reg, dst_reg: columns_reg + 1 + i, - amount: 0, + extra_amount: 0, }); } else { program.emit_column(table_cursor_id, i, columns_reg + 1 + i); @@ -1337,14 +1337,14 @@ pub fn emit_cdc_insns( program.emit_insn(Insn::Copy { src_reg: rowid_reg, dst_reg: turso_cdc_registers + 4, - amount: 0, + extra_amount: 0, }); if let Some(before_record_reg) = before_record_reg { program.emit_insn(Insn::Copy { src_reg: before_record_reg, dst_reg: turso_cdc_registers + 5, - amount: 0, + extra_amount: 0, }); } else { program.emit_null(turso_cdc_registers + 5, None); @@ -1355,7 +1355,7 @@ pub fn emit_cdc_insns( program.emit_insn(Insn::Copy { src_reg: after_record_reg, dst_reg: turso_cdc_registers + 6, - amount: 0, + extra_amount: 0, }); } else { program.emit_null(turso_cdc_registers + 6, None); diff --git a/core/translate/expr.rs b/core/translate/expr.rs index a3a639e15..706496edb 100644 --- a/core/translate/expr.rs +++ b/core/translate/expr.rs @@ -458,7 +458,7 @@ pub fn translate_expr( program.emit_insn(Insn::Copy { src_reg: reg, dst_reg: target_register, - amount: 0, + extra_amount: 0, }); if let Some(span) = constant_span { program.constant_span_end(span); @@ -1024,10 +1024,15 @@ pub fn translate_expr( ScalarFunc::ConcatWs => { let args = expect_arguments_min!(args, 2, srf); - let temp_register = program.alloc_register(); - for arg in args.iter() { - let reg = program.alloc_register(); - translate_expr(program, referenced_tables, arg, reg, resolver)?; + let temp_register = program.alloc_registers(args.len() + 1); + for (i, arg) in args.iter().enumerate() { + translate_expr( + program, + referenced_tables, + arg, + temp_register + i + 1, + resolver, + )?; } program.emit_insn(Insn::Function { constant_mask: 0, @@ -1039,7 +1044,7 @@ pub fn translate_expr( program.emit_insn(Insn::Copy { src_reg: temp_register, dst_reg: target_register, - amount: 1, + extra_amount: 0, }); Ok(target_register) } @@ -1083,7 +1088,7 @@ pub fn translate_expr( program.emit_insn(Insn::Copy { src_reg: temp_reg, dst_reg: target_register, - amount: 0, + extra_amount: 0, }); Ok(target_register) @@ -1569,7 +1574,7 @@ pub fn translate_expr( program.emit_insn(Insn::Copy { src_reg: output_register, dst_reg: target_register, - amount: 0, + extra_amount: 0, }); Ok(target_register) } @@ -1591,7 +1596,7 @@ pub fn translate_expr( program.emit_insn(Insn::Copy { src_reg: output_register, dst_reg: target_register, - amount: 0, + extra_amount: 0, }); Ok(target_register) } @@ -1746,7 +1751,7 @@ pub fn translate_expr( program.emit_insn(Insn::Copy { src_reg: start_reg, dst_reg: target_register, - amount: 0, + extra_amount: 0, }); Ok(target_register) } @@ -1980,7 +1985,7 @@ pub fn translate_expr( .expect("Subquery result_columns_start_reg must be set") + *column, dst_reg: target_register, - amount: 0, + extra_amount: 0, }); Ok(target_register) } diff --git a/core/translate/insert.rs b/core/translate/insert.rs index 27de4a38b..868aacf50 100644 --- a/core/translate/insert.rs +++ b/core/translate/insert.rs @@ -379,7 +379,7 @@ pub fn translate_insert( program.emit_insn(Insn::Copy { src_reg: reg, dst_reg: rowid_reg, - amount: 0, // TODO: rename 'amount' to something else; amount==0 means 1 + extra_amount: 0, // TODO: rename 'amount' to something else; amount==0 means 1 }); // for the row record, the rowid alias column is always set to NULL program.emit_insn(Insn::SoftNull { reg }); @@ -464,14 +464,14 @@ pub fn translate_insert( program.emit_insn(Insn::Copy { src_reg: column_registers_start + col.0, dst_reg: idx_start_reg + i, - amount: 0, + extra_amount: 0, }); } // last register is the rowid program.emit_insn(Insn::Copy { src_reg: rowid_reg, dst_reg: idx_start_reg + num_cols, - amount: 0, + extra_amount: 0, }); let index = schema @@ -811,7 +811,7 @@ fn populate_columns_multiple_rows( program.emit_insn(Insn::Copy { src_reg: yield_reg + value_index_seen, dst_reg: column_registers_start + value_index + other_values_seen, - amount: 0, + extra_amount: 0, }); } diff --git a/core/translate/schema.rs b/core/translate/schema.rs index fef50bb32..a1785f7f5 100644 --- a/core/translate/schema.rs +++ b/core/translate/schema.rs @@ -213,7 +213,7 @@ pub fn emit_schema_entry( program.emit_insn(Insn::Copy { src_reg: root_page_reg, dst_reg: rootpage_reg, - amount: 1, + extra_amount: 0, }); } diff --git a/core/translate/select.rs b/core/translate/select.rs index abc3ba30e..a8ad0d737 100644 --- a/core/translate/select.rs +++ b/core/translate/select.rs @@ -741,7 +741,7 @@ pub fn emit_simple_count( program.emit_insn(Insn::Copy { src_reg: target_reg, dst_reg: output_reg, - amount: 0, + extra_amount: 0, }); program.emit_result_row(output_reg, 1); Ok(()) diff --git a/core/translate/values.rs b/core/translate/values.rs index a5e0f4142..28c037850 100644 --- a/core/translate/values.rs +++ b/core/translate/values.rs @@ -102,7 +102,7 @@ fn emit_toplevel_values( program.emit_insn(Insn::Copy { src_reg: start_reg + i, dst_reg: copy_start_reg + i, - amount: 0, + extra_amount: 0, }); } diff --git a/core/vdbe/execute.rs b/core/vdbe/execute.rs index c1b1a2af5..5293310d0 100644 --- a/core/vdbe/execute.rs +++ b/core/vdbe/execute.rs @@ -5641,12 +5641,12 @@ pub fn op_copy( let Insn::Copy { src_reg, dst_reg, - amount, + extra_amount, } = insn else { unreachable!("unexpected Insn {:?}", insn) }; - for i in 0..=*amount { + for i in 0..=*extra_amount { state.registers[*dst_reg + i] = state.registers[*src_reg + i].clone(); } state.pc += 1; diff --git a/core/vdbe/explain.rs b/core/vdbe/explain.rs index 339bf303c..38981da29 100644 --- a/core/vdbe/explain.rs +++ b/core/vdbe/explain.rs @@ -1230,12 +1230,12 @@ pub fn insn_to_str( Insn::Copy { src_reg, dst_reg, - amount, + extra_amount, } => ( "Copy", *src_reg as i32, *dst_reg as i32, - *amount as i32, + *extra_amount as i32, Value::build_text(""), 0, format!("r[{dst_reg}]=r[{src_reg}]"), diff --git a/core/vdbe/insn.rs b/core/vdbe/insn.rs index f094f3db0..37acbc5e3 100644 --- a/core/vdbe/insn.rs +++ b/core/vdbe/insn.rs @@ -800,7 +800,7 @@ pub enum Insn { Copy { src_reg: usize, dst_reg: usize, - amount: usize, // 0 amount means we include src_reg, dst_reg..=dst_reg+amount = src_reg..=src_reg+amount + extra_amount: usize, // 0 extra_amount means we include src_reg, dst_reg..=dst_reg+amount = src_reg..=src_reg+amount }, /// Allocate a new b-tree. diff --git a/testing/scalar-functions.test b/testing/scalar-functions.test index 807c4971d..8ab2ce2b6 100755 --- a/testing/scalar-functions.test +++ b/testing/scalar-functions.test @@ -35,6 +35,10 @@ do_execsql_test concat_ws-multiple { select concat_ws(',', 1, 2), concat_ws(',', 3, 4) } {1,2|3,4} +do_execsql_test concat_ws-complex-args { + select concat_ws(',', 'a' || 'b', 'b' || 'c', 'c' || 'd'); +} {ab,bc,cd} + do_execsql_test char { select char(108, 105) } {li}