diff --git a/core/translate/mod.rs b/core/translate/mod.rs index f0abe0b62..9eb2859ae 100644 --- a/core/translate/mod.rs +++ b/core/translate/mod.rs @@ -9,24 +9,11 @@ use crate::pager::Pager; use crate::schema::Schema; use crate::sqlite3_ondisk::{DatabaseHeader, MIN_PAGE_CACHE_SIZE}; use crate::util::normalize_ident; -use crate::vdbe::{builder::ProgramBuilder, BranchOffset, Insn, Program}; +use crate::vdbe::{builder::ProgramBuilder, Insn, Program}; use crate::Result; -use select::{build_select, translate_select}; +use select::{prepare_select, translate_select}; use sqlite3_parser::ast; -struct LimitInfo { - limit_reg: usize, - num: i64, - goto_label: BranchOffset, -} - -#[derive(Debug)] -struct SortInfo { - sorter_cursor: usize, - sorter_reg: usize, - count: usize, -} - /// Translate SQL statement into bytecode program. pub fn translate( schema: &Schema, @@ -36,7 +23,7 @@ pub fn translate( ) -> Result { match stmt { ast::Stmt::Select(select) => { - let select = build_select(schema, &select)?; + let select = prepare_select(schema, &select)?; translate_select(select) } ast::Stmt::Pragma(name, body) => translate_pragma(&name, body, database_header, pager), diff --git a/core/translate/select.rs b/core/translate/select.rs index 54570c74d..3cd9ebb2d 100644 --- a/core/translate/select.rs +++ b/core/translate/select.rs @@ -1,23 +1,49 @@ -use std::rc::Rc; - -use crate::Result; -use sqlite3_parser::ast::{self, JoinOperator, JoinType}; - -use crate::function::AggFunc; -use crate::schema::{Column, PseudoTable, Schema}; -use crate::translate::expr::analyze_columns; -use crate::translate::expr::maybe_apply_affinity; -use crate::translate::expr::translate_expr; -use crate::translate::normalize_ident; +use crate::function::{AggFunc, Func}; +use crate::schema::{Column, PseudoTable, Schema, Table}; +use crate::translate::expr::{analyze_columns, maybe_apply_affinity, translate_expr}; use crate::translate::where_clause::{ process_where, translate_processed_where, translate_where, ProcessedWhereClause, }; -use crate::translate::{Insn, LimitInfo}; +use crate::translate::{normalize_ident, Insn}; use crate::types::{OwnedRecord, OwnedValue}; -use crate::vdbe::{builder::ProgramBuilder, Program}; -use crate::{function::Func, schema::Table, vdbe::BranchOffset}; +use crate::vdbe::{builder::ProgramBuilder, BranchOffset, Program}; +use crate::Result; -use super::SortInfo; +use sqlite3_parser::ast::{self, JoinOperator, JoinType}; + +use std::rc::Rc; + +/// A representation of a `SELECT` statement that has all the information +/// needed for code generation. +pub struct Select<'a> { + /// The columns that are being selected. + pub columns: &'a Vec, + /// Information about each column. + pub column_info: Vec>, + /// The tables we are retrieving data from, including tables mentioned + /// in `FROM` and `JOIN` clauses. + pub src_tables: Vec>, + /// The `LIMIT` clause. + pub limit: &'a Option, + /// The `ORDER BY` clause. + pub order_by: &'a Option>, + /// Whether the query contains an aggregation function. + pub exist_aggregation: bool, + /// The `WHERE` clause. + pub where_clause: &'a Option, + /// Ordered list of opened read table loops. + /// + /// The list is used to generate inner loops like this: + /// + /// cursor 0 = open table 0 + /// for each row in cursor 0 + /// cursor 1 = open table 1 + /// for each row in cursor 1 + /// ... + /// end cursor 1 + /// end cursor 0 + pub loops: Vec, +} #[derive(Debug)] pub struct SrcTable<'a> { @@ -91,27 +117,20 @@ pub struct LoopInfo { pub open_cursor: usize, } -pub struct Select<'a> { - pub columns: &'a Vec, - pub column_info: Vec>, - pub src_tables: Vec>, // Tables we use to get data from. This includes "from" and "joins" - pub limit: &'a Option, - pub order_by: &'a Option>, - pub exist_aggregation: bool, - pub where_clause: &'a Option, - /// Ordered list of opened read table loops - /// Used for generating a loop that looks like this: - /// cursor 0 = open table 0 - /// for each row in cursor 0 - /// cursor 1 = open table 1 - /// for each row in cursor 1 - /// ... - /// end cursor 1 - /// end cursor 0 - pub loops: Vec, +struct LimitInfo { + limit_reg: usize, + num: i64, + goto_label: BranchOffset, } -pub fn build_select<'a>(schema: &Schema, select: &'a ast::Select) -> Result> { +#[derive(Debug)] +struct SortInfo { + sorter_cursor: usize, + sorter_reg: usize, + count: usize, +} + +pub fn prepare_select<'a>(schema: &Schema, select: &'a ast::Select) -> Result> { match &select.body.select { ast::OneSelect::Select { columns,