Skip to main content

gluesql_core/query_builder/select/
values.rs

1use crate::{
2    ast::{Query, SetExpr, Values},
3    plan::{QueryPlan, ValuesPlan},
4    query_builder::{
5        ExprList, ExprNode, LimitNode, OffsetNode, OrderByExprList, QueryNode, SourceNode,
6        ValuesOrderByNode,
7        select::{BuildQuery, BuildQueryPlan},
8    },
9    result::Result,
10};
11
12#[derive(Clone, Debug)]
13pub struct ValuesNode<'a> {
14    pub values: Vec<ExprList<'a>>,
15}
16
17impl<'a> ValuesNode<'a> {
18    pub fn order_by<T: Into<OrderByExprList<'a>>>(
19        self,
20        order_by_exprs: T,
21    ) -> ValuesOrderByNode<'a> {
22        ValuesOrderByNode::new(self, order_by_exprs)
23    }
24
25    pub fn offset<T: Into<ExprNode<'a>>>(self, expr: T) -> OffsetNode<'a> {
26        OffsetNode::new(self, expr)
27    }
28
29    pub fn limit<T: Into<ExprNode<'a>>>(self, expr: T) -> LimitNode<'a> {
30        LimitNode::new(self, expr)
31    }
32
33    pub fn alias_as(self, table_alias: &'a str) -> SourceNode<'a> {
34        QueryNode::ValuesNode(self).alias_as(table_alias)
35    }
36}
37
38impl ValuesNode<'_> {
39    pub(super) fn build_values_plan(self) -> Result<ValuesPlan> {
40        let values = self
41            .values
42            .into_iter()
43            .map(ExprList::build_exprs_plan)
44            .collect::<Result<Vec<_>>>()?;
45
46        Ok(ValuesPlan(values))
47    }
48}
49
50impl BuildQueryPlan for ValuesNode<'_> {
51    fn build_query_plan(self) -> Result<QueryPlan> {
52        self.build_values_plan().map(QueryPlan::Values)
53    }
54}
55
56impl BuildQuery for ValuesNode<'_> {
57    fn build_query(self) -> Result<Query> {
58        let values = self
59            .values
60            .into_iter()
61            .map(ExprList::build_exprs)
62            .collect::<Result<Vec<_>>>()?;
63
64        let body = SetExpr::Values(Values(values));
65
66        Ok(Query {
67            body,
68            order_by: Vec::new(),
69            limit: None,
70            offset: None,
71        })
72    }
73}
74
75pub fn values<'a, T: Into<ExprList<'a>>>(values: Vec<T>) -> ValuesNode<'a> {
76    let values: Vec<ExprList> = values.into_iter().map(Into::into).collect();
77
78    ValuesNode { values }
79}
80
81#[cfg(test)]
82mod tests {
83    use crate::query_builder::{num, test_query_builder};
84
85    #[test]
86    fn values() {
87        use crate::query_builder::values;
88
89        let actual = values(vec![vec![num(7)]]);
90        let expected = "VALUES(7)";
91        test_query_builder(actual, expected);
92
93        let actual = values(vec!["1, 'a'", "2, 'b'"]);
94        let expected = "VALUES(1, 'a'), (2, 'b')";
95        test_query_builder(actual, expected);
96
97        let actual = values(vec!["1, 'a'", "2, 'b'"]).order_by(vec!["column1 desc"]);
98        let expected = "VALUES(1, 'a'), (2, 'b') ORDER BY column1 desc";
99        test_query_builder(actual, expected);
100
101        let actual = values(vec!["1, 'a'", "2, 'b'"]).offset(1);
102        let expected = "VALUES(1, 'a'), (2, 'b') offset 1";
103        test_query_builder(actual, expected);
104
105        let actual = values(vec!["1, 'a'", "2, 'b'"])
106            .order_by("column1")
107            .offset(1);
108        let expected = "VALUES(1, 'a'), (2, 'b') ORDER BY column1 OFFSET 1";
109        test_query_builder(actual, expected);
110
111        let actual = values(vec!["1, 'a'", "2, 'b'"]).limit(1);
112        let expected = "VALUES(1, 'a'), (2, 'b') limit 1";
113        test_query_builder(actual, expected);
114
115        let actual = values(vec!["1, 'a'", "2, 'b'"])
116            .order_by("column1")
117            .limit(1);
118        let expected = "VALUES(1, 'a'), (2, 'b') ORDER BY column1 LIMIT 1";
119        test_query_builder(actual, expected);
120
121        let actual = values(vec!["1, 'a'", "2, 'b'"]).offset(1).limit(1);
122        let expected = "VALUES(1, 'a'), (2, 'b') offset 1 limit 1";
123        test_query_builder(actual, expected);
124
125        let actual = values(vec!["1, 'a'", "2, 'b'"]).alias_as("Sub").select();
126        let expected = "SELECT * FROM (VALUES(1, 'a'), (2, 'b')) AS Sub";
127        test_query_builder(actual, expected);
128
129        let actual = values(vec!["1, 'a'", "2, 'b'"])
130            .order_by("column1")
131            .alias_as("Sub")
132            .select();
133        let expected = "SELECT * FROM (VALUES(1, 'a'), (2, 'b') ORDER BY column1) AS Sub";
134        test_query_builder(actual, expected);
135    }
136}