diff --git a/core/vdbe/mod.rs b/core/vdbe/mod.rs index a81a1c687..1d8b943e0 100644 --- a/core/vdbe/mod.rs +++ b/core/vdbe/mod.rs @@ -3671,14 +3671,17 @@ fn affinity(datatype: &str) -> Affinity { /// 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. fn cast_text_to_integer(text: &str) -> OwnedValue { let text = text.trim(); + if text.is_empty() { + return OwnedValue::Integer(0); + } if let Ok(i) = text.parse::() { return OwnedValue::Integer(i); } // Try to find longest valid prefix that parses as an integer // TODO: inefficient - let mut end_index = text.len() - 1; - while end_index > 0 { - if let Ok(i) = text[..=end_index].parse::() { + let mut end_index = text.len().saturating_sub(1) as isize; + while end_index >= 0 { + if let Ok(i) = text[..=end_index as usize].parse::() { return OwnedValue::Integer(i); } end_index -= 1; @@ -3692,14 +3695,17 @@ fn cast_text_to_integer(text: &str) -> OwnedValue { /// If there is no prefix that can be interpreted as a real number, the result of the conversion is 0.0. fn cast_text_to_real(text: &str) -> OwnedValue { let trimmed = text.trim_start(); + if trimmed.is_empty() { + return OwnedValue::Float(0.0); + } if let Ok(num) = trimmed.parse::() { return OwnedValue::Float(num); } // Try to find longest valid prefix that parses as a float // TODO: inefficient - let mut end_index = trimmed.len() - 1; - while end_index > 0 { - if let Ok(num) = trimmed[..=end_index].parse::() { + let mut end_index = trimmed.len().saturating_sub(1) as isize; + while end_index >= 0 { + if let Ok(num) = trimmed[..=end_index as usize].parse::() { return OwnedValue::Float(num); } end_index -= 1; diff --git a/testing/scalar-functions.test b/testing/scalar-functions.test index 2ba0d58a4..2315117b2 100755 --- a/testing/scalar-functions.test +++ b/testing/scalar-functions.test @@ -739,6 +739,7 @@ do_execsql_test zeroblob-blob { } {1} # CAST tests - INTEGER affinity + do_execsql_test cast-text-to-integer { SELECT CAST('123' AS INTEGER); } {123} @@ -747,6 +748,10 @@ do_execsql_test cast-text-with-spaces-to-integer { SELECT CAST(' 123 ' AS INTEGER); } {123} +do_execsql_test cast-text-with-trailing-junk-to-integer { + SELECT CAST('1abc' AS INTEGER); +} {1} + do_execsql_test cast-invalid-text-to-integer { SELECT CAST('abc' AS INTEGER); } {0}