Merge 'Fix ungrouped aggregate with offset clause' from Preston Thorpe

closes #3300

Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #3347
This commit is contained in:
Jussi Saurio
2025-09-26 09:13:16 +03:00
committed by GitHub
2 changed files with 47 additions and 13 deletions

View File

@@ -26,6 +26,7 @@ pub fn emit_ungrouped_aggregation<'a>(
plan: &'a SelectPlan,
) -> Result<()> {
let agg_start_reg = t_ctx.reg_agg_start.unwrap();
for (i, agg) in plan.aggregates.iter().enumerate() {
let agg_result_reg = agg_start_reg + i;
program.emit_insn(Insn::AggFinal {
@@ -44,19 +45,46 @@ pub fn emit_ungrouped_aggregation<'a>(
}
t_ctx.resolver.enable_expr_to_reg_cache();
// This always emits a ResultRow because currently it can only be used for a single row result
// Limit is None because we early exit on limit 0 and the max rows here is 1
emit_select_result(
program,
&t_ctx.resolver,
plan,
None,
None,
t_ctx.reg_nonagg_emit_once_flag,
t_ctx.reg_offset,
t_ctx.reg_result_cols_start.unwrap(),
t_ctx.limit_ctx,
)?;
// Handle OFFSET for ungrouped aggregates
// Since we only have one result row, either skip it (offset > 0) or emit it
if let Some(offset_reg) = t_ctx.reg_offset {
let done_label = program.allocate_label();
// If offset > 0, jump to end (skip the single row)
program.emit_insn(Insn::IfPos {
reg: offset_reg,
target_pc: done_label,
decrement_by: 0,
});
// Offset is 0, fall through to emit the row
emit_select_result(
program,
&t_ctx.resolver,
plan,
None,
None,
t_ctx.reg_nonagg_emit_once_flag,
None, // we've already handled offset
t_ctx.reg_result_cols_start.unwrap(),
t_ctx.limit_ctx,
)?;
program.resolve_label(done_label, program.offset());
} else {
// No offset specified, just emit the row
emit_select_result(
program,
&t_ctx.resolver,
plan,
None,
None,
t_ctx.reg_nonagg_emit_once_flag,
t_ctx.reg_offset,
t_ctx.reg_result_cols_start.unwrap(),
t_ctx.limit_ctx,
)?;
}
Ok(())
}

View File

@@ -58,3 +58,9 @@ do_execsql_test_on_specific_db {:memory:} select-limit-comma-offset-equivalence
4
5}
# https://github.com/tursodatabase/turso/issues/3300
do_execsql_test_on_specific_db {:memory:} select-ungrouped-aggregate-with-offset-limit {
CREATE TABLE t(a INTEGER);
INSERT INTO t VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
SELECT COUNT(a) FROM t LIMIT 1 OFFSET 1;
} {}