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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/// Types for outer-scope AST nodes (query, table, func def, transform)
use serde::{Deserialize, Serialize};

use super::{Dialect, Ident, Node, Range, Ty};

#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Default)]
pub struct Query {
    pub version: Option<i64>,
    #[serde(default)]
    pub dialect: Dialect,
    pub nodes: Vec<Node>,
}

/// Function definition.
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub struct FuncDef {
    pub name: Ident,
    pub positional_params: Vec<(Node, Option<Ty>)>, // ident
    pub named_params: Vec<(Node, Option<Ty>)>,      // named expr
    pub body: Box<Node>,
    pub return_type: Option<Ty>,
}

#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub struct Table {
    pub name: String,
    pub pipeline: Box<Node>,
    pub id: Option<usize>,
}

/// Transform is a stage of a pipeline. It is created from a FuncCall during parsing.
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, strum::AsRefStr)]
pub enum Transform {
    From(TableRef),
    Select(Vec<Node>),
    Filter(Box<Node>),
    Derive(Vec<Node>),
    Aggregate {
        assigns: Vec<Node>,
        by: Vec<Node>,
    },
    Sort(Vec<ColumnSort<Node>>),
    Take {
        range: Range,
        by: Vec<Node>,
        sort: Vec<ColumnSort<Node>>,
    },
    Join {
        side: JoinSide,
        with: TableRef,
        filter: JoinFilter,
    },
    Group {
        by: Vec<Node>,
        pipeline: Box<Node>,
    },
    Window {
        kind: WindowKind,
        range: Range,
        pipeline: Box<Node>,
    },
    Unique, // internal only, can be expressed with group & take
}

#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub enum WindowKind {
    Rows,
    Range,
}
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub struct TableRef {
    pub name: String,
    pub alias: Option<String>,
    pub declared_at: Option<usize>,
}

#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub enum JoinFilter {
    On(Vec<Node>),
    Using(Vec<Node>),
}

#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub enum JoinSide {
    Inner,
    Left,
    Right,
    Full,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ColumnSort<T = Node> {
    pub direction: SortDirection,
    pub column: T,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum SortDirection {
    Asc,
    Desc,
}

impl Default for SortDirection {
    fn default() -> Self {
        SortDirection::Asc
    }
}