diff --git a/core/translate/expr.rs b/core/translate/expr.rs index 909fb484b..6a3b1fc8b 100644 --- a/core/translate/expr.rs +++ b/core/translate/expr.rs @@ -1850,7 +1850,7 @@ pub fn translate_expr( } ast::Expr::Literal(lit) => match lit { ast::Literal::Numeric(val) => { - if val.starts_with("0x") { + if val.starts_with("0x") || val.starts_with("0X") { // must be a hex decimal let int_value = i64::from_str_radix(&val[2..], 16)?; program.emit_insn(Insn::Integer { @@ -1941,14 +1941,22 @@ pub fn translate_expr( // Special case: if we're negating "9223372036854775808", this is exactly MIN_INT64 // If we don't do this -1 * 9223372036854775808 will overflow and parse will fail // and trigger conversion to Real. - if numeric_value == "9223372036854775808" { + if numeric_value == "9223372036854775808" + || numeric_value.eq_ignore_ascii_case("0x7fffffffffffffff") + { program.emit_insn(Insn::Integer { value: i64::MIN, dest: target_register, }); } else { - let maybe_int = numeric_value.parse::(); - if let Ok(value) = maybe_int { + if numeric_value.starts_with("0x") || numeric_value.starts_with("0X") { + // must be a hex decimal + let int_value = i64::from_str_radix(&numeric_value[2..], 16)?; + program.emit_insn(Insn::Integer { + value: -int_value, + dest: target_register, + }); + } else if let Ok(value) = numeric_value.parse::() { program.emit_insn(Insn::Integer { value: value * -1, dest: target_register, @@ -1982,8 +1990,13 @@ pub fn translate_expr( Ok(target_register) } (UnaryOperator::BitwiseNot, ast::Expr::Literal(ast::Literal::Numeric(num_val))) => { - let maybe_int = num_val.parse::(); - if let Ok(val) = maybe_int { + if num_val.starts_with("0x") || num_val.starts_with("0X") { + let int_value = i64::from_str_radix(&num_val[2..], 16)?; + program.emit_insn(Insn::Integer { + value: !int_value, + dest: target_register, + }); + } else if let Ok(val) = num_val.parse::() { program.emit_insn(Insn::Integer { value: !val, dest: target_register, diff --git a/testing/math.test b/testing/math.test index 32cb6b2f7..bc44a72ef 100755 --- a/testing/math.test +++ b/testing/math.test @@ -624,10 +624,14 @@ do_execsql_test bitwise-not-text-float { SELECT ~'823.34' } {-824} -do_execsql_test bitwise-not-text-int { +do_execsql_test bitwise-not-text-int-1 { SELECT ~'1234' } {-1235} +do_execsql_test bitwise-not-text-int-2 { + SELECT ~0xA +} {-11} + do_execsql_test bitwise-not-scalar-float { SELECT ~abs(693.9) } {-694} diff --git a/testing/select.test b/testing/select.test index e9d119f51..6f0c6997d 100755 --- a/testing/select.test +++ b/testing/select.test @@ -15,6 +15,10 @@ do_execsql_test select-const-3 { SELECT 0xDEAF } {57007} +do_execsql_test select-const-4 { + SELECT -0xA +} {-10} + do_execsql_test select-true { SELECT true } {1}