add max aggregate function

This commit is contained in:
mazchew
2024-07-09 02:43:36 +08:00
parent e5d55398db
commit 3f339d07d3
4 changed files with 61 additions and 2 deletions

View File

@@ -471,9 +471,21 @@ fn translate_aggregation(
});
target_register
}
AggFunc::GroupConcat => todo!(),
AggFunc::Max => todo!(),
AggFunc::Max => {
if args.len() != 1 {
anyhow::bail!("Parse error: max bad number of arguments");
}
let expr = &args[0];
let expr_reg = program.alloc_register();
let _ = translate_expr(program, cursor_id, table, expr, expr_reg);
program.emit_insn(Insn::AggStep {
acc_reg: target_register,
col: expr_reg,
func: AggFunc::Max,
});
target_register
}
AggFunc::Min => todo!(),
AggFunc::StringAgg => todo!(),
AggFunc::Sum => {

View File

@@ -47,6 +47,7 @@ impl Display for OwnedValue {
AggContext::Avg(acc, _count) => write!(f, "{}", acc),
AggContext::Sum(acc) => write!(f, "{}", acc),
AggContext::Count(count) => write!(f, "{}", count),
AggContext::Max(max) => write!(f, "{}", max),
},
OwnedValue::Record(r) => write!(f, "{:?}", r),
}
@@ -58,6 +59,7 @@ pub enum AggContext {
Avg(OwnedValue, OwnedValue), // acc and count
Sum(OwnedValue),
Count(OwnedValue),
Max(OwnedValue),
}
impl std::ops::Add<OwnedValue> for OwnedValue {
@@ -163,6 +165,7 @@ pub fn to_value(value: &OwnedValue) -> Value<'_> {
AggContext::Avg(acc, _count) => to_value(acc), // we assume aggfinal was called
AggContext::Sum(acc) => to_value(acc),
AggContext::Count(count) => to_value(count),
AggContext::Max(max) => to_value(max),
},
OwnedValue::Record(_) => todo!(),
}

View File

@@ -433,6 +433,20 @@ impl Program {
AggFunc::Count => {
OwnedValue::Agg(Box::new(AggContext::Count(OwnedValue::Integer(0))))
}
AggFunc::Max => {
let col = state.registers[*col].clone();
match col {
OwnedValue::Integer(_) => {
OwnedValue::Agg(Box::new(AggContext::Max(OwnedValue::Integer(i64::MIN))))
}
OwnedValue::Float(_) => {
OwnedValue::Agg(Box::new(AggContext::Max(OwnedValue::Float(f64::NEG_INFINITY))))
}
_ => {
unreachable!();
}
}
}
_ => {
todo!();
}
@@ -472,6 +486,31 @@ impl Program {
};
*count += 1;
}
AggFunc::Max => {
let col = state.registers[*col].clone();
let OwnedValue::Agg(agg) = state.registers[*acc_reg].borrow_mut() else {
unreachable!();
};
let AggContext::Max(acc) = agg.borrow_mut() else {
unreachable!();
};
match (acc, col) {
(OwnedValue::Integer(ref mut current_max), OwnedValue::Integer(value)) => {
if value > *current_max {
*current_max = value;
}
}
(OwnedValue::Float(ref mut current_max), OwnedValue::Float(value)) => {
if value > *current_max {
*current_max = value;
}
}
_ => {
eprintln!("Unexpected types in max aggregation");
}
}
}
_ => {
todo!();
}
@@ -492,6 +531,7 @@ impl Program {
}
AggFunc::Sum => {}
AggFunc::Count => {}
AggFunc::Max => {}
_ => {
todo!();
}

View File

@@ -47,6 +47,10 @@ do_execsql_test select-count {
SELECT count(id) FROM users;
} {10000}
do_execsql_test select-max {
SELECT max(age) FROM users;
} {100}
do_execsql_test select-limit-0 {
SELECT id FROM users LIMIT 0;
} {}