diff --git a/core/translate/emitter.rs b/core/translate/emitter.rs index e4d05bfaa..b473715fe 100644 --- a/core/translate/emitter.rs +++ b/core/translate/emitter.rs @@ -62,6 +62,8 @@ pub struct TranslateCtx<'a> { pub label_main_loop_end: Option, // First register of the aggregation results pub reg_agg_start: Option, + // Register to track if we set non aggregate cols to first encountered row in non group by agg statement + pub reg_agg_flag: Option, // First register of the result columns of the query pub reg_result_cols_start: Option, // 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())); diff --git a/core/translate/main_loop.rs b/core/translate/main_loop.rs index 7b51a2328..95601bb9a 100644 --- a/core/translate/main_loop.rs +++ b/core/translate/main_loop.rs @@ -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 => { diff --git a/core/translate/result_row.rs b/core/translate/result_row.rs index ad8454c25..7988d0417 100644 --- a/core/translate/result_row.rs +++ b/core/translate/result_row.rs @@ -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, diff --git a/core/translate/subquery.rs b/core/translate/subquery.rs index 1730312be..f81b20788 100644 --- a/core/translate/subquery.rs +++ b/core/translate/subquery.rs @@ -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,