diff --git a/core/translate/emitter.rs b/core/translate/emitter.rs index bf585ddd..12db50a9 100644 --- a/core/translate/emitter.rs +++ b/core/translate/emitter.rs @@ -16,8 +16,8 @@ use super::aggregation::emit_ungrouped_aggregation; use super::group_by::{emit_group_by, init_group_by, GroupByMetadata}; use super::main_loop::{close_loop, emit_loop, init_loop, open_loop, LeftJoinMetadata, LoopLabels}; use super::order_by::{emit_order_by, init_order_by, SortMetadata}; -use super::plan::SelectPlan; -use super::plan::SourceOperator; +use super::plan::Operation; +use super::plan::{SelectPlan, TableReference}; use super::subquery::emit_subqueries; #[derive(Debug)] @@ -58,7 +58,7 @@ impl<'a> Resolver<'a> { #[derive(Debug)] pub struct TranslateCtx<'a> { // A typical query plan is a nested loop. Each loop has its own LoopLabels (see the definition of LoopLabels for more details) - pub labels_main_loop: HashMap, + pub labels_main_loop: Vec, // label for the instruction that jumps to the next phase of the query after the main loop // we don't know ahead of time what that is (GROUP BY, ORDER BY, etc.) pub label_main_loop_end: Option, @@ -111,7 +111,7 @@ fn prologue<'a>( let start_offset = program.offset(); let t_ctx = TranslateCtx { - labels_main_loop: HashMap::new(), + labels_main_loop: Vec::new(), label_main_loop_end: None, reg_agg_start: None, reg_limit: None, @@ -195,12 +195,7 @@ pub fn emit_query<'a>( t_ctx: &'a mut TranslateCtx<'a>, ) -> Result { // Emit subqueries first so the results can be read in the main query loop. - emit_subqueries( - program, - t_ctx, - &mut plan.referenced_tables, - &mut plan.source, - )?; + emit_subqueries(program, t_ctx, &mut plan.table_references)?; if t_ctx.reg_limit.is_none() { t_ctx.reg_limit = plan.limit.map(|_| program.alloc_register()); @@ -236,16 +231,21 @@ pub fn emit_query<'a>( if let Some(ref mut group_by) = plan.group_by { init_group_by(program, t_ctx, group_by, &plan.aggregates)?; } - init_loop(program, t_ctx, &plan.source, &OperationMode::SELECT)?; + init_loop( + program, + t_ctx, + &plan.table_references, + &OperationMode::SELECT, + )?; // Set up main query execution loop - open_loop(program, t_ctx, &mut plan.source, &plan.referenced_tables)?; + open_loop(program, t_ctx, &plan.table_references, &plan.where_clause)?; // Process result columns and expressions in the inner loop emit_loop(program, t_ctx, plan)?; // Clean up and close the main execution loop - close_loop(program, t_ctx, &plan.source)?; + close_loop(program, t_ctx, &plan.table_references)?; program.resolve_label(after_main_loop_label, program.offset()); @@ -285,20 +285,25 @@ fn emit_program_for_delete( } // Initialize cursors and other resources needed for query execution - init_loop(program, &mut t_ctx, &plan.source, &OperationMode::DELETE)?; + init_loop( + program, + &mut t_ctx, + &plan.table_references, + &OperationMode::DELETE, + )?; // Set up main query execution loop open_loop( program, &mut t_ctx, - &mut plan.source, - &plan.referenced_tables, + &mut plan.table_references, + &plan.where_clause, )?; - emit_delete_insns(program, &mut t_ctx, &plan.source, &plan.limit)?; + emit_delete_insns(program, &mut t_ctx, &plan.table_references, &plan.limit)?; // Clean up and close the main execution loop - close_loop(program, &mut t_ctx, &plan.source)?; + close_loop(program, &mut t_ctx, &plan.table_references)?; program.resolve_label(after_main_loop_label, program.offset()); @@ -315,20 +320,15 @@ fn emit_program_for_delete( fn emit_delete_insns( program: &mut ProgramBuilder, t_ctx: &mut TranslateCtx, - source: &SourceOperator, + table_references: &[TableReference], limit: &Option, ) -> Result<()> { - let cursor_id = match source { - SourceOperator::Scan { - table_reference, .. - } => program.resolve_cursor_id(&table_reference.table_identifier), - SourceOperator::Search { - table_reference, - search, - .. - } => match search { + let table_reference = table_references.first().unwrap(); + let cursor_id = match &table_reference.op { + Operation::Scan { .. } => program.resolve_cursor_id(&table_reference.identifier), + Operation::Search(search) => match search { Search::RowidEq { .. } | Search::RowidSearch { .. } => { - program.resolve_cursor_id(&table_reference.table_identifier) + program.resolve_cursor_id(&table_reference.identifier) } Search::IndexSearch { index, .. } => program.resolve_cursor_id(&index.name), }, diff --git a/core/translate/expr.rs b/core/translate/expr.rs index 1c275f9d..0ad1ba39 100644 --- a/core/translate/expr.rs +++ b/core/translate/expr.rs @@ -13,7 +13,7 @@ use crate::vdbe::{ use crate::Result; use super::emitter::Resolver; -use super::plan::{TableReference, TableReferenceType}; +use super::plan::{Operation, TableReference}; #[derive(Debug, Clone, Copy)] pub struct ConditionMetadata { @@ -1831,12 +1831,12 @@ pub fn translate_expr( column, is_rowid_alias, } => { - let tbl_ref = referenced_tables.as_ref().unwrap().get(*table).unwrap(); - match tbl_ref.reference_type { + let table_reference = referenced_tables.as_ref().unwrap().get(*table).unwrap(); + match table_reference.op { // If we are reading a column from a table, we find the cursor that corresponds to // the table and read the column from the cursor. - TableReferenceType::BTreeTable => { - let cursor_id = program.resolve_cursor_id(&tbl_ref.table_identifier); + Operation::Scan { .. } | Operation::Search(_) => { + let cursor_id = program.resolve_cursor_id(&table_reference.identifier); if *is_rowid_alias { program.emit_insn(Insn::RowId { cursor_id, @@ -1849,13 +1849,13 @@ pub fn translate_expr( dest: target_register, }); } - let column = tbl_ref.table.get_column_at(*column); + let column = table_reference.table.get_column_at(*column); maybe_apply_affinity(column.ty, target_register, program); Ok(target_register) } // If we are reading a column from a subquery, we instead copy the column from the // subquery's result registers. - TableReferenceType::Subquery { + Operation::Subquery { result_columns_start_reg, .. } => { @@ -1869,8 +1869,8 @@ pub fn translate_expr( } } ast::Expr::RowId { database: _, table } => { - let tbl_ref = referenced_tables.as_ref().unwrap().get(*table).unwrap(); - let cursor_id = program.resolve_cursor_id(&tbl_ref.table_identifier); + let table_reference = referenced_tables.as_ref().unwrap().get(*table).unwrap(); + let cursor_id = program.resolve_cursor_id(&table_reference.identifier); program.emit_insn(Insn::RowId { cursor_id, dest: target_register, @@ -2180,8 +2180,8 @@ pub fn get_name( } match expr { ast::Expr::Column { table, column, .. } => { - let table_ref = referenced_tables.get(*table).unwrap(); - table_ref.table.get_column_at(*column).name.clone() + let table_reference = referenced_tables.get(*table).unwrap(); + table_reference.table.get_column_at(*column).name.clone() } _ => fallback(), } diff --git a/core/translate/group_by.rs b/core/translate/group_by.rs index 284f9e47..b537257a 100644 --- a/core/translate/group_by.rs +++ b/core/translate/group_by.rs @@ -274,7 +274,7 @@ pub fn emit_group_by<'a>( let agg_result_reg = start_reg + i; translate_aggregation_step_groupby( program, - &plan.referenced_tables, + &plan.table_references, pseudo_cursor, cursor_index, agg, @@ -384,7 +384,7 @@ pub fn emit_group_by<'a>( for expr in having.iter() { translate_condition_expr( program, - &plan.referenced_tables, + &plan.table_references, expr, ConditionMetadata { jump_if_condition_is_true: false, diff --git a/core/translate/order_by.rs b/core/translate/order_by.rs index 6e634123..a908da57 100644 --- a/core/translate/order_by.rs +++ b/core/translate/order_by.rs @@ -184,7 +184,7 @@ pub fn order_by_sorter_insert( let key_reg = start_reg + i; translate_expr( program, - Some(&plan.referenced_tables), + Some(&plan.table_references), expr, key_reg, &t_ctx.resolver, @@ -205,7 +205,7 @@ pub fn order_by_sorter_insert( } translate_expr( program, - Some(&plan.referenced_tables), + Some(&plan.table_references), &rc.expr, cur_reg, &t_ctx.resolver, diff --git a/core/translate/result_row.rs b/core/translate/result_row.rs index 0b4b343d..ad8454c2 100644 --- a/core/translate/result_row.rs +++ b/core/translate/result_row.rs @@ -29,7 +29,7 @@ pub fn emit_select_result( let reg = start_reg + i; translate_expr( program, - Some(&plan.referenced_tables), + Some(&plan.table_references), &rc.expr, reg, &t_ctx.resolver,