feat: support unary positive

This commit is contained in:
JeanArhancet
2024-12-13 02:05:31 +01:00
parent 3023d228c7
commit 8bf6572e9e
3 changed files with 29 additions and 8 deletions

View File

@@ -1665,23 +1665,37 @@ pub fn translate_expr(
ast::Expr::Raise(_, _) => todo!(),
ast::Expr::Subquery(_) => todo!(),
ast::Expr::Unary(op, expr) => match (op, expr.as_ref()) {
(UnaryOperator::Negative, ast::Expr::Literal(ast::Literal::Numeric(numeric_value))) => {
(
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 {
program.emit_insn(Insn::Integer {
value: -value,
value: value * multiplier,
dest: target_register,
});
} else {
program.emit_insn(Insn::Real {
value: -numeric_value.parse::<f64>()?,
value: multiplier as f64 * numeric_value.parse::<f64>()?,
dest: target_register,
});
}
program.mark_last_insn_constant();
Ok(target_register)
}
(UnaryOperator::Negative, _) => {
(UnaryOperator::Negative | UnaryOperator::Positive, _) => {
let value = if let UnaryOperator::Negative = op {
-1
} else {
1
};
let reg = program.alloc_register();
translate_expr(
program,
@@ -1692,7 +1706,7 @@ pub fn translate_expr(
)?;
let zero_reg = program.alloc_register();
program.emit_insn(Insn::Integer {
value: -1,
value,
dest: zero_reg,
});
program.mark_last_insn_constant();

View File

@@ -75,11 +75,18 @@ do_execsql_test select-string-agg-with-column-delimiter {
SELECT string_agg(name, id) FROM products;
} {hat2cap3shirt4sweater5sweatshirt6shorts7jeans8sneakers9boots10coat11accessories}
do_execsql_test select-agg-unary {
do_execsql_test select-agg-unary-negative {
SELECT -max(age) FROM users;
} {-100}
do_execsql_test select-agg-binary-unary {
do_execsql_test select-agg-unary-positive {
SELECT +max(age) FROM users;
} {100}
do_execsql_test select-agg-binary-unary-negative {
SELECT min(age) + -max(age) FROM users;
} {-99}
do_execsql_test select-agg-binary-unary-positive {
SELECT min(age) + +max(age) FROM users;
} {101}

View File

@@ -400,7 +400,7 @@ do_execsql_test octet-length-date-binary-expr {
} {1}
do_execsql_test min-number {
select min(-10,2,3)
select min(-10,2,3,+4)
} {-10}
do_execsql_test min-str {