fix aggregation functions without group by

This commit is contained in:
Ihor Andrianov
2025-03-27 21:48:32 +02:00
parent 73a35329d0
commit b47c214a5e
4 changed files with 30 additions and 2 deletions

View File

@@ -62,6 +62,8 @@ pub struct TranslateCtx<'a> {
pub label_main_loop_end: Option<BranchOffset>,
// First register of the aggregation results
pub reg_agg_start: Option<usize>,
// Register to track if we set non aggregate cols to first encountered row in non group by agg statement
pub reg_agg_flag: Option<usize>,
// First register of the result columns of the query
pub reg_result_cols_start: Option<usize>,
// The register holding the limit value, if any.
@@ -115,6 +117,7 @@ fn prologue<'a>(
labels_main_loop: (0..table_count).map(|_| LoopLabels::new(program)).collect(),
label_main_loop_end: None,
reg_agg_start: None,
reg_agg_flag: None,
reg_limit: None,
reg_offset: None,
reg_limit_offset_sum: None,
@@ -242,6 +245,11 @@ pub fn emit_query<'a>(
target_pc: after_main_loop_label,
});
}
if !plan.aggregates.is_empty() && plan.group_by.is_none() {
let flag = program.alloc_register();
program.emit_int(0, flag);
t_ctx.reg_agg_flag = Some(flag);
}
// Allocate registers for result columns
t_ctx.reg_result_cols_start = Some(program.alloc_registers(plan.result_columns.len()));

View File

@@ -677,6 +677,18 @@ fn emit_loop_source(
&t_ctx.resolver,
)?;
}
if let Some(flag) = t_ctx.reg_agg_flag {
let offset = program.offset().add(plan.result_columns.len() as u32);
program.emit_insn(Insn::If {
reg: flag,
target_pc: offset,
jump_if_null: false,
});
}
let col_start = t_ctx.reg_result_cols_start.unwrap();
for (i, rc) in plan.result_columns.iter().enumerate() {
if rc.contains_aggregates {
// Do nothing, aggregates are computed above
@@ -684,7 +696,9 @@ fn emit_loop_source(
// it will be computed after the aggregations are finalized.
continue;
}
let reg = start_reg + num_aggs + i;
let reg = col_start + i;
translate_expr(
program,
Some(&plan.table_references),
@@ -693,6 +707,9 @@ fn emit_loop_source(
&t_ctx.resolver,
)?;
}
if let Some(flag) = t_ctx.reg_agg_flag {
program.emit_int(1, flag);
}
Ok(())
}
LoopEmitTarget::QueryResult => {

View File

@@ -25,7 +25,9 @@ pub fn emit_select_result(
}
let start_reg = t_ctx.reg_result_cols_start.unwrap();
for (i, rc) in plan.result_columns.iter().enumerate() {
for (i, rc) in plan.result_columns.iter().enumerate().filter(|(_, rc)| {
t_ctx.reg_agg_flag.is_some() && rc.contains_aggregates || t_ctx.reg_agg_flag.is_none()
}) {
let reg = start_reg + i;
translate_expr(
program,

View File

@@ -75,6 +75,7 @@ pub fn emit_subquery<'a>(
meta_left_joins: (0..plan.table_references.len()).map(|_| None).collect(),
meta_sort: None,
reg_agg_start: None,
reg_agg_flag: None,
reg_result_cols_start: None,
result_column_indexes_in_orderby_sorter: (0..plan.result_columns.len()).collect(),
result_columns_to_skip_in_orderby_sorter: None,