mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-09 02:04:22 +01:00
Use positional offsets in translate::expr to remap parameters to their correct offsets
This commit is contained in:
@@ -1851,11 +1851,8 @@ pub fn translate_expr(
|
||||
} else {
|
||||
Some(program.resolve_cursor_id(&table_reference.identifier))
|
||||
};
|
||||
let index_cursor_id = if let Some(index) = index {
|
||||
Some(program.resolve_cursor_id(&index.name))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let index_cursor_id =
|
||||
index.map(|index| program.resolve_cursor_id(&index.name));
|
||||
if *is_rowid_alias {
|
||||
if let Some(index_cursor_id) = index_cursor_id {
|
||||
program.emit_insn(Insn::IdxRowId {
|
||||
@@ -2150,7 +2147,21 @@ pub fn translate_expr(
|
||||
}
|
||||
},
|
||||
ast::Expr::Variable(name) => {
|
||||
// Table t: (a,b,c)
|
||||
// For 'insert' statements:
|
||||
// INSERT INTO t (b,c,a) values (?,?,?)
|
||||
// since we walk the columns in the tables column order, we have to store the value index that
|
||||
// the parameter was given for an insert statement. Then, we may end up with something
|
||||
// like: insert into (b,c,a) values (22,?,?), in which case we will get a = 2, c = 1
|
||||
// instead of previously we would have gotten a = 0, c = 1
|
||||
// where it instead should be c = 0, a = 1. So all we can do is store the value index
|
||||
// alongside the index into the parameters list, then during bind_at: we can translate
|
||||
// this value into the proper order.
|
||||
let index = program.parameters.push(name);
|
||||
if let Some(ref mut indicies) = &mut program.param_positions {
|
||||
// index of the parameter in the inserted values + index of the parameter relative
|
||||
indicies.push((program.current_col_idx.unwrap_or(index.get()), index));
|
||||
}
|
||||
program.emit_insn(Insn::Variable {
|
||||
index,
|
||||
dest: target_register,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::num::NonZero;
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
|
||||
@@ -589,6 +590,7 @@ fn populate_column_registers(
|
||||
rowid_reg: usize,
|
||||
resolver: &Resolver,
|
||||
) -> Result<()> {
|
||||
program.param_positions = Some(vec![]);
|
||||
for (i, mapping) in column_mappings.iter().enumerate() {
|
||||
let target_reg = column_registers_start + i;
|
||||
|
||||
@@ -643,6 +645,18 @@ fn populate_column_registers(
|
||||
}
|
||||
}
|
||||
}
|
||||
// if there are any parameter positions, we sort them by the value_index position
|
||||
// to ensure we are binding the parameters to the proper index later on
|
||||
if let Some(ref mut params) = program.param_positions.as_mut() {
|
||||
params.sort_by_key(|(val_pos, _)| *val_pos);
|
||||
}
|
||||
|
||||
let remap: Option<Vec<NonZero<usize>>> = program
|
||||
.param_positions
|
||||
.as_ref()
|
||||
.map(|pos| pos.iter().map(|&(_, internal_idx)| internal_idx).collect());
|
||||
|
||||
program.set_param_remap(remap);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user