use sqlparser::ast::{Ident, TableAlias};
use super::super::logical_plan::Columns;
use crate::reference::TableReference;
#[derive(Clone)]
pub(super) struct CteDecl {
pub(super) name: Ident,
pub(super) columns: Vec<Ident>,
}
#[derive(Default)]
pub(super) struct Scope {
pub(super) relations: Vec<Relation>,
pub(super) query_outputs: Vec<OutputCol>,
pub(super) merge_columns: Vec<Ident>,
}
#[derive(Clone)]
pub(super) struct OutputCol {
pub(super) name: Option<Ident>,
pub(super) identity: bool,
}
#[derive(Clone)]
pub(super) enum Relation {
Table {
alias: Option<Ident>,
table: TableReference,
columns: Columns,
},
Derived {
alias: Option<Ident>,
columns: Vec<Ident>,
},
TableFunction { alias: Option<Ident> },
}
impl Scope {
pub(super) fn single(relation: Relation) -> Scope {
Scope {
relations: vec![relation],
..Scope::default()
}
}
pub(super) fn from_relations(relations: &[Relation]) -> Scope {
Scope {
relations: relations.to_vec(),
..Scope::default()
}
}
pub(super) fn absorb(&mut self, other: Scope) {
self.relations.extend(other.relations);
self.merge_columns.extend(other.merge_columns);
}
pub(super) fn add_merge_columns(&mut self, columns: impl IntoIterator<Item = Ident>) {
self.merge_columns.extend(columns);
}
pub(super) fn with_query_outputs(self, query_outputs: Vec<OutputCol>) -> Scope {
Scope {
query_outputs,
..self
}
}
pub(super) fn exposed_columns(&self, alias: Option<&TableAlias>) -> Vec<Ident> {
let alias_columns: Vec<&Ident> = alias
.map(|a| a.columns.iter().map(|c| &c.name).collect())
.unwrap_or_default();
let len = alias_columns.len().max(self.query_outputs.len());
(0..len)
.filter_map(|i| {
alias_columns
.get(i)
.map(|n| (*n).clone())
.or_else(|| self.query_outputs.get(i).and_then(|o| o.name.clone()))
})
.collect()
}
}
impl Relation {
pub(super) fn exposed_name(&self) -> Option<&Ident> {
match self {
Relation::Table { alias, table, .. } => alias.as_ref().or(Some(&table.name)),
Relation::Derived { alias, .. } | Relation::TableFunction { alias } => alias.as_ref(),
}
}
pub(super) fn known_columns(&self) -> &[Ident] {
match self {
Relation::Table {
columns: Columns::Cataloged(cols),
..
} => cols,
Relation::Derived { columns, .. } => columns,
Relation::Table {
columns: Columns::Unknown,
..
}
| Relation::TableFunction { .. } => &[],
}
}
}