Skip to main content

gluesql_core/query_builder/
assignment.rs

1use {
2    super::ExprNode,
3    crate::{
4        parse_sql::parse_assignment,
5        plan::AssignmentPlan,
6        result::{Error, Result},
7        translate::{NO_PARAMS, translate_assignment},
8    },
9};
10
11#[derive(Clone, Debug)]
12pub enum AssignmentNode<'a> {
13    Expr(String, ExprNode<'a>),
14    Text(String),
15}
16
17impl From<&str> for AssignmentNode<'_> {
18    fn from(expr: &str) -> Self {
19        Self::Text(expr.to_owned())
20    }
21}
22
23impl<'a> TryFrom<AssignmentNode<'a>> for AssignmentPlan {
24    type Error = Error;
25
26    fn try_from(node: AssignmentNode<'a>) -> Result<Self> {
27        match node {
28            AssignmentNode::Text(expr) => {
29                let assignment = parse_assignment(expr)
30                    .and_then(|assignment| translate_assignment(&assignment, NO_PARAMS))?;
31                Ok(assignment.into())
32            }
33            AssignmentNode::Expr(col, expr_node) => {
34                let value = expr_node.build_expr_plan()?;
35                let id = col;
36                Ok(AssignmentPlan { id, value })
37            }
38        }
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use {
45        crate::{
46            parse_sql::parse_assignment,
47            plan::AssignmentPlan,
48            query_builder::AssignmentNode,
49            translate::{NO_PARAMS, translate_assignment},
50        },
51        pretty_assertions::assert_eq,
52    };
53
54    fn test(actual: AssignmentNode, expected: &str) {
55        let parsed = &parse_assignment(expected).expect(expected);
56        let expected = translate_assignment(parsed, NO_PARAMS).map(AssignmentPlan::from);
57        assert_eq!(actual.try_into(), expected);
58    }
59
60    #[test]
61    fn assignment() {
62        let actual = "foo = 1".into();
63        let expected = "foo = 1";
64        test(actual, expected);
65
66        let actual = r#"foo = "choco""#.into();
67        let expected = r#"foo = "choco""#;
68        test(actual, expected);
69
70        let actual = r"Bar = mild".into();
71        let expected = r"Bar = mild";
72        test(actual, expected);
73
74        let actual = AssignmentNode::Expr("foo".into(), "1".into());
75        let expected = "foo = 1";
76        test(actual, expected);
77
78        let actual = AssignmentNode::Expr("foo".into(), r#""cocoa""#.into());
79        let expected = r#"foo = "cocoa""#;
80        test(actual, expected);
81
82        let actual = AssignmentNode::Expr("Bar".into(), "mild".into());
83        let expected = "Bar = mild";
84        test(actual, expected);
85    }
86}