Skip to content

Commit

Permalink
Merge 'Fix SELECT -9223372036854775808 result differs from SQLite' …
Browse files Browse the repository at this point in the history
…from Krishna Vishal

Closes #812
`-9223372036854775808` is `MIN_INT64`. So when we extract out the minus
and try to parse the remainder it becomes greater than MAX_INT64
(9223372036854775807) and will trigger overflow, which converts the
literal into `Real`. So we have to handle it as a special case.

Reviewed-by: Kim Seon Woo (@seonWKim)

Closes #814
  • Loading branch information
penberg committed Jan 30, 2025
2 parents 4a07017 + 39b4122 commit 4673ac9
Showing 1 changed file with 18 additions and 7 deletions.
25 changes: 18 additions & 7 deletions core/translate/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1822,22 +1822,33 @@ pub fn translate_expr(
UnaryOperator::Negative | UnaryOperator::Positive,
ast::Expr::Literal(ast::Literal::Numeric(numeric_value)),
) => {
let maybe_int = numeric_value.parse::<i64>();
let multiplier = if let UnaryOperator::Negative = op {
-1
} else {
1
};
if let Ok(value) = maybe_int {

// 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 multiplier == -1 && numeric_value == "9223372036854775808" {
program.emit_insn(Insn::Integer {
value: value * multiplier,
value: i64::MIN,
dest: target_register,
});
} else {
program.emit_insn(Insn::Real {
value: multiplier as f64 * numeric_value.parse::<f64>()?,
dest: target_register,
});
let maybe_int = numeric_value.parse::<i64>();
if let Ok(value) = maybe_int {
program.emit_insn(Insn::Integer {
value: value * multiplier,
dest: target_register,
});
} else {
let value = numeric_value.parse::<f64>()?;
program.emit_insn(Insn::Real {
value: value * multiplier as f64,
dest: target_register,
});
}
}
Ok(target_register)
}
Expand Down

0 comments on commit 4673ac9

Please sign in to comment.