gluesql_core/ast_builder/
select_item.rs1use {
2 super::ExprNode,
3 crate::{
4 ast::{Expr, SelectItem, ToSqlUnquoted},
5 ast_builder::ExprWithAliasNode,
6 parse_sql::parse_select_item,
7 result::{Error, Result},
8 translate::translate_select_item,
9 },
10};
11
12#[derive(Clone, Debug)]
13pub enum SelectItemNode<'a> {
14 SelectItem(SelectItem),
15 Expr(ExprNode<'a>),
16 Text(String),
17 ExprWithAliasNode(ExprWithAliasNode<'a>),
18}
19
20impl<'a> From<SelectItem> for SelectItemNode<'a> {
21 fn from(select_item: SelectItem) -> Self {
22 Self::SelectItem(select_item)
23 }
24}
25
26impl<'a> From<ExprNode<'a>> for SelectItemNode<'a> {
27 fn from(expr_node: ExprNode<'a>) -> Self {
28 Self::Expr(expr_node)
29 }
30}
31
32impl<'a> From<&str> for SelectItemNode<'a> {
33 fn from(select_item: &str) -> Self {
34 Self::Text(select_item.to_owned())
35 }
36}
37
38impl<'a> From<ExprWithAliasNode<'a>> for SelectItemNode<'a> {
39 fn from(expr_node: ExprWithAliasNode<'a>) -> Self {
40 Self::ExprWithAliasNode(expr_node)
41 }
42}
43
44impl<'a> TryFrom<SelectItemNode<'a>> for SelectItem {
45 type Error = Error;
46
47 fn try_from(select_item_node: SelectItemNode<'a>) -> Result<Self> {
48 match select_item_node {
49 SelectItemNode::SelectItem(select_item) => Ok(select_item),
50 SelectItemNode::Text(select_item) => {
51 parse_select_item(select_item).and_then(|item| translate_select_item(&item))
52 }
53 SelectItemNode::Expr(expr_node) => {
54 let expr = Expr::try_from(expr_node)?;
55 let label = expr.to_sql_unquoted();
56
57 Ok(SelectItem::Expr { expr, label })
58 }
59 SelectItemNode::ExprWithAliasNode(alias_node) => {
60 let (expr, label) = alias_node.try_into()?;
61
62 Ok(SelectItem::Expr { expr, label })
63 }
64 }
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use {
71 crate::{
72 ast::SelectItem,
73 ast_builder::{SelectItemNode, col},
74 parse_sql::parse_select_item,
75 translate::translate_select_item,
76 },
77 pretty_assertions::assert_eq,
78 };
79
80 fn test(actual: SelectItemNode, expected: &str) {
81 let parsed = &parse_select_item(expected).expect(expected);
82 let expected = translate_select_item(parsed);
83 assert_eq!(actual.try_into(), expected);
84 }
85
86 #[test]
87 fn select_item() {
88 let actual = SelectItem::Wildcard.into();
89 let expected = "*";
90 test(actual, expected);
91
92 let actual = "Foo.*".into();
93 let expected = "Foo.*";
94 test(actual, expected);
95
96 let actual = "id as hello".into();
97 let expected = "id as hello";
98 test(actual, expected);
99
100 let actual = col("id").into();
101 let expected = "id";
102 test(actual, expected);
103 }
104}