Skip to content

Commit c44da4d

Browse files
committed
Fix incorrect text->numeric coercion in CAST
1 parent 038fb96 commit c44da4d

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

core/vdbe/mod.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -3580,7 +3580,15 @@ fn exec_cast(value: &OwnedValue, datatype: &str) -> OwnedValue {
35803580
let text = String::from_utf8_lossy(b);
35813581
cast_text_to_numeric(&text)
35823582
}
3583-
OwnedValue::Text(t) => cast_text_to_numeric(t.as_str()),
3583+
OwnedValue::Text(t) => {
3584+
let text = t.as_str();
3585+
// Looks like a float
3586+
if text.contains('.') || text.contains('e') || text.contains('E') {
3587+
cast_text_to_real(text)
3588+
} else {
3589+
cast_text_to_integer(text)
3590+
}
3591+
}
35843592
OwnedValue::Integer(i) => OwnedValue::Integer(*i),
35853593
OwnedValue::Float(f) => OwnedValue::Float(*f),
35863594
_ => value.clone(), // TODO probably wrong
@@ -3672,14 +3680,15 @@ fn affinity(datatype: &str) -> Affinity {
36723680
/// The CAST operator understands decimal integers only — conversion of hexadecimal integers stops at the "x" in the "0x" prefix of the hexadecimal integer string and thus result of the CAST is always zero.
36733681
fn cast_text_to_integer(text: &str) -> OwnedValue {
36743682
let text = text.trim();
3683+
36753684
if let Ok(i) = text.parse::<i64>() {
36763685
return OwnedValue::Integer(i);
36773686
}
36783687
// Try to find longest valid prefix that parses as an integer
36793688
// TODO: inefficient
3680-
let mut end_index = text.len() - 1;
3681-
while end_index > 0 {
3682-
if let Ok(i) = text[..=end_index].parse::<i64>() {
3689+
let mut end_index = text.len().saturating_sub(1) as isize;
3690+
while end_index >= 0 {
3691+
if let Ok(i) = text[..=end_index as usize].parse::<i64>() {
36833692
return OwnedValue::Integer(i);
36843693
}
36853694
end_index -= 1;

0 commit comments

Comments
 (0)