core: Move build_select() to select.rs

This commit is contained in:
Pekka Enberg
2024-07-24 21:13:08 +03:00
parent 4844f173b0
commit be91b9aaca
3 changed files with 109 additions and 104 deletions

View File

@@ -9,109 +9,6 @@ use crate::{
vdbe::{builder::ProgramBuilder, BranchOffset, Insn},
};
pub fn build_select<'a>(schema: &Schema, select: &'a ast::Select) -> Result<Select<'a>> {
match &select.body.select {
ast::OneSelect::Select {
columns,
from: Some(from),
where_clause,
..
} => {
let (table_name, maybe_alias) = match &from.select {
Some(select_table) => match select_table.as_ref() {
ast::SelectTable::Table(name, alias, ..) => (
&name.name,
alias.as_ref().map(|als| match als {
ast::As::As(alias) => alias, // users as u
ast::As::Elided(alias) => alias, // users u
}),
),
_ => todo!(),
},
None => todo!(),
};
let table_name = &table_name.0;
let maybe_alias = maybe_alias.map(|als| &als.0);
let table = match schema.get_table(table_name) {
Some(table) => table,
None => anyhow::bail!("Parse error: no such table: {}", table_name),
};
let identifier = normalize_ident(maybe_alias.unwrap_or(table_name));
let mut joins = Vec::new();
joins.push(SrcTable {
table: Table::BTree(table.clone()),
identifier,
join_info: None,
});
if let Some(selected_joins) = &from.joins {
for join in selected_joins {
let (table_name, maybe_alias) = match &join.table {
ast::SelectTable::Table(name, alias, ..) => (
&name.name,
alias.as_ref().map(|als| match als {
ast::As::As(alias) => alias, // users as u
ast::As::Elided(alias) => alias, // users u
}),
),
_ => todo!(),
};
let table_name = &table_name.0;
let maybe_alias = maybe_alias.as_ref().map(|als| &als.0);
let table = match schema.get_table(table_name) {
Some(table) => table,
None => anyhow::bail!("Parse error: no such table: {}", table_name),
};
let identifier = normalize_ident(maybe_alias.unwrap_or(table_name));
joins.push(SrcTable {
table: Table::BTree(table),
identifier,
join_info: Some(join),
});
}
}
let _table = Table::BTree(table);
let column_info = analyze_columns(columns, &joins);
let exist_aggregation = column_info
.iter()
.any(|info| info.is_aggregation_function());
Ok(Select {
columns,
column_info,
src_tables: joins,
limit: &select.limit,
order_by: &select.order_by,
exist_aggregation,
where_clause,
loops: Vec::new(),
})
}
ast::OneSelect::Select {
columns,
from: None,
where_clause,
..
} => {
let column_info = analyze_columns(columns, &Vec::new());
let exist_aggregation = column_info
.iter()
.any(|info| info.is_aggregation_function());
Ok(Select {
columns,
column_info,
src_tables: Vec::new(),
limit: &select.limit,
order_by: &select.order_by,
where_clause,
exist_aggregation,
loops: Vec::new(),
})
}
_ => todo!(),
}
}
pub fn translate_expr(
program: &mut ProgramBuilder,
select: &Select,

View File

@@ -15,7 +15,8 @@ use crate::types::{OwnedRecord, OwnedValue};
use crate::util::normalize_ident;
use crate::vdbe::{builder::ProgramBuilder, BranchOffset, Insn, Program};
use anyhow::Result;
use expr::{build_select, maybe_apply_affinity, translate_expr};
use expr::{maybe_apply_affinity, translate_expr};
use select::build_select;
use select::LeftJoinBookkeeping;
use sqlite3_parser::ast::{self, Literal};
use where_clause::{process_where, ProcessedWhereClause};

View File

@@ -1,5 +1,9 @@
use anyhow::Result;
use sqlite3_parser::ast::{self, JoinOperator, JoinType};
use crate::schema::Schema;
use crate::translate::expr::analyze_columns;
use crate::translate::normalize_ident;
use crate::{function::Func, schema::Table, vdbe::BranchOffset};
#[derive(Debug)]
@@ -93,3 +97,106 @@ pub struct Select<'a> {
/// end cursor 0
pub loops: Vec<LoopInfo>,
}
pub fn build_select<'a>(schema: &Schema, select: &'a ast::Select) -> Result<Select<'a>> {
match &select.body.select {
ast::OneSelect::Select {
columns,
from: Some(from),
where_clause,
..
} => {
let (table_name, maybe_alias) = match &from.select {
Some(select_table) => match select_table.as_ref() {
ast::SelectTable::Table(name, alias, ..) => (
&name.name,
alias.as_ref().map(|als| match als {
ast::As::As(alias) => alias, // users as u
ast::As::Elided(alias) => alias, // users u
}),
),
_ => todo!(),
},
None => todo!(),
};
let table_name = &table_name.0;
let maybe_alias = maybe_alias.map(|als| &als.0);
let table = match schema.get_table(table_name) {
Some(table) => table,
None => anyhow::bail!("Parse error: no such table: {}", table_name),
};
let identifier = normalize_ident(maybe_alias.unwrap_or(table_name));
let mut joins = Vec::new();
joins.push(SrcTable {
table: Table::BTree(table.clone()),
identifier,
join_info: None,
});
if let Some(selected_joins) = &from.joins {
for join in selected_joins {
let (table_name, maybe_alias) = match &join.table {
ast::SelectTable::Table(name, alias, ..) => (
&name.name,
alias.as_ref().map(|als| match als {
ast::As::As(alias) => alias, // users as u
ast::As::Elided(alias) => alias, // users u
}),
),
_ => todo!(),
};
let table_name = &table_name.0;
let maybe_alias = maybe_alias.as_ref().map(|als| &als.0);
let table = match schema.get_table(table_name) {
Some(table) => table,
None => anyhow::bail!("Parse error: no such table: {}", table_name),
};
let identifier = normalize_ident(maybe_alias.unwrap_or(table_name));
joins.push(SrcTable {
table: Table::BTree(table),
identifier,
join_info: Some(join),
});
}
}
let _table = Table::BTree(table);
let column_info = analyze_columns(columns, &joins);
let exist_aggregation = column_info
.iter()
.any(|info| info.is_aggregation_function());
Ok(Select {
columns,
column_info,
src_tables: joins,
limit: &select.limit,
order_by: &select.order_by,
exist_aggregation,
where_clause,
loops: Vec::new(),
})
}
ast::OneSelect::Select {
columns,
from: None,
where_clause,
..
} => {
let column_info = analyze_columns(columns, &Vec::new());
let exist_aggregation = column_info
.iter()
.any(|info| info.is_aggregation_function());
Ok(Select {
columns,
column_info,
src_tables: Vec::new(),
limit: &select.limit,
order_by: &select.order_by,
where_clause,
exist_aggregation,
loops: Vec::new(),
})
}
_ => todo!(),
}
}