Add support for unary op negation of aggregates

This commit is contained in:
PThorpe92
2024-12-11 11:29:06 -05:00
parent d5391dc716
commit 16595f39f5
3 changed files with 37 additions and 8 deletions

View File

@@ -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::<i64>();
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::<f64>()? 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, _) => {

View File

@@ -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}

View File

@@ -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}