mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-17 22:14:37 +01:00
fix aggregation functions without group by
This commit is contained in:
@@ -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()));
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user