From 16595f39f5ae72ddf96e25523acdbbfd55bab37f Mon Sep 17 00:00:00 2001 From: PThorpe92 Date: Wed, 11 Dec 2024 11:29:06 -0500 Subject: [PATCH] Add support for unary op negation of aggregates --- core/translate/expr.rs | 32 ++++++++++++++++++++++++++++---- testing/agg-functions.test | 9 +++++++++ testing/math.test | 4 ---- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/core/translate/expr.rs b/core/translate/expr.rs index 1e8c4d4d6..b92b892ac 100644 --- a/core/translate/expr.rs +++ b/core/translate/expr.rs @@ -1627,30 +1627,54 @@ pub fn translate_expr( dest: target_register, }); } + program.mark_last_insn_constant(); + Ok(target_register) + } + (UnaryOperator::Negative, _) => { + let reg = program.alloc_register(); + translate_expr( + program, + referenced_tables, + expr, + reg, + precomputed_exprs_to_registers, + )?; + let zero_reg = program.alloc_register(); + program.emit_insn(Insn::Integer { + value: -1, + dest: zero_reg, + }); + program.mark_last_insn_constant(); + program.emit_insn(Insn::Multiply { + lhs: zero_reg, + rhs: reg, + dest: target_register, + }); Ok(target_register) } (UnaryOperator::BitwiseNot, ast::Expr::Literal(ast::Literal::Numeric(num_val))) => { let maybe_int = num_val.parse::(); - if let Ok(maybe_int) = maybe_int { + if let Ok(val) = maybe_int { program.emit_insn(Insn::Integer { - value: !maybe_int, + value: !val, dest: target_register, }); - Ok(target_register) } else { let num_val = num_val.parse::()? as i64; program.emit_insn(Insn::Integer { value: !num_val, dest: target_register, }); - Ok(target_register) } + program.mark_last_insn_constant(); + Ok(target_register) } (UnaryOperator::BitwiseNot, ast::Expr::Literal(ast::Literal::Null)) => { program.emit_insn(Insn::Null { dest: target_register, dest_end: None, }); + program.mark_last_insn_constant(); Ok(target_register) } (UnaryOperator::BitwiseNot, _) => { diff --git a/testing/agg-functions.test b/testing/agg-functions.test index fbc007b62..e5594efa5 100755 --- a/testing/agg-functions.test +++ b/testing/agg-functions.test @@ -74,3 +74,12 @@ do_execsql_test select-string-agg-with-delimiter { do_execsql_test select-string-agg-with-column-delimiter { SELECT string_agg(name, id) FROM products; } {hat2cap3shirt4sweater5sweatshirt6shorts7jeans8sneakers9boots10coat11accessories} + +do_execsql_test select-agg-unary { + SELECT -max(age) FROM users; +} {-100} + +do_execsql_test select-agg-binary-unary { + SELECT min(age) + -max(age) FROM users; +} {-99} + diff --git a/testing/math.test b/testing/math.test index 45b38f7d6..af477fca4 100644 --- a/testing/math.test +++ b/testing/math.test @@ -283,10 +283,6 @@ do_execsql_test bitwise-and-float-int-rev { SELECT 261.8 & 660 } {4} -do_execsql_test bitwise-and-float-int-rev { - SELECT SUM(id) from products -} {66} - do_execsql_test bitwise-and-int-agg-int { SELECT 8261 & sum(id) from products } {64}