1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
mod filter;
mod group_by;
mod having;
mod join;
mod limit;
mod offset;
mod offset_limit;
mod order_by;
mod project;
mod root;
mod values;

pub use {
    filter::FilterNode,
    group_by::GroupByNode,
    having::HavingNode,
    join::{HashJoinNode, JoinConstraintNode, JoinNode},
    limit::LimitNode,
    offset::OffsetNode,
    offset_limit::OffsetLimitNode,
    order_by::OrderByNode,
    project::ProjectNode,
    root::{select, SelectNode},
    values::{values, ValuesNode},
};

use {
    super::Build,
    crate::{
        ast::{Query, Select, SetExpr, Statement},
        result::Result,
    },
};

pub trait Prebuild<T> {
    fn prebuild(self) -> Result<T>;
}

impl<T: Prebuild<Select>> Prebuild<Query> for T {
    fn prebuild(self) -> Result<Query> {
        let select = self.prebuild()?;
        let body = SetExpr::Select(Box::new(select));
        let query = Query {
            body,
            order_by: Vec::new(),
            limit: None,
            offset: None,
        };

        Ok(query)
    }
}

impl<T: Prebuild<Query>> Build for T {
    fn build(self) -> Result<Statement> {
        let query = self.prebuild()?;

        Ok(Statement::Query(query))
    }
}