remove fields from GroupByMetadata that can be function-local

This commit is contained in:
Jussi Saurio
2025-01-04 09:53:02 +02:00
parent bd5f081ea8
commit 9ccbb69618

View File

@@ -54,18 +54,12 @@ pub struct GroupByMetadata {
pub subroutine_accumulator_clear_label: BranchOffset,
// Register holding the return offset for the accumulator clear subroutine
pub subroutine_accumulator_clear_return_offset_register: usize,
// Label for the subroutine that outputs the accumulator contents
pub subroutine_accumulator_output_label: BranchOffset,
// Register holding the return offset for the accumulator output subroutine
pub subroutine_accumulator_output_return_offset_register: usize,
// Label for the instruction that sets the accumulator indicator to true (indicating data exists in the accumulator for the current group)
pub accumulator_indicator_set_true_label: BranchOffset,
// Register holding the key used for sorting in the Sorter
pub sorter_key_register: usize,
// Register holding a flag to abort the grouping process if necessary
pub abort_flag_register: usize,
// Register holding a boolean indicating whether there's data in the accumulator (used for aggregation)
pub data_in_accumulator_indicator_register: usize,
// Register holding the start of the accumulator group registers (i.e. the groups, not the aggregates)
pub group_exprs_accumulator_register: usize,
// Starting index of the register(s) that hold the comparison result between the current row and the previous row
@@ -85,11 +79,11 @@ pub struct LoopLabels {
loop_end: BranchOffset,
}
/// The Metadata struct holds various information and labels used during bytecode generation.
/// The TranslateCtx struct holds various information and labels used during bytecode generation.
/// It is used for maintaining state and control flow during the bytecode
/// generation process.
#[derive(Debug)]
pub struct Metadata {
pub struct TranslateCtx {
// A typical query plan is a nested loop. Each loop has its own LoopLabels (see the definition of LoopLabels for more details)
loop_labels: HashMap<usize, LoopLabels>,
// label for the instruction that jumps to the next phase of the query after the main loop
@@ -126,7 +120,7 @@ pub enum OperationMode {
}
/// Initialize the program with basic setup and return initial metadata and labels
fn prologue() -> Result<(ProgramBuilder, Metadata, BranchOffset, BranchOffset)> {
fn prologue() -> Result<(ProgramBuilder, TranslateCtx, BranchOffset, BranchOffset)> {
let mut program = ProgramBuilder::new();
let init_label = program.allocate_label();
@@ -139,7 +133,7 @@ fn prologue() -> Result<(ProgramBuilder, Metadata, BranchOffset, BranchOffset)>
let start_offset = program.offset();
let metadata = Metadata {
let t_ctx = TranslateCtx {
loop_labels: HashMap::new(),
after_main_loop_label: None,
group_by_metadata: None,
@@ -152,7 +146,7 @@ fn prologue() -> Result<(ProgramBuilder, Metadata, BranchOffset, BranchOffset)>
limit_reg: None,
};
Ok((program, metadata, init_label, start_offset))
Ok((program, t_ctx, init_label, start_offset))
}
/// Clean up and finalize the program, resolving any remaining labels
@@ -201,7 +195,7 @@ fn emit_program_for_select(
connection: Weak<Connection>,
syms: &SymbolTable,
) -> Result<Program> {
let (mut program, mut metadata, init_label, start_offset) = prologue()?;
let (mut program, mut t_ctx, init_label, start_offset) = prologue()?;
// Trivial exit on LIMIT 0
if let Some(limit) = plan.limit {
@@ -212,7 +206,7 @@ fn emit_program_for_select(
}
// Emit main parts of query
emit_query(&mut program, &mut plan, &mut metadata, syms)?;
emit_query(&mut program, &mut plan, &mut t_ctx, syms)?;
// Finalize program
epilogue(&mut program, init_label, start_offset)?;
@@ -296,7 +290,7 @@ fn emit_subquery(
_ => unreachable!("emit_subquery called on non-subquery"),
}
let end_coroutine_label = program.allocate_label();
let mut metadata = Metadata {
let mut metadata = TranslateCtx {
loop_labels: HashMap::new(),
after_main_loop_label: None,
group_by_metadata: None,
@@ -336,21 +330,21 @@ fn emit_subquery(
fn emit_query(
program: &mut ProgramBuilder,
plan: &mut SelectPlan,
metadata: &mut Metadata,
t_ctx: &mut TranslateCtx,
syms: &SymbolTable,
) -> Result<usize> {
// Emit subqueries first so the results can be read in the main query loop.
emit_subqueries(program, &mut plan.referenced_tables, &mut plan.source, syms)?;
if metadata.limit_reg.is_none() {
metadata.limit_reg = plan.limit.map(|_| program.alloc_register());
if t_ctx.limit_reg.is_none() {
t_ctx.limit_reg = plan.limit.map(|_| program.alloc_register());
}
// No rows will be read from source table loops if there is a constant false condition eg. WHERE 0
// however an aggregation might still happen,
// e.g. SELECT COUNT(*) WHERE 0 returns a row with 0, not an empty result set
let after_main_loop_label = program.allocate_label();
metadata.after_main_loop_label = Some(after_main_loop_label);
t_ctx.after_main_loop_label = Some(after_main_loop_label);
if plan.contains_constant_false_condition {
program.emit_insn_with_label_dependency(
Insn::Goto {
@@ -361,33 +355,32 @@ fn emit_query(
}
// Allocate registers for result columns
metadata.result_column_start_register =
Some(program.alloc_registers(plan.result_columns.len()));
t_ctx.result_column_start_register = Some(program.alloc_registers(plan.result_columns.len()));
// Initialize cursors and other resources needed for query execution
if let Some(ref mut order_by) = plan.order_by {
init_order_by(program, order_by, metadata)?;
init_order_by(program, order_by, t_ctx)?;
}
if let Some(ref mut group_by) = plan.group_by {
init_group_by(program, group_by, &plan.aggregates, metadata)?;
init_group_by(program, group_by, &plan.aggregates, t_ctx)?;
}
init_source(program, &plan.source, metadata, &OperationMode::SELECT)?;
init_source(program, &plan.source, t_ctx, &OperationMode::SELECT)?;
// Set up main query execution loop
open_loop(
program,
&mut plan.source,
&plan.referenced_tables,
metadata,
t_ctx,
syms,
)?;
// Process result columns and expressions in the inner loop
inner_loop_emit(program, plan, metadata, syms)?;
inner_loop_emit(program, plan, t_ctx, syms)?;
// Clean up and close the main execution loop
close_loop(program, &plan.source, metadata)?;
close_loop(program, &plan.source, t_ctx)?;
program.resolve_label(after_main_loop_label, program.offset());
@@ -403,7 +396,7 @@ fn emit_query(
&plan.aggregates,
plan.limit,
&plan.referenced_tables,
metadata,
t_ctx,
syms,
&plan.query_type,
)?;
@@ -414,7 +407,7 @@ fn emit_query(
&plan.referenced_tables,
&plan.result_columns,
&plan.aggregates,
metadata,
t_ctx,
syms,
&plan.query_type,
)?;
@@ -430,13 +423,13 @@ fn emit_query(
order_by,
&plan.result_columns,
plan.limit,
metadata,
t_ctx,
&plan.query_type,
)?;
}
}
Ok(metadata.result_column_start_register.unwrap())
Ok(t_ctx.result_column_start_register.unwrap())
}
fn emit_program_for_delete(
@@ -445,7 +438,7 @@ fn emit_program_for_delete(
connection: Weak<Connection>,
syms: &SymbolTable,
) -> Result<Program> {
let (mut program, mut metadata, init_label, start_offset) = prologue()?;
let (mut program, mut t_ctx, init_label, start_offset) = prologue()?;
// No rows will be read from source table loops if there is a constant false condition eg. WHERE 0
let after_main_loop_label = program.allocate_label();
@@ -462,7 +455,7 @@ fn emit_program_for_delete(
init_source(
&mut program,
&plan.source,
&mut metadata,
&mut t_ctx,
&OperationMode::DELETE,
)?;
@@ -471,14 +464,14 @@ fn emit_program_for_delete(
&mut program,
&mut plan.source,
&plan.referenced_tables,
&mut metadata,
&mut t_ctx,
syms,
)?;
emit_delete_insns(&mut program, &plan.source, &plan.limit, &metadata)?;
emit_delete_insns(&mut program, &plan.source, &plan.limit, &t_ctx)?;
// Clean up and close the main execution loop
close_loop(&mut program, &plan.source, &mut metadata)?;
close_loop(&mut program, &plan.source, &mut t_ctx)?;
program.resolve_label(after_main_loop_label, program.offset());
@@ -492,10 +485,10 @@ fn emit_program_for_delete(
fn init_order_by(
program: &mut ProgramBuilder,
order_by: &[(ast::Expr, Direction)],
metadata: &mut Metadata,
t_ctx: &mut TranslateCtx,
) -> Result<()> {
let sort_cursor = program.alloc_cursor_id(None, None);
metadata.sort_metadata = Some(SortMetadata {
t_ctx.sort_metadata = Some(SortMetadata {
sort_cursor,
sorter_data_register: program.alloc_register(),
});
@@ -516,21 +509,19 @@ fn init_group_by(
program: &mut ProgramBuilder,
group_by: &GroupBy,
aggregates: &[Aggregate],
metadata: &mut Metadata,
t_ctx: &mut TranslateCtx,
) -> Result<()> {
let num_aggs = aggregates.len();
let sort_cursor = program.alloc_cursor_id(None, None);
let abort_flag_register = program.alloc_register();
let data_in_accumulator_indicator_register = program.alloc_register();
let group_exprs_comparison_register = program.alloc_registers(group_by.exprs.len());
let group_exprs_accumulator_register = program.alloc_registers(group_by.exprs.len());
let agg_exprs_start_reg = program.alloc_registers(num_aggs);
let sorter_key_register = program.alloc_register();
let subroutine_accumulator_clear_label = program.allocate_label();
let subroutine_accumulator_output_label = program.allocate_label();
let mut order = Vec::new();
const ASCENDING: i64 = 0;
@@ -573,17 +564,14 @@ fn init_group_by(
subroutine_accumulator_clear_label,
);
metadata.aggregation_start_register = Some(agg_exprs_start_reg);
t_ctx.aggregation_start_register = Some(agg_exprs_start_reg);
metadata.group_by_metadata = Some(GroupByMetadata {
t_ctx.group_by_metadata = Some(GroupByMetadata {
sort_cursor,
subroutine_accumulator_clear_label,
subroutine_accumulator_clear_return_offset_register,
subroutine_accumulator_output_label,
subroutine_accumulator_output_return_offset_register: program.alloc_register(),
accumulator_indicator_set_true_label: program.allocate_label(),
abort_flag_register,
data_in_accumulator_indicator_register,
group_exprs_accumulator_register,
group_exprs_comparison_register,
sorter_key_register,
@@ -595,7 +583,7 @@ fn init_group_by(
fn init_source(
program: &mut ProgramBuilder,
source: &SourceOperator,
metadata: &mut Metadata,
t_ctx: &mut TranslateCtx,
mode: &OperationMode,
) -> Result<()> {
let operator_id = source.id();
@@ -604,7 +592,7 @@ fn init_source(
loop_start: program.allocate_label(),
loop_end: program.allocate_label(),
};
metadata.loop_labels.insert(operator_id, loop_labels);
t_ctx.loop_labels.insert(operator_id, loop_labels);
match source {
SourceOperator::Subquery { .. } => Ok(()),
@@ -621,10 +609,10 @@ fn init_source(
set_match_flag_true_label: program.allocate_label(),
check_match_flag_label: program.allocate_label(),
};
metadata.left_joins.insert(*id, lj_metadata);
t_ctx.left_joins.insert(*id, lj_metadata);
}
init_source(program, left, metadata, mode)?;
init_source(program, right, metadata, mode)?;
init_source(program, left, t_ctx, mode)?;
init_source(program, right, t_ctx, mode)?;
Ok(())
}
@@ -727,7 +715,7 @@ fn open_loop(
program: &mut ProgramBuilder,
source: &mut SourceOperator,
referenced_tables: &[TableReference],
metadata: &mut Metadata,
t_ctx: &mut TranslateCtx,
syms: &SymbolTable,
) -> Result<()> {
match source {
@@ -750,7 +738,7 @@ fn open_loop(
jump_on_definition: 0,
start_offset: coroutine_implementation_start,
});
let loop_labels = metadata
let loop_labels = t_ctx
.loop_labels
.get(id)
.expect("subquery has no loop labels");
@@ -800,9 +788,9 @@ fn open_loop(
outer,
..
} => {
open_loop(program, left, referenced_tables, metadata, syms)?;
open_loop(program, left, referenced_tables, t_ctx, syms)?;
let loop_labels = metadata
let loop_labels = t_ctx
.loop_labels
.get(&right.id())
.expect("right side of join has no loop labels");
@@ -810,7 +798,7 @@ fn open_loop(
let mut jump_target_when_false = loop_labels.next;
if *outer {
let lj_meta = metadata.left_joins.get(id).unwrap();
let lj_meta = t_ctx.left_joins.get(id).unwrap();
program.emit_insn(Insn::Integer {
value: 0,
dest: lj_meta.match_flag_register,
@@ -818,7 +806,7 @@ fn open_loop(
jump_target_when_false = lj_meta.check_match_flag_label;
}
open_loop(program, right, referenced_tables, metadata, syms)?;
open_loop(program, right, referenced_tables, t_ctx, syms)?;
if let Some(predicates) = predicates {
let jump_target_when_true = program.allocate_label();
@@ -841,7 +829,7 @@ fn open_loop(
}
if *outer {
let lj_meta = metadata.left_joins.get(id).unwrap();
let lj_meta = t_ctx.left_joins.get(id).unwrap();
program.defer_label_resolution(
lj_meta.set_match_flag_true_label,
program.offset() as usize,
@@ -869,10 +857,7 @@ fn open_loop(
} else {
program.emit_insn(Insn::RewindAsync { cursor_id });
}
let loop_labels = metadata
.loop_labels
.get(id)
.expect("scan has no loop labels");
let loop_labels = t_ctx.loop_labels.get(id).expect("scan has no loop labels");
program.emit_insn_with_label_dependency(
if iter_dir
.as_ref()
@@ -922,7 +907,7 @@ fn open_loop(
..
} => {
let table_cursor_id = program.resolve_cursor_id(&table_reference.table_identifier);
let loop_labels = metadata
let loop_labels = t_ctx
.loop_labels
.get(id)
.expect("search has no loop labels");
@@ -1148,7 +1133,7 @@ pub enum InnerLoopEmitTarget<'a> {
fn inner_loop_emit(
program: &mut ProgramBuilder,
plan: &mut SelectPlan,
metadata: &mut Metadata,
t_ctx: &mut TranslateCtx,
syms: &SymbolTable,
) -> Result<()> {
// if we have a group by, we emit a record into the group by sorter.
@@ -1157,7 +1142,7 @@ fn inner_loop_emit(
program,
&plan.result_columns,
&plan.aggregates,
metadata,
t_ctx,
InnerLoopEmitTarget::GroupBySorter {
group_by,
aggregates: &plan.aggregates,
@@ -1173,7 +1158,7 @@ fn inner_loop_emit(
program,
&plan.result_columns,
&plan.aggregates,
metadata,
t_ctx,
InnerLoopEmitTarget::AggStep,
&plan.referenced_tables,
syms,
@@ -1185,7 +1170,7 @@ fn inner_loop_emit(
program,
&plan.result_columns,
&plan.aggregates,
metadata,
t_ctx,
InnerLoopEmitTarget::OrderBySorter { order_by },
&plan.referenced_tables,
syms,
@@ -1196,7 +1181,7 @@ fn inner_loop_emit(
program,
&plan.result_columns,
&plan.aggregates,
metadata,
t_ctx,
InnerLoopEmitTarget::QueryResult {
query_type: &plan.query_type,
limit: plan.limit,
@@ -1213,7 +1198,7 @@ fn inner_loop_source_emit(
program: &mut ProgramBuilder,
result_columns: &[ResultSetColumn],
aggregates: &[Aggregate],
metadata: &mut Metadata,
t_ctx: &mut TranslateCtx,
emit_target: InnerLoopEmitTarget,
referenced_tables: &[TableReference],
syms: &SymbolTable,
@@ -1254,7 +1239,7 @@ fn inner_loop_source_emit(
// TODO: although it's less often useful, SQLite does allow for expressions in the SELECT that are not part of a GROUP BY or aggregate.
// We currently ignore those and only emit the GROUP BY keys and aggregate arguments. This should be fixed.
let group_by_metadata = metadata.group_by_metadata.as_ref().unwrap();
let group_by_metadata = t_ctx.group_by_metadata.as_ref().unwrap();
sorter_insert(
program,
@@ -1272,8 +1257,8 @@ fn inner_loop_source_emit(
referenced_tables,
order_by,
result_columns,
&mut metadata.result_column_indexes_in_orderby_sorter,
metadata.sort_metadata.as_ref().unwrap(),
&mut t_ctx.result_column_indexes_in_orderby_sorter,
t_ctx.sort_metadata.as_ref().unwrap(),
None,
syms,
)?;
@@ -1282,7 +1267,7 @@ fn inner_loop_source_emit(
InnerLoopEmitTarget::AggStep => {
let num_aggs = aggregates.len();
let start_reg = program.alloc_registers(num_aggs);
metadata.aggregation_start_register = Some(start_reg);
t_ctx.aggregation_start_register = Some(start_reg);
// In planner.rs, we have collected all aggregates from the SELECT clause, including ones where the aggregate is embedded inside
// a more complex expression. Some examples: length(sum(x)), sum(x) + avg(y), sum(x) + 1, etc.
@@ -1313,13 +1298,13 @@ fn inner_loop_source_emit(
program,
referenced_tables,
result_columns,
metadata.result_column_start_register.unwrap(),
t_ctx.result_column_start_register.unwrap(),
None,
limit.map(|l| {
(
l,
metadata.limit_reg.unwrap(),
metadata.after_main_loop_label.unwrap(),
t_ctx.limit_reg.unwrap(),
t_ctx.after_main_loop_label.unwrap(),
)
}),
syms,
@@ -1337,9 +1322,9 @@ fn inner_loop_source_emit(
fn close_loop(
program: &mut ProgramBuilder,
source: &SourceOperator,
metadata: &mut Metadata,
t_ctx: &mut TranslateCtx,
) -> Result<()> {
let loop_labels = *metadata
let loop_labels = *t_ctx
.loop_labels
.get(&source.id())
.expect("source has no loop labels");
@@ -1363,10 +1348,10 @@ fn close_loop(
outer,
..
} => {
close_loop(program, right, metadata)?;
close_loop(program, right, t_ctx)?;
if *outer {
let lj_meta = metadata.left_joins.get(id).unwrap();
let lj_meta = t_ctx.left_joins.get(id).unwrap();
// The left join match flag is set to 1 when there is any match on the right table
// (e.g. SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a).
// If the left join match flag has been set to 1, we jump to the next row on the outer table,
@@ -1410,7 +1395,7 @@ fn close_loop(
assert!(program.offset() == jump_offset);
}
close_loop(program, left, metadata)?;
close_loop(program, left, t_ctx)?;
}
SourceOperator::Scan {
table_reference,
@@ -1486,7 +1471,7 @@ fn emit_delete_insns(
program: &mut ProgramBuilder,
source: &SourceOperator,
limit: &Option<usize>,
metadata: &Metadata,
t_ctx: &TranslateCtx,
) -> Result<()> {
let cursor_id = match source {
SourceOperator::Scan {
@@ -1523,9 +1508,9 @@ fn emit_delete_insns(
program.emit_insn_with_label_dependency(
Insn::DecrJumpZero {
reg: limit_reg,
target_pc: metadata.after_main_loop_label.unwrap(),
target_pc: t_ctx.after_main_loop_label.unwrap(),
},
metadata.after_main_loop_label.unwrap(),
t_ctx.after_main_loop_label.unwrap(),
)
}
@@ -1544,7 +1529,7 @@ fn group_by_emit(
aggregates: &[Aggregate],
limit: Option<usize>,
referenced_tables: &[TableReference],
metadata: &mut Metadata,
t_ctx: &mut TranslateCtx,
syms: &SymbolTable,
query_type: &SelectQueryType,
) -> Result<()> {
@@ -1552,15 +1537,16 @@ fn group_by_emit(
let grouping_done_label = program.allocate_label();
let group_by_output_row_label = program.allocate_label();
let group_by_end_label = program.allocate_label();
let group_by_metadata = metadata.group_by_metadata.as_mut().unwrap();
let group_by_metadata = t_ctx.group_by_metadata.as_mut().unwrap();
let subroutine_accumulator_output_label = program.allocate_label();
let subroutine_accumulator_output_return_offset_register = program.alloc_register();
// Register holding a boolean indicating whether there's data in the accumulator (used for aggregation)
let data_in_accumulator_indicator_register = program.alloc_register();
let GroupByMetadata {
group_exprs_comparison_register: comparison_register,
subroutine_accumulator_output_return_offset_register,
subroutine_accumulator_output_label,
subroutine_accumulator_clear_return_offset_register,
subroutine_accumulator_clear_label,
data_in_accumulator_indicator_register,
accumulator_indicator_set_true_label,
group_exprs_accumulator_register: group_exprs_start_register,
abort_flag_register,
@@ -1687,7 +1673,7 @@ fn group_by_emit(
// Accumulate the values into the aggregations
program.resolve_label(agg_step_label, program.offset());
let start_reg = metadata.aggregation_start_register.unwrap();
let start_reg = t_ctx.aggregation_start_register.unwrap();
let mut cursor_index = group_by.exprs.len();
for (i, agg) in aggregates.iter().enumerate() {
let agg_result_reg = start_reg + i;
@@ -1748,10 +1734,10 @@ fn group_by_emit(
program.add_comment(program.offset(), "emit row for final group");
program.emit_insn_with_label_dependency(
Insn::Gosub {
target_pc: group_by_metadata.subroutine_accumulator_output_label,
return_reg: group_by_metadata.subroutine_accumulator_output_return_offset_register,
target_pc: subroutine_accumulator_output_label,
return_reg: subroutine_accumulator_output_return_offset_register,
},
group_by_metadata.subroutine_accumulator_output_label,
subroutine_accumulator_output_label,
);
program.add_comment(program.offset(), "group by finished");
@@ -1766,18 +1752,15 @@ fn group_by_emit(
dest: group_by_metadata.abort_flag_register,
});
program.emit_insn(Insn::Return {
return_reg: group_by_metadata.subroutine_accumulator_output_return_offset_register,
return_reg: subroutine_accumulator_output_return_offset_register,
});
program.resolve_label(
group_by_metadata.subroutine_accumulator_output_label,
program.offset(),
);
program.resolve_label(subroutine_accumulator_output_label, program.offset());
program.add_comment(program.offset(), "output group by row subroutine start");
program.emit_insn_with_label_dependency(
Insn::IfPos {
reg: group_by_metadata.data_in_accumulator_indicator_register,
reg: data_in_accumulator_indicator_register,
target_pc: group_by_output_row_label,
decrement_by: 0,
},
@@ -1789,10 +1772,10 @@ fn group_by_emit(
program.offset() as usize,
);
program.emit_insn(Insn::Return {
return_reg: group_by_metadata.subroutine_accumulator_output_return_offset_register,
return_reg: subroutine_accumulator_output_return_offset_register,
});
let agg_start_reg = metadata.aggregation_start_register.unwrap();
let agg_start_reg = t_ctx.aggregation_start_register.unwrap();
// Resolve the label for the start of the group by output row subroutine
program.resolve_label(group_by_output_row_label, program.offset());
for (i, agg) in aggregates.iter().enumerate() {
@@ -1839,9 +1822,9 @@ fn group_by_emit(
program,
referenced_tables,
result_columns,
metadata.result_column_start_register.unwrap(),
t_ctx.result_column_start_register.unwrap(),
Some(&precomputed_exprs_to_register),
limit.map(|l| (l, metadata.limit_reg.unwrap(), group_by_end_label)),
limit.map(|l| (l, t_ctx.limit_reg.unwrap(), group_by_end_label)),
syms,
query_type,
)?;
@@ -1852,8 +1835,8 @@ fn group_by_emit(
referenced_tables,
order_by,
result_columns,
&mut metadata.result_column_indexes_in_orderby_sorter,
metadata.sort_metadata.as_ref().unwrap(),
&mut t_ctx.result_column_indexes_in_orderby_sorter,
t_ctx.sort_metadata.as_ref().unwrap(),
Some(&precomputed_exprs_to_register),
syms,
)?;
@@ -1861,7 +1844,7 @@ fn group_by_emit(
}
program.emit_insn(Insn::Return {
return_reg: group_by_metadata.subroutine_accumulator_output_return_offset_register,
return_reg: subroutine_accumulator_output_return_offset_register,
});
program.add_comment(program.offset(), "clear accumulator subroutine start");
@@ -1877,10 +1860,10 @@ fn group_by_emit(
program.emit_insn(Insn::Integer {
value: 0,
dest: group_by_metadata.data_in_accumulator_indicator_register,
dest: data_in_accumulator_indicator_register,
});
program.emit_insn(Insn::Return {
return_reg: group_by_metadata.subroutine_accumulator_clear_return_offset_register,
return_reg: subroutine_accumulator_clear_return_offset_register,
});
program.resolve_label(group_by_end_label, program.offset());
@@ -1896,11 +1879,11 @@ fn agg_without_group_by_emit(
referenced_tables: &[TableReference],
result_columns: &[ResultSetColumn],
aggregates: &[Aggregate],
metadata: &mut Metadata,
t_ctx: &mut TranslateCtx,
syms: &SymbolTable,
query_type: &SelectQueryType,
) -> Result<()> {
let agg_start_reg = metadata.aggregation_start_register.unwrap();
let agg_start_reg = t_ctx.aggregation_start_register.unwrap();
for (i, agg) in aggregates.iter().enumerate() {
let agg_result_reg = agg_start_reg + i;
program.emit_insn(Insn::AggFinal {
@@ -1922,7 +1905,7 @@ fn agg_without_group_by_emit(
program,
referenced_tables,
result_columns,
metadata.result_column_start_register.unwrap(),
t_ctx.result_column_start_register.unwrap(),
Some(&precomputed_exprs_to_register),
None,
syms,
@@ -1940,7 +1923,7 @@ fn order_by_emit(
order_by: &[(ast::Expr, Direction)],
result_columns: &[ResultSetColumn],
limit: Option<usize>,
metadata: &mut Metadata,
t_ctx: &mut TranslateCtx,
query_type: &SelectQueryType,
) -> Result<()> {
let sort_loop_start_label = program.allocate_label();
@@ -1957,7 +1940,7 @@ fn order_by_emit(
}
for (i, rc) in result_columns.iter().enumerate() {
// If any result columns are not in the ORDER BY sorter, it's because they are equal to a sort key and were already added to the pseudo columns above.
if let Some(ref v) = metadata.result_columns_to_skip_in_orderby_sorter {
if let Some(ref v) = t_ctx.result_columns_to_skip_in_orderby_sorter {
if v.contains(&i) {
continue;
}
@@ -1971,7 +1954,7 @@ fn order_by_emit(
}
let num_columns_in_sorter = order_by.len() + result_columns.len()
- metadata
- t_ctx
.result_columns_to_skip_in_orderby_sorter
.as_ref()
.map(|v| v.len())
@@ -1983,7 +1966,7 @@ fn order_by_emit(
columns: pseudo_columns,
}))),
);
let sort_metadata = metadata.sort_metadata.as_mut().unwrap();
let sort_metadata = t_ctx.sort_metadata.as_mut().unwrap();
program.emit_insn(Insn::OpenPseudo {
cursor_id: pseudo_cursor,
@@ -2009,12 +1992,12 @@ fn order_by_emit(
// We emit the columns in SELECT order, not sorter order (sorter always has the sort keys first).
// This is tracked in m.result_column_indexes_in_orderby_sorter.
let cursor_id = pseudo_cursor;
let start_reg = metadata.result_column_start_register.unwrap();
let start_reg = t_ctx.result_column_start_register.unwrap();
for i in 0..result_columns.len() {
let reg = start_reg + i;
program.emit_insn(Insn::Column {
cursor_id,
column: metadata.result_column_indexes_in_orderby_sorter[&i],
column: t_ctx.result_column_indexes_in_orderby_sorter[&i],
dest: reg,
});
}
@@ -2023,7 +2006,7 @@ fn order_by_emit(
program,
start_reg,
result_columns.len(),
limit.map(|l| (l, metadata.limit_reg.unwrap(), sort_loop_end_label)),
limit.map(|l| (l, t_ctx.limit_reg.unwrap(), sort_loop_end_label)),
query_type,
)?;