From b3c57d569115e4fd1b69288c771da42dfa54e194 Mon Sep 17 00:00:00 2001 From: jussisaurio Date: Sun, 13 Oct 2024 11:25:33 +0300 Subject: [PATCH] core/translate: (refactor) use btreetablereference struct instead of tuple --- core/translate/emitter.rs | 97 ++++++++++++++++--------------- core/translate/expr.rs | 42 ++++++++------ core/translate/optimizer.rs | 95 ++++++++++++++---------------- core/translate/plan.rs | 111 +++++++++++++++++++++++------------- core/translate/planner.rs | 33 +++++------ 5 files changed, 206 insertions(+), 172 deletions(-) diff --git a/core/translate/emitter.rs b/core/translate/emitter.rs index cb0ed95c4..1271b2a63 100644 --- a/core/translate/emitter.rs +++ b/core/translate/emitter.rs @@ -18,7 +18,7 @@ use super::expr::{ ConditionMetadata, }; use super::optimizer::ExpressionResultCache; -use super::plan::Plan; +use super::plan::{BTreeTableReference, Plan}; use super::plan::{Operator, ProjectionColumn}; /** @@ -32,19 +32,19 @@ pub trait Emitter { &mut self, pb: &mut ProgramBuilder, m: &mut Metadata, - referenced_tables: &[(Rc, String)], + referenced_tables: &[BTreeTableReference], ) -> Result; fn result_columns( &self, program: &mut ProgramBuilder, - referenced_tables: &[(Rc, String)], + referenced_tables: &[BTreeTableReference], metadata: &mut Metadata, cursor_override: Option<&SortCursorOverride>, ) -> Result; fn result_row( &mut self, program: &mut ProgramBuilder, - referenced_tables: &[(Rc, String)], + referenced_tables: &[BTreeTableReference], metadata: &mut Metadata, cursor_override: Option<&SortCursorOverride>, ) -> Result<()>; @@ -163,13 +163,12 @@ impl Emitter for Operator { &mut self, program: &mut ProgramBuilder, m: &mut Metadata, - referenced_tables: &[(Rc, String)], + referenced_tables: &[BTreeTableReference], ) -> Result { let current_operator_column_count = self.column_count(referenced_tables); match self { Operator::Scan { - table, - table_identifier, + table_reference, id, step, predicates, @@ -182,10 +181,10 @@ impl Emitter for Operator { match *step { SCAN_OPEN_READ => { let cursor_id = program.alloc_cursor_id( - Some(table_identifier.clone()), - Some(Table::BTree(table.clone())), + Some(table_reference.table_identifier.clone()), + Some(Table::BTree(table_reference.table.clone())), ); - let root_page = table.root_page; + let root_page = table_reference.table.root_page; let next_row_label = program.allocate_label(); m.next_row_labels.insert(*id, next_row_label); program.emit_insn(Insn::OpenReadAsync { @@ -197,7 +196,8 @@ impl Emitter for Operator { Ok(OpStepResult::Continue) } SCAN_BODY => { - let cursor_id = program.resolve_cursor_id(table_identifier, None); + let cursor_id = + program.resolve_cursor_id(&table_reference.table_identifier, None); program.emit_insn(Insn::RewindAsync { cursor_id }); let scan_loop_body_label = program.allocate_label(); let halt_label = m.termination_label_stack.last().unwrap(); @@ -237,7 +237,8 @@ impl Emitter for Operator { Ok(OpStepResult::ReadyToEmit) } SCAN_NEXT => { - let cursor_id = program.resolve_cursor_id(table_identifier, None); + let cursor_id = + program.resolve_cursor_id(&table_reference.table_identifier, None); program .resolve_label(*m.next_row_labels.get(id).unwrap(), program.offset()); program.emit_insn(Insn::NextAsync { cursor_id }); @@ -255,8 +256,7 @@ impl Emitter for Operator { } } Operator::Search { - table, - table_identifier, + table_reference, search, predicates, step, @@ -270,8 +270,8 @@ impl Emitter for Operator { match *step { SEARCH_OPEN_READ => { let table_cursor_id = program.alloc_cursor_id( - Some(table_identifier.clone()), - Some(Table::BTree(table.clone())), + Some(table_reference.table_identifier.clone()), + Some(Table::BTree(table_reference.table.clone())), ); let next_row_label = program.allocate_label(); @@ -285,7 +285,7 @@ impl Emitter for Operator { m.scan_loop_body_labels.push(scan_loop_body_label); program.emit_insn(Insn::OpenReadAsync { cursor_id: table_cursor_id, - root_page: table.root_page, + root_page: table_reference.table.root_page, }); program.emit_insn(Insn::OpenReadAwait); @@ -303,7 +303,8 @@ impl Emitter for Operator { Ok(OpStepResult::Continue) } SEARCH_BODY => { - let table_cursor_id = program.resolve_cursor_id(table_identifier, None); + let table_cursor_id = + program.resolve_cursor_id(&table_reference.table_identifier, None); // Open the loop for the index search. // Primary key equality search is handled with a SeekRowid instruction which does not loop, since it is a single row lookup. @@ -521,7 +522,7 @@ impl Emitter for Operator { program.resolve_cursor_id(&index.name, None) } Search::PrimaryKeySearch { .. } => { - program.resolve_cursor_id(table_identifier, None) + program.resolve_cursor_id(&table_reference.table_identifier, None) } Search::PrimaryKeyEq { .. } => unreachable!(), }; @@ -642,11 +643,13 @@ impl Emitter for Operator { // If not, we set the right table cursor's "pseudo null bit" on, which means any Insn::Column will return NULL let right_cursor_id = match right.as_ref() { Operator::Scan { - table_identifier, .. - } => program.resolve_cursor_id(table_identifier, None), + table_reference, .. + } => program + .resolve_cursor_id(&table_reference.table_identifier, None), Operator::Search { - table_identifier, .. - } => program.resolve_cursor_id(table_identifier, None), + table_reference, .. + } => program + .resolve_cursor_id(&table_reference.table_identifier, None), _ => unreachable!(), }; program.emit_insn(Insn::NullRow { @@ -1394,41 +1397,37 @@ impl Emitter for Operator { fn result_columns( &self, program: &mut ProgramBuilder, - referenced_tables: &[(Rc, String)], + referenced_tables: &[BTreeTableReference], m: &mut Metadata, cursor_override: Option<&SortCursorOverride>, ) -> Result { let col_count = self.column_count(referenced_tables); match self { Operator::Scan { - table, - table_identifier, - .. + table_reference, .. } => { let start_reg = program.alloc_registers(col_count); let table = cursor_override .map(|c| c.pseudo_table.clone()) - .unwrap_or_else(|| Table::BTree(table.clone())); - let cursor_id = cursor_override - .map(|c| c.cursor_id) - .unwrap_or_else(|| program.resolve_cursor_id(table_identifier, None)); + .unwrap_or_else(|| Table::BTree(table_reference.table.clone())); + let cursor_id = cursor_override.map(|c| c.cursor_id).unwrap_or_else(|| { + program.resolve_cursor_id(&table_reference.table_identifier, None) + }); let start_column_offset = cursor_override.map(|c| c.sort_key_len).unwrap_or(0); translate_table_columns(program, cursor_id, &table, start_column_offset, start_reg); Ok(start_reg) } Operator::Search { - table, - table_identifier, - .. + table_reference, .. } => { let start_reg = program.alloc_registers(col_count); let table = cursor_override .map(|c| c.pseudo_table.clone()) - .unwrap_or_else(|| Table::BTree(table.clone())); - let cursor_id = cursor_override - .map(|c| c.cursor_id) - .unwrap_or_else(|| program.resolve_cursor_id(table_identifier, None)); + .unwrap_or_else(|| Table::BTree(table_reference.table.clone())); + let cursor_id = cursor_override.map(|c| c.cursor_id).unwrap_or_else(|| { + program.resolve_cursor_id(&table_reference.table_identifier, None) + }); let start_column_offset = cursor_override.map(|c| c.sort_key_len).unwrap_or(0); translate_table_columns(program, cursor_id, &table, start_column_offset, start_reg); @@ -1544,13 +1543,16 @@ impl Emitter for Operator { cur_reg += 1; } ProjectionColumn::Star => { - for (table, table_identifier) in referenced_tables.iter() { + for table_reference in referenced_tables.iter() { let table = cursor_override .map(|c| c.pseudo_table.clone()) - .unwrap_or_else(|| Table::BTree(table.clone())); + .unwrap_or_else(|| Table::BTree(table_reference.table.clone())); let cursor_id = cursor_override.map(|c| c.cursor_id).unwrap_or_else(|| { - program.resolve_cursor_id(table_identifier, None) + program.resolve_cursor_id( + &table_reference.table_identifier, + None, + ) }); let start_column_offset = cursor_override.map(|c| c.sort_key_len).unwrap_or(0); @@ -1563,18 +1565,19 @@ impl Emitter for Operator { ); } } - ProjectionColumn::TableStar(_, table_identifier) => { - let (table, table_identifier) = referenced_tables + ProjectionColumn::TableStar(table_reference) => { + let table_ref = referenced_tables .iter() - .find(|(_, id)| id == table_identifier) + .find(|t| t.table_identifier == table_reference.table_identifier) .unwrap(); let table = cursor_override .map(|c| c.pseudo_table.clone()) - .unwrap_or_else(|| Table::BTree(table.clone())); + .unwrap_or_else(|| Table::BTree(table_ref.table.clone())); let cursor_id = cursor_override.map(|c| c.cursor_id).unwrap_or_else(|| { - program.resolve_cursor_id(table_identifier, None) + program + .resolve_cursor_id(&table_reference.table_identifier, None) }); let start_column_offset = cursor_override.map(|c| c.sort_key_len).unwrap_or(0); @@ -1597,7 +1600,7 @@ impl Emitter for Operator { fn result_row( &mut self, program: &mut ProgramBuilder, - referenced_tables: &[(Rc, String)], + referenced_tables: &[BTreeTableReference], m: &mut Metadata, cursor_override: Option<&SortCursorOverride>, ) -> Result<()> { diff --git a/core/translate/expr.rs b/core/translate/expr.rs index d8c0c2604..83c891975 100644 --- a/core/translate/expr.rs +++ b/core/translate/expr.rs @@ -11,7 +11,7 @@ use crate::{ vdbe::{builder::ProgramBuilder, BranchOffset, Insn}, }; -use super::plan::Aggregate; +use super::plan::{Aggregate, BTreeTableReference}; #[derive(Default, Debug, Clone, Copy)] pub struct ConditionMetadata { @@ -22,7 +22,7 @@ pub struct ConditionMetadata { pub fn translate_condition_expr( program: &mut ProgramBuilder, - referenced_tables: &[(Rc, String)], + referenced_tables: &[BTreeTableReference], expr: &ast::Expr, cursor_hint: Option, condition_metadata: ConditionMetadata, @@ -555,7 +555,7 @@ pub fn translate_condition_expr( pub fn get_cached_or_translate( program: &mut ProgramBuilder, - referenced_tables: Option<&[(Rc, String)]>, + referenced_tables: Option<&[BTreeTableReference]>, expr: &ast::Expr, cursor_hint: Option, cached_results: Option<&Vec<&CachedResult>>, @@ -582,7 +582,7 @@ pub fn get_cached_or_translate( pub fn translate_expr( program: &mut ProgramBuilder, - referenced_tables: Option<&[(Rc, String)]>, + referenced_tables: Option<&[BTreeTableReference]>, expr: &ast::Expr, target_register: usize, cursor_hint: Option, @@ -1541,14 +1541,15 @@ pub fn resolve_ident_qualified( program: &ProgramBuilder, table_name: &str, ident: &str, - referenced_tables: &[(Rc, String)], + referenced_tables: &[BTreeTableReference], cursor_hint: Option, ) -> Result<(usize, Type, usize, bool)> { let ident = normalize_ident(ident); let table_name = normalize_ident(table_name); - for (catalog_table, identifier) in referenced_tables.iter() { - if *identifier == table_name { - let res = catalog_table + for table_reference in referenced_tables.iter() { + if table_reference.table_identifier == table_name { + let res = table_reference + .table .columns .iter() .enumerate() @@ -1573,7 +1574,8 @@ pub fn resolve_ident_qualified( is_primary_key = res.1.primary_key; } } - let cursor_id = program.resolve_cursor_id(identifier, cursor_hint); + let cursor_id = + program.resolve_cursor_id(&table_reference.table_identifier, cursor_hint); return Ok((idx, col_type, cursor_id, is_primary_key)); } } @@ -1588,18 +1590,25 @@ pub fn resolve_ident_qualified( pub fn resolve_ident_table( program: &ProgramBuilder, ident: &str, - referenced_tables: Option<&[(Rc, String)]>, + referenced_tables: Option<&[BTreeTableReference]>, cursor_hint: Option, ) -> Result<(usize, Type, usize, bool)> { let ident = normalize_ident(ident); let mut found = Vec::new(); - for (catalog_table, identifier) in referenced_tables.unwrap() { - let res = catalog_table + for table_reference in referenced_tables.unwrap() { + let res = table_reference + .table .columns .iter() .enumerate() .find(|(_, col)| col.name == *ident) - .map(|(idx, col)| (idx, col.ty, catalog_table.column_is_rowid_alias(col))); + .map(|(idx, col)| { + ( + idx, + col.ty, + table_reference.table.column_is_rowid_alias(col), + ) + }); let mut idx; let mut col_type; let mut is_rowid_alias; @@ -1616,10 +1625,11 @@ pub fn resolve_ident_table( }) { idx = res.0; col_type = res.1.ty; - is_rowid_alias = catalog_table.column_is_rowid_alias(res.1); + is_rowid_alias = table_reference.table.column_is_rowid_alias(res.1); } } - let cursor_id = program.resolve_cursor_id(identifier, cursor_hint); + let cursor_id = + program.resolve_cursor_id(&table_reference.table_identifier, cursor_hint); found.push((idx, col_type, cursor_id, is_rowid_alias)); } } @@ -1685,7 +1695,7 @@ pub fn translate_table_columns( pub fn translate_aggregation( program: &mut ProgramBuilder, - referenced_tables: &[(Rc, String)], + referenced_tables: &[BTreeTableReference], agg: &Aggregate, target_register: usize, cursor_hint: Option, diff --git a/core/translate/optimizer.rs b/core/translate/optimizer.rs index 23b40aa6b..1fc4aba68 100644 --- a/core/translate/optimizer.rs +++ b/core/translate/optimizer.rs @@ -9,8 +9,8 @@ use crate::{ }; use super::plan::{ - get_table_ref_bitmask_for_ast_expr, get_table_ref_bitmask_for_operator, Direction, Operator, - Plan, ProjectionColumn, Search, + get_table_ref_bitmask_for_ast_expr, get_table_ref_bitmask_for_operator, BTreeTableReference, + Direction, Operator, Plan, ProjectionColumn, Search, }; /** @@ -57,30 +57,17 @@ fn _operator_is_already_ordered_by( ) -> Result { match operator { Operator::Scan { - table, - table_identifier, - .. - } => { - let tuple = (table.clone(), table_identifier.clone()); - Ok(key.is_primary_key_of(&tuple)) - } + table_reference, .. + } => Ok(key.is_primary_key_of(&table_reference)), Operator::Search { - table, - table_identifier, + table_reference, search, .. } => match search { - Search::PrimaryKeyEq { .. } => { - let tuple = (table.clone(), table_identifier.clone()); - Ok(key.is_primary_key_of(&tuple)) - } - Search::PrimaryKeySearch { .. } => { - let tuple = (table.clone(), table_identifier.clone()); - Ok(key.is_primary_key_of(&tuple)) - } + Search::PrimaryKeyEq { .. } => Ok(key.is_primary_key_of(&table_reference)), + Search::PrimaryKeySearch { .. } => Ok(key.is_primary_key_of(&table_reference)), Search::IndexSearch { index, .. } => { - let tuple = (table.clone(), table_identifier.clone()); - let index_idx = key.check_index_scan(&tuple, available_indexes)?; + let index_idx = key.check_index_scan(&table_reference, available_indexes)?; let index_is_the_same = index_idx .map(|i| Rc::ptr_eq(&available_indexes[i], index)) .unwrap_or(false); @@ -102,7 +89,7 @@ fn _operator_is_already_ordered_by( fn eliminate_unnecessary_orderby( operator: &mut Operator, - referenced_tables: &Vec<(Rc, String)>, + referenced_tables: &Vec, available_indexes: &Vec>, ) -> Result<()> { match operator { @@ -134,15 +121,14 @@ fn eliminate_unnecessary_orderby( */ fn use_indexes( operator: &mut Operator, - referenced_tables: &[(Rc, String)], + referenced_tables: &[BTreeTableReference], available_indexes: &[Rc], ) -> Result<()> { match operator { Operator::Search { .. } => Ok(()), Operator::Scan { - table, + table_reference, predicates: filter, - table_identifier, id, .. } => { @@ -153,11 +139,14 @@ fn use_indexes( let fs = filter.as_mut().unwrap(); for i in 0..fs.len() { let f = fs[i].take_ownership(); - let table = referenced_tables + let table_ref = referenced_tables .iter() - .find(|(t, t_id)| Rc::ptr_eq(t, table) && t_id == table_identifier) + .find(|t| { + Rc::ptr_eq(&t.table, &table_reference.table) + && t.table_identifier == table_reference.table_identifier + }) .unwrap(); - match try_extract_index_search_expression(f, table, available_indexes)? { + match try_extract_index_search_expression(f, table_ref, available_indexes)? { Either::Left(non_index_using_expr) => { fs[i] = non_index_using_expr; } @@ -165,8 +154,7 @@ fn use_indexes( fs.remove(i); *operator = Operator::Search { id: *id, - table: table.0.clone(), - table_identifier: table.1.clone(), + table_reference: table_ref.clone(), predicates: Some(fs.clone()), search: index_search, step: 0, @@ -363,7 +351,7 @@ fn eliminate_constants(operator: &mut Operator) -> Result, String)>, + referenced_tables: &Vec, ) -> Result<()> { match operator { Operator::Filter { @@ -465,17 +453,17 @@ fn push_predicates( fn push_predicate( operator: &mut Operator, predicate: ast::Expr, - referenced_tables: &Vec<(Rc, String)>, + referenced_tables: &Vec, ) -> Result> { match operator { Operator::Scan { predicates, - table_identifier, + table_reference, .. } => { let table_index = referenced_tables .iter() - .position(|(_, t_id)| t_id == table_identifier) + .position(|t| t.table_identifier == table_reference.table_identifier) .unwrap(); let predicate_bitmask = @@ -751,7 +739,7 @@ fn find_indexes_of_all_result_columns_in_operator_that_match_expr_either_fully_o } } ProjectionColumn::Star => {} - ProjectionColumn::TableStar(_, _) => {} + ProjectionColumn::TableStar(_) => {} } } @@ -985,21 +973,21 @@ pub trait Optimizable { .check_constant()? .map_or(false, |c| c == ConstantPredicate::AlwaysFalse)) } - fn is_primary_key_of(&self, table: &(Rc, String)) -> bool; + fn is_primary_key_of(&self, table_reference: &BTreeTableReference) -> bool; fn check_index_scan( &mut self, - table: &(Rc, String), + table_reference: &BTreeTableReference, available_indexes: &[Rc], ) -> Result>; } impl Optimizable for ast::Expr { - fn is_primary_key_of(&self, table: &(Rc, String)) -> bool { + fn is_primary_key_of(&self, table_reference: &BTreeTableReference) -> bool { match self { ast::Expr::Id(ident) => { let ident = normalize_ident(&ident.0); - table - .0 + table_reference + .table .get_column(&ident) .map_or(false, |(_, c)| c.primary_key) } @@ -1007,9 +995,9 @@ impl Optimizable for ast::Expr { let tbl = normalize_ident(&tbl.0); let ident = normalize_ident(&ident.0); - tbl == table.1 - && table - .0 + tbl == table_reference.table_identifier + && table_reference + .table .get_column(&ident) .map_or(false, |(_, c)| c.primary_key) } @@ -1018,7 +1006,7 @@ impl Optimizable for ast::Expr { } fn check_index_scan( &mut self, - table: &(Rc, String), + table_reference: &BTreeTableReference, available_indexes: &[Rc], ) -> Result> { match self { @@ -1028,7 +1016,8 @@ impl Optimizable for ast::Expr { .iter() .enumerate() .filter(|(_, i)| { - i.table_name == table.1 && i.columns.iter().any(|c| c.name == ident) + i.table_name == table_reference.table_identifier + && i.columns.iter().any(|c| c.name == ident) }) .collect::>(); if indexes.is_empty() { @@ -1042,7 +1031,7 @@ impl Optimizable for ast::Expr { ast::Expr::Qualified(_, ident) => { let ident = normalize_ident(&ident.0); let index = available_indexes.iter().enumerate().find(|(_, i)| { - if i.table_name != table.0.name { + if i.table_name != table_reference.table.name { return false; } i.columns.iter().any(|c| normalize_ident(&c.name) == ident) @@ -1053,11 +1042,11 @@ impl Optimizable for ast::Expr { Ok(Some(index.unwrap().0)) } ast::Expr::Binary(lhs, op, rhs) => { - let lhs_index = lhs.check_index_scan(table, available_indexes)?; + let lhs_index = lhs.check_index_scan(table_reference, available_indexes)?; if lhs_index.is_some() { return Ok(lhs_index); } - let rhs_index = rhs.check_index_scan(table, available_indexes)?; + let rhs_index = rhs.check_index_scan(table_reference, available_indexes)?; if rhs_index.is_some() { // swap lhs and rhs let lhs_new = rhs.take_ownership(); @@ -1196,12 +1185,12 @@ pub enum Either { pub fn try_extract_index_search_expression( expr: ast::Expr, - table: &(Rc, String), + table_reference: &BTreeTableReference, available_indexes: &[Rc], ) -> Result> { match expr { ast::Expr::Binary(mut lhs, operator, mut rhs) => { - if lhs.is_primary_key_of(table) { + if lhs.is_primary_key_of(table_reference) { match operator { ast::Operator::Equals => { return Ok(Either::Right(Search::PrimaryKeyEq { cmp_expr: *rhs })); @@ -1219,7 +1208,7 @@ pub fn try_extract_index_search_expression( } } - if rhs.is_primary_key_of(table) { + if rhs.is_primary_key_of(table_reference) { match operator { ast::Operator::Equals => { return Ok(Either::Right(Search::PrimaryKeyEq { cmp_expr: *lhs })); @@ -1237,7 +1226,7 @@ pub fn try_extract_index_search_expression( } } - if let Some(index_index) = lhs.check_index_scan(table, available_indexes)? { + if let Some(index_index) = lhs.check_index_scan(table_reference, available_indexes)? { match operator { ast::Operator::Equals | ast::Operator::Greater @@ -1254,7 +1243,7 @@ pub fn try_extract_index_search_expression( } } - if let Some(index_index) = rhs.check_index_scan(table, available_indexes)? { + if let Some(index_index) = rhs.check_index_scan(table_reference, available_indexes)? { match operator { ast::Operator::Equals | ast::Operator::Greater diff --git a/core/translate/plan.rs b/core/translate/plan.rs index 80463af4d..e5e816123 100644 --- a/core/translate/plan.rs +++ b/core/translate/plan.rs @@ -16,7 +16,7 @@ use crate::{ #[derive(Debug)] pub struct Plan { pub root_operator: Operator, - pub referenced_tables: Vec<(Rc, String)>, + pub referenced_tables: Vec, pub available_indexes: Vec>, } @@ -111,8 +111,7 @@ pub enum Operator { // e.g. SELECT * FROM t1 WHERE t1.foo = 5 Scan { id: usize, - table: Rc, - table_identifier: String, + table_reference: BTreeTableReference, predicates: Option>, step: usize, }, @@ -121,8 +120,7 @@ pub enum Operator { // (i.e. a primary key or a secondary index) Search { id: usize, - table: Rc, - table_identifier: String, + table_reference: BTreeTableReference, search: Search, predicates: Option>, step: usize, @@ -133,6 +131,12 @@ pub enum Operator { Nothing, } +#[derive(Clone, Debug)] +pub struct BTreeTableReference { + pub table: Rc, + pub table_identifier: String, +} + /// An enum that represents a search operation that can be used to search for a row in a table using an index /// (i.e. a primary key or a secondary index) #[derive(Clone, Debug)] @@ -157,27 +161,27 @@ pub enum Search { pub enum ProjectionColumn { Column(ast::Expr), Star, - TableStar(Rc, String), + TableStar(BTreeTableReference), } impl ProjectionColumn { - pub fn column_count(&self, referenced_tables: &[(Rc, String)]) -> usize { + pub fn column_count(&self, referenced_tables: &[BTreeTableReference]) -> usize { match self { ProjectionColumn::Column(_) => 1, ProjectionColumn::Star => { let mut count = 0; - for (table, _) in referenced_tables { - count += table.columns.len(); + for table_reference in referenced_tables { + count += table_reference.table.columns.len(); } count } - ProjectionColumn::TableStar(table, _) => table.columns.len(), + ProjectionColumn::TableStar(table_reference) => table_reference.table.columns.len(), } } } impl Operator { - pub fn column_count(&self, referenced_tables: &[(Rc, String)]) -> usize { + pub fn column_count(&self, referenced_tables: &[BTreeTableReference]) -> usize { match self { Operator::Aggregate { group_by, @@ -194,8 +198,12 @@ impl Operator { .iter() .map(|e| e.column_count(referenced_tables)) .sum(), - Operator::Scan { table, .. } => table.columns.len(), - Operator::Search { table, .. } => table.columns.len(), + Operator::Scan { + table_reference, .. + } => table_reference.table.columns.len(), + Operator::Search { + table_reference, .. + } => table_reference.table.columns.len(), Operator::Nothing => 0, } } @@ -243,13 +251,27 @@ impl Operator { _ => "expr".to_string(), }, ProjectionColumn::Star => "*".to_string(), - ProjectionColumn::TableStar(_, tbl) => format!("{}.{}", tbl, "*"), + ProjectionColumn::TableStar(table_reference) => { + format!("{}.{}", table_reference.table_identifier, "*") + } }) .collect(), - Operator::Scan { table, .. } => table.columns.iter().map(|c| c.name.clone()).collect(), - Operator::Search { table, .. } => { - table.columns.iter().map(|c| c.name.clone()).collect() - } + Operator::Scan { + table_reference, .. + } => table_reference + .table + .columns + .iter() + .map(|c| c.name.clone()) + .collect(), + Operator::Search { + table_reference, .. + } => table_reference + .table + .columns + .iter() + .map(|c| c.name.clone()) + .collect(), Operator::Nothing => vec![], } } @@ -394,7 +416,9 @@ impl Display for Operator { .map(|expr| match expr { ProjectionColumn::Column(c) => c.to_string(), ProjectionColumn::Star => "*".to_string(), - ProjectionColumn::TableStar(_, a) => format!("{}.{}", a, "*"), + ProjectionColumn::TableStar(table_reference) => { + format!("{}.{}", table_reference.table_identifier, "*") + } }) .collect::>() .join(", "); @@ -402,16 +426,19 @@ impl Display for Operator { fmt_operator(source, f, level + 1, true) } Operator::Scan { - table, + table_reference, predicates: filter, - table_identifier, .. } => { - let table_name = if table.name == *table_identifier { - table.name.clone() - } else { - format!("{} AS {}", &table.name, &table_identifier) - }; + let table_name = + if table_reference.table.name == table_reference.table_identifier { + table_reference.table_identifier.clone() + } else { + format!( + "{} AS {}", + &table_reference.table.name, &table_reference.table_identifier + ) + }; let filter_string = filter.as_ref().map(|f| { let filters_string = f .iter() @@ -427,7 +454,7 @@ impl Display for Operator { Ok(()) } Operator::Search { - table_identifier, + table_reference, search, .. } => { @@ -436,14 +463,14 @@ impl Display for Operator { writeln!( f, "{}SEARCH {} USING INTEGER PRIMARY KEY (rowid=?)", - indent, table_identifier + indent, table_reference.table_identifier )?; } Search::IndexSearch { index, .. } => { writeln!( f, "{}SEARCH {} USING INDEX {}", - indent, table_identifier, index.name + indent, table_reference.table_identifier, index.name )?; } } @@ -466,7 +493,7 @@ impl Display for Operator { then the return value will be (in bits): 110 */ pub fn get_table_ref_bitmask_for_operator<'a>( - tables: &'a Vec<(Rc, String)>, + tables: &'a Vec, operator: &'a Operator, ) -> Result { let mut table_refs_mask = 0; @@ -495,18 +522,22 @@ pub fn get_table_ref_bitmask_for_operator<'a>( Operator::Projection { source, .. } => { table_refs_mask |= get_table_ref_bitmask_for_operator(tables, source)?; } - Operator::Scan { table, .. } => { + Operator::Scan { + table_reference, .. + } => { table_refs_mask |= 1 << tables .iter() - .position(|(t, _)| Rc::ptr_eq(t, table)) + .position(|t| Rc::ptr_eq(&t.table, &table_reference.table)) .unwrap(); } - Operator::Search { table, .. } => { + Operator::Search { + table_reference, .. + } => { table_refs_mask |= 1 << tables .iter() - .position(|(t, _)| Rc::ptr_eq(t, table)) + .position(|t| Rc::ptr_eq(&t.table, &table_reference.table)) .unwrap(); } Operator::Nothing => {} @@ -523,7 +554,7 @@ pub fn get_table_ref_bitmask_for_operator<'a>( then the return value will be (in bits): 011 */ pub fn get_table_ref_bitmask_for_ast_expr<'a>( - tables: &'a Vec<(Rc, String)>, + tables: &'a Vec, predicate: &'a ast::Expr, ) -> Result { let mut table_refs_mask = 0; @@ -537,7 +568,7 @@ pub fn get_table_ref_bitmask_for_ast_expr<'a>( let matching_tables = tables .iter() .enumerate() - .filter(|(_, (table, _))| table.get_column(&ident).is_some()); + .filter(|(_, table_reference)| table_reference.table.get_column(&ident).is_some()); let mut matches = 0; let mut matching_tbl = None; @@ -561,17 +592,17 @@ pub fn get_table_ref_bitmask_for_ast_expr<'a>( let matching_table = tables .iter() .enumerate() - .find(|(_, (_, t_id))| *t_id == tbl); + .find(|(_, t)| t.table_identifier == tbl); if matching_table.is_none() { crate::bail_parse_error!("introspect: table not found: {}", &tbl) } - let matching_table = matching_table.unwrap(); - if matching_table.1 .0.get_column(&ident).is_none() { + let (table_index, table_reference) = matching_table.unwrap(); + if table_reference.table.get_column(&ident).is_none() { crate::bail_parse_error!("column with qualified name {}.{} not found", &tbl, &ident) } - table_refs_mask |= 1 << matching_table.0; + table_refs_mask |= 1 << table_index; } ast::Expr::Literal(_) => {} ast::Expr::Like { lhs, rhs, .. } => { diff --git a/core/translate/planner.rs b/core/translate/planner.rs index deca4497c..e615d74db 100644 --- a/core/translate/planner.rs +++ b/core/translate/planner.rs @@ -1,4 +1,4 @@ -use super::plan::{Aggregate, Direction, Operator, Plan, ProjectionColumn}; +use super::plan::{Aggregate, BTreeTableReference, Direction, Operator, Plan, ProjectionColumn}; use crate::{ function::Func, schema::{BTreeTable, Schema}, @@ -113,16 +113,14 @@ pub fn prepare_select_plan<'a>(schema: &Schema, select: ast::Select) -> Result

{ projection_expressions.push(ProjectionColumn::Column(expr.clone())); @@ -299,7 +297,7 @@ fn parse_from( schema: &Schema, from: Option, operator_id_counter: &mut OperatorIdCounter, -) -> Result<(Operator, Vec<(Rc, String)>)> { +) -> Result<(Operator, Vec)> { if from.as_ref().and_then(|f| f.select.as_ref()).is_none() { return Ok((Operator::Nothing, vec![])); } @@ -318,15 +316,17 @@ fn parse_from( }) .map(|a| a.0); - (table, alias.unwrap_or(qualified_name.name.0)) + BTreeTableReference { + table: table.clone(), + table_identifier: alias.unwrap_or(qualified_name.name.0), + } } _ => todo!(), }; let mut operator = Operator::Scan { - table: first_table.0.clone(), + table_reference: first_table.clone(), predicates: None, - table_identifier: first_table.1.clone(), id: operator_id_counter.get_next_id(), step: 0, }; @@ -353,7 +353,7 @@ fn parse_join( schema: &Schema, join: ast::JoinedSelectTable, operator_id_counter: &mut OperatorIdCounter, - tables: &mut Vec<(Rc, String)>, + tables: &mut Vec, ) -> Result<(Operator, bool, Option>)> { let ast::JoinedSelectTable { operator, @@ -372,8 +372,10 @@ fn parse_join( ast::As::Elided(id) => id, }) .map(|a| a.0); - - (table, alias.unwrap_or(qualified_name.name.0)) + BTreeTableReference { + table: table.clone(), + table_identifier: alias.unwrap_or(qualified_name.name.0), + } } _ => todo!(), }; @@ -402,9 +404,8 @@ fn parse_join( Ok(( Operator::Scan { - table: table.0.clone(), + table_reference: table.clone(), predicates: None, - table_identifier: table.1.clone(), id: operator_id_counter.get_next_id(), step: 0, },