use squonk::ast::generated::visit::{VisitMut, walk_expr_mut};
use squonk::ast::render::{RenderConfig, RenderCtx, RenderExt as _};
use squonk::ast::{Expr, Ident, SetExpr, Statement, TableFactor};
use squonk::parse;
struct Qualify {
alias: Ident,
}
impl VisitMut for Qualify {
fn visit_expr_mut(&mut self, node: &mut Expr) {
if let Expr::Column { name, .. } = node {
if name.0.len() == 1 {
name.0.insert(0, self.alias.clone());
}
}
walk_expr_mut(self, node);
}
}
fn table_alias(statement: &Statement) -> Ident {
let Statement::Query { query, .. } = statement else {
panic!("expected a query statement");
};
let SetExpr::Select { select, .. } = &query.body else {
panic!("expected a SELECT body");
};
let TableFactor::Table {
alias: Some(alias), ..
} = &select.from[0].relation
else {
panic!("expected an aliased table");
};
alias.name.clone()
}
fn main() {
let parsed = parse("SELECT id, total FROM orders AS o").expect("parses");
let mut statements = parsed.statements().to_vec();
let mut qualify = Qualify {
alias: table_alias(&statements[0]),
};
for statement in &mut statements {
qualify.visit_statement_mut(statement);
}
let config = RenderConfig::default();
let ctx = RenderCtx::new(parsed.resolver(), parsed.source(), &config);
let rewritten = statements[0].displayed(&ctx).to_string();
println!("before: {parsed}");
println!("after: {rewritten}");
assert_eq!(rewritten, "SELECT o.id, o.total FROM orders AS o");
}