use std::collections::HashMap;
use crate::sql_engine::models::{Location, QualifiedName, ResolvedColumn, TableReference};
#[derive(Debug, Clone)]
pub enum CursorContext {
SelectList,
TableRef,
Predicate,
AfterTableRef,
TableTarget,
AfterUpdateTable,
AfterDeleteTable,
SetClause { target_table: QualifiedName },
OrderGroupBy,
ExecCall,
DdlObject,
SchemaDot {
schema_name: String,
in_table_ref: bool,
},
PackageDot {
schema: Option<String>,
package: String,
},
ColumnDot { table_ref: String },
General,
}
#[derive(Debug, Clone)]
pub struct ResolvedTableRef {
pub reference: TableReference,
pub resolved_schema: Option<String>,
pub exists: Option<bool>,
}
#[derive(Debug, Clone)]
pub struct ResolutionError {
pub location: Location,
pub message: String,
pub kind: ResolutionErrorKind,
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[allow(dead_code)]
pub enum ResolutionErrorKind {
UnknownSchema,
UnknownTable,
UnknownColumn,
AmbiguousColumn,
}
#[derive(Debug, Clone)]
pub struct SemanticContext {
pub table_refs: Vec<ResolvedTableRef>,
pub aliases: HashMap<String, QualifiedName>,
pub cursor_context: CursorContext,
pub available_columns: Vec<ResolvedColumn>,
pub resolution_errors: Vec<ResolutionError>,
pub prefix: String,
pub cte_names: Vec<String>,
pub is_partial: bool,
}
impl SemanticContext {
pub fn empty() -> Self {
Self {
table_refs: Vec::new(),
aliases: HashMap::new(),
cursor_context: CursorContext::General,
available_columns: Vec::new(),
resolution_errors: Vec::new(),
cte_names: Vec::new(),
prefix: String::new(),
is_partial: true,
}
}
#[allow(dead_code)]
pub fn resolve_alias(
&self,
name: &str,
normalize: &dyn Fn(&str) -> String,
) -> Option<&QualifiedName> {
let normalized = normalize(name);
self.aliases.get(&normalized)
}
pub fn columns_for(
&self,
table_ref: &str,
normalize: &dyn Fn(&str) -> String,
) -> Vec<&ResolvedColumn> {
let normalized = normalize(table_ref);
let target = self
.aliases
.get(&normalized)
.map(|qn| normalize(&qn.name))
.unwrap_or_else(|| normalized.clone());
self.available_columns
.iter()
.filter(|c| normalize(&c.table_name) == target)
.collect()
}
}