diff --git a/core/translate.rs b/core/translate.rs index 2ff6afb74..a0c77c64a 100644 --- a/core/translate.rs +++ b/core/translate.rs @@ -401,17 +401,19 @@ fn translate_table_star( .unwrap() .open_cursor; for (i, col) in table.columns().iter().enumerate() { + let col_target_register = target_register + i; if table.column_is_rowid_alias(col) { program.emit_insn(Insn::RowId { cursor_id: table_cursor, - dest: target_register + i, + dest: col_target_register, }); } else { program.emit_insn(Insn::Column { column: i, - dest: target_register + i, + dest: col_target_register, cursor_id: table_cursor, }); + maybe_apply_affinity(col, col_target_register, program); } } } @@ -516,6 +518,7 @@ fn translate_expr( cursor_id, }); } + maybe_apply_affinity(col, target_register, program); Ok(target_register) } ast::Expr::InList { .. } => todo!(), @@ -772,3 +775,12 @@ fn update_pragma(name: &str, value: i64, header: Rc>, pa _ => todo!(), } } + +fn maybe_apply_affinity(col: &Column, target_register: usize, program: &mut ProgramBuilder) { + match col.ty { + crate::schema::Type::Real => program.emit_insn(Insn::RealAffinity { + register: target_register, + }), + _ => {} + } +} diff --git a/core/vdbe.rs b/core/vdbe.rs index 6ec43178a..da0bd8543 100644 --- a/core/vdbe.rs +++ b/core/vdbe.rs @@ -102,6 +102,11 @@ pub enum Insn { dest: usize, }, + // If register holds an integer, transform it to a float + RealAffinity { + register: usize, + }, + // Write a string value into a register. String8 { value: String, @@ -400,6 +405,13 @@ impl Program { state.registers[*dest] = OwnedValue::Float(*value); state.pc += 1; } + Insn::RealAffinity { register } => { + if let OwnedValue::Integer(i) = &state.registers[*register] { + state.registers[*register] = OwnedValue::Float(*i as f64); + } else { + }; + state.pc += 1; + } Insn::String8 { value, dest } => { state.registers[*dest] = OwnedValue::Text(Rc::new(value.into())); state.pc += 1; @@ -433,7 +445,7 @@ impl Program { OwnedValue::Integer(0), ))), AggFunc::Sum => { - OwnedValue::Agg(Box::new(AggContext::Sum(OwnedValue::Float(0.0)))) + OwnedValue::Agg(Box::new(AggContext::Sum(OwnedValue::Integer(0)))) } AggFunc::Count => { OwnedValue::Agg(Box::new(AggContext::Count(OwnedValue::Integer(0)))) @@ -441,12 +453,12 @@ impl Program { AggFunc::Max => { let col = state.registers[*col].clone(); match col { - OwnedValue::Integer(_) => { - OwnedValue::Agg(Box::new(AggContext::Max(OwnedValue::Integer(i64::MIN)))) - } - OwnedValue::Float(_) => { - OwnedValue::Agg(Box::new(AggContext::Max(OwnedValue::Float(f64::NEG_INFINITY)))) - } + OwnedValue::Integer(_) => OwnedValue::Agg(Box::new( + AggContext::Max(OwnedValue::Integer(i64::MIN)), + )), + OwnedValue::Float(_) => OwnedValue::Agg(Box::new( + AggContext::Max(OwnedValue::Float(f64::NEG_INFINITY)), + )), _ => { unreachable!(); } @@ -455,12 +467,12 @@ impl Program { AggFunc::Min => { let col = state.registers[*col].clone(); match col { - OwnedValue::Integer(_) => { - OwnedValue::Agg(Box::new(AggContext::Min(OwnedValue::Integer(i64::MAX)))) - } - OwnedValue::Float(_) => { - OwnedValue::Agg(Box::new(AggContext::Min(OwnedValue::Float(f64::INFINITY)))) - } + OwnedValue::Integer(_) => OwnedValue::Agg(Box::new( + AggContext::Min(OwnedValue::Integer(i64::MAX)), + )), + OwnedValue::Float(_) => OwnedValue::Agg(Box::new( + AggContext::Min(OwnedValue::Float(f64::INFINITY)), + )), _ => { unreachable!(); } @@ -507,20 +519,27 @@ impl Program { } AggFunc::Max => { let col = state.registers[*col].clone(); - let OwnedValue::Agg(agg) = state.registers[*acc_reg].borrow_mut() else { + let OwnedValue::Agg(agg) = state.registers[*acc_reg].borrow_mut() + else { unreachable!(); }; let AggContext::Max(acc) = agg.borrow_mut() else { unreachable!(); }; - + match (acc, col) { - (OwnedValue::Integer(ref mut current_max), OwnedValue::Integer(value)) => { + ( + OwnedValue::Integer(ref mut current_max), + OwnedValue::Integer(value), + ) => { if value > *current_max { *current_max = value; } } - (OwnedValue::Float(ref mut current_max), OwnedValue::Float(value)) => { + ( + OwnedValue::Float(ref mut current_max), + OwnedValue::Float(value), + ) => { if value > *current_max { *current_max = value; } @@ -532,20 +551,27 @@ impl Program { } AggFunc::Min => { let col = state.registers[*col].clone(); - let OwnedValue::Agg(agg) = state.registers[*acc_reg].borrow_mut() else { + let OwnedValue::Agg(agg) = state.registers[*acc_reg].borrow_mut() + else { unreachable!(); }; let AggContext::Min(acc) = agg.borrow_mut() else { unreachable!(); }; - + match (acc, col) { - (OwnedValue::Integer(ref mut current_min), OwnedValue::Integer(value)) => { + ( + OwnedValue::Integer(ref mut current_min), + OwnedValue::Integer(value), + ) => { if value < *current_min { *current_min = value; } } - (OwnedValue::Float(ref mut current_min), OwnedValue::Float(value)) => { + ( + OwnedValue::Float(ref mut current_min), + OwnedValue::Float(value), + ) => { if value < *current_min { *current_min = value; } @@ -576,7 +602,7 @@ impl Program { AggFunc::Sum => {} AggFunc::Count => {} AggFunc::Max => {} - AggFunc::Min => {} + AggFunc::Min => {} _ => { todo!(); } @@ -836,6 +862,15 @@ fn insn_to_str(addr: BranchOffset, insn: &Insn, indent: String) -> String { 0, "".to_string(), ), + Insn::RealAffinity { register } => ( + "RealAffinity", + *register as i32, + 0, + 0, + OwnedValue::Text(Rc::new("".to_string())), + 0, + "".to_string(), + ), Insn::String8 { value, dest } => ( "String8", *dest as i32, @@ -945,17 +980,25 @@ fn insn_to_str(addr: BranchOffset, insn: &Insn, indent: String) -> String { fn get_indent_count(indent_count: usize, curr_insn: &Insn, prev_insn: Option<&Insn>) -> usize { let indent_count = if let Some(insn) = prev_insn { match insn { - Insn::RewindAwait { cursor_id: _, pc_if_empty: _, } => indent_count + 1, + Insn::RewindAwait { + cursor_id: _, + pc_if_empty: _, + } => indent_count + 1, Insn::SorterSort { cursor_id: _ } => indent_count + 1, - _ => indent_count + _ => indent_count, } - } else { indent_count }; + } else { + indent_count + }; let indent_count = match curr_insn { - Insn::NextAsync { cursor_id: _ } => indent_count - 1, - Insn::SorterNext { cursor_id: _, pc_if_next: _, } => indent_count - 1, - _ => indent_count - }; - + Insn::NextAsync { cursor_id: _ } => indent_count - 1, + Insn::SorterNext { + cursor_id: _, + pc_if_next: _, + } => indent_count - 1, + _ => indent_count, + }; + indent_count -} \ No newline at end of file +} diff --git a/testing/all.test b/testing/all.test index b0c47f75e..61a5f8d89 100755 --- a/testing/all.test +++ b/testing/all.test @@ -68,8 +68,12 @@ do_execsql_test pragma-cache-size { do_execsql_test cross-join { select * from users, products limit 1; -} {1|Jamie|Foster|dylan00@example.com|496-522-9493|62375\ Johnson\ Rest\ Suite\ 322|West\ Lauriestad|IL|35865|94|1|hat|79} +} {1|Jamie|Foster|dylan00@example.com|496-522-9493|62375\ Johnson\ Rest\ Suite\ 322|West\ Lauriestad|IL|35865|94|1|hat|79.0} do_execsql_test cross-join-specific-columns { select first_name, price from users, products limit 1; -} {Jamie|79} +} {Jamie|79.0} + +do_execsql_test realify { + select price from products limit 1; +} {79.0}