koron_query_parser/
support.rs1use sqlparser::ast;
2
3use crate::{error::ParseError, internal, malformed_query, query_metadata::FromClauseIdentifier};
4
5pub(crate) fn remove_outer_parens(expr: &ast::Expr) -> &ast::Expr {
7 match expr {
8 ast::Expr::Nested(inner) => remove_outer_parens(inner),
9 _ => expr,
10 }
11}
12
13pub(crate) fn extract_qualified_column(
15 from_clause_identifier: FromClauseIdentifier<'_>,
16 compound_identifier: &ast::Expr,
17 name_parts: &[ast::Ident],
18) -> Result<String, ParseError> {
19 let unknown_column = || {
20 Err(malformed_query!(format!(
21 "the {compound_identifier} column is not part of the table that's listed in the FROM clause ({from_clause_identifier}).",
22 )))
23 };
24
25 let mut name_parts = name_parts.iter();
26
27 let column = name_parts.next_back().ok_or_else(|| {
28 internal!("found empty column name (CompoundIdentifier) in query AST.".to_string())
29 })?;
30 let column = case_fold_identifier(column);
31
32 if let Some(table) = name_parts.next_back() {
33 let schema = name_parts.next_back();
34 let db = name_parts.next_back();
35 if !from_clause_identifier.matches(db, schema, table) {
36 return unknown_column();
37 }
38 }
39 if name_parts.count() > 0 {
40 return Err(internal!(format!(
41 "found too many ident in column name (i.e., {compound_identifier})."
42 )));
43 }
44
45 Ok(column)
46}
47
48pub(crate) fn case_fold_identifier(ident: &ast::Ident) -> String {
49 let ast::Ident { value, quote_style } = ident;
52 if quote_style.is_none() {
53 value.to_ascii_lowercase()
54 } else {
55 value.to_string()
56 }
57}