select.rs: use new data structures when parsing select

This commit is contained in:
Jussi Saurio
2025-02-01 22:33:26 +02:00
parent 16a97d3b98
commit 2ddac4bf21

View File

@@ -1,12 +1,12 @@
use super::emitter::emit_program;
use super::expr::get_name;
use super::plan::SelectQueryType;
use super::plan::{select_star, SelectQueryType};
use crate::function::{AggFunc, ExtFunc, Func};
use crate::translate::optimizer::optimize_plan;
use crate::translate::plan::{Aggregate, Direction, GroupBy, Plan, ResultSetColumn, SelectPlan};
use crate::translate::planner::{
bind_column_references, break_predicate_at_and_boundaries, parse_from, parse_limit,
parse_where, resolve_aggregates, OperatorIdCounter,
parse_where, resolve_aggregates,
};
use crate::util::normalize_ident;
use crate::SymbolTable;
@@ -43,52 +43,51 @@ pub fn prepare_select_plan(
crate::bail_parse_error!("SELECT without columns is not allowed");
}
let mut operator_id_counter = OperatorIdCounter::new();
let mut where_predicates = vec![];
// Parse the FROM clause
let (source, referenced_tables) =
parse_from(schema, from, &mut operator_id_counter, syms)?;
// Parse the FROM clause into a vec of TableReferences. Fold all the join conditions expressions into the WHERE clause.
let table_references = parse_from(schema, from, syms, &mut where_predicates)?;
let mut plan = SelectPlan {
source,
table_references,
result_columns: vec![],
where_clause: None,
where_clause: where_predicates,
group_by: None,
order_by: None,
aggregates: vec![],
limit: None,
offset: None,
referenced_tables,
available_indexes: schema.indexes.clone().into_values().flatten().collect(),
contains_constant_false_condition: false,
query_type: SelectQueryType::TopLevel,
};
// Parse the WHERE clause
plan.where_clause = parse_where(where_clause, &plan.referenced_tables)?;
// Parse the actual WHERE clause and add its conditions to the plan WHERE clause that already contains the join conditions.
parse_where(where_clause, &plan.table_references, &mut plan.where_clause)?;
let mut aggregate_expressions = Vec::new();
for (result_column_idx, column) in columns.iter_mut().enumerate() {
match column {
ResultColumn::Star => {
plan.source.select_star(&mut plan.result_columns);
select_star(&plan.table_references, &mut plan.result_columns);
}
ResultColumn::TableStar(name) => {
let name_normalized = normalize_ident(name.0.as_str());
let referenced_table = plan
.referenced_tables
.table_references
.iter()
.find(|t| t.table_identifier == name_normalized);
.enumerate()
.find(|(_, t)| t.identifier == name_normalized);
if referenced_table.is_none() {
crate::bail_parse_error!("Table {} not found", name.0);
}
let table_reference = referenced_table.unwrap();
for (idx, col) in table_reference.columns().iter().enumerate() {
let (table_index, table) = referenced_table.unwrap();
for (idx, col) in table.columns().iter().enumerate() {
plan.result_columns.push(ResultSetColumn {
expr: ast::Expr::Column {
database: None, // TODO: support different databases
table: table_reference.table_index,
table: table_index,
column: idx,
is_rowid_alias: col.is_rowid_alias,
},
@@ -98,7 +97,7 @@ pub fn prepare_select_plan(
}
}
ResultColumn::Expr(ref mut expr, maybe_alias) => {
bind_column_references(expr, &plan.referenced_tables)?;
bind_column_references(expr, &plan.table_references)?;
match expr {
ast::Expr::FunctionCall {
name,
@@ -141,7 +140,7 @@ pub fn prepare_select_plan(
name: get_name(
maybe_alias.as_ref(),
expr,
&plan.referenced_tables,
&plan.table_references,
|| format!("expr_{}", result_column_idx),
),
expr: expr.clone(),
@@ -155,7 +154,7 @@ pub fn prepare_select_plan(
name: get_name(
maybe_alias.as_ref(),
expr,
&plan.referenced_tables,
&plan.table_references,
|| format!("expr_{}", result_column_idx),
),
expr: expr.clone(),
@@ -174,7 +173,7 @@ pub fn prepare_select_plan(
name: get_name(
maybe_alias.as_ref(),
expr,
&plan.referenced_tables,
&plan.table_references,
|| format!("expr_{}", result_column_idx),
),
expr: expr.clone(),
@@ -191,7 +190,7 @@ pub fn prepare_select_plan(
name: get_name(
maybe_alias.as_ref(),
expr,
&plan.referenced_tables,
&plan.table_references,
|| format!("expr_{}", result_column_idx),
),
expr: expr.clone(),
@@ -225,7 +224,7 @@ pub fn prepare_select_plan(
name: get_name(
maybe_alias.as_ref(),
expr,
&plan.referenced_tables,
&plan.table_references,
|| format!("expr_{}", result_column_idx),
),
expr: expr.clone(),
@@ -245,7 +244,7 @@ pub fn prepare_select_plan(
name: get_name(
maybe_alias.as_ref(),
expr,
&plan.referenced_tables,
&plan.table_references,
|| format!("expr_{}", result_column_idx),
),
expr: expr.clone(),
@@ -258,7 +257,7 @@ pub fn prepare_select_plan(
}
if let Some(mut group_by) = group_by {
for expr in group_by.exprs.iter_mut() {
bind_column_references(expr, &plan.referenced_tables)?;
bind_column_references(expr, &plan.table_references)?;
}
plan.group_by = Some(GroupBy {
@@ -267,7 +266,7 @@ pub fn prepare_select_plan(
let mut predicates = vec![];
break_predicate_at_and_boundaries(having, &mut predicates);
for expr in predicates.iter_mut() {
bind_column_references(expr, &plan.referenced_tables)?;
bind_column_references(expr, &plan.table_references)?;
let contains_aggregates =
resolve_aggregates(expr, &mut aggregate_expressions);
if !contains_aggregates {
@@ -313,7 +312,7 @@ pub fn prepare_select_plan(
o.expr
};
bind_column_references(&mut expr, &plan.referenced_tables)?;
bind_column_references(&mut expr, &plan.table_references)?;
resolve_aggregates(&expr, &mut plan.aggregates);
key.push((