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
use crate::common::{DataType, FQName};
use itertools::Itertools;
use std::fmt::{Display, Formatter};

#[derive(PartialEq, Debug, Clone)]
pub struct Aggregate {
    pub or_replace: bool,
    pub not_exists: bool,
    pub name: FQName,
    pub data_type: DataType,
    pub sfunc: FQName,
    pub stype: DataType,
    pub finalfunc: FQName,
    pub init_cond: InitCondition,
}

impl Display for Aggregate {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "CREATE {}AGGREGATE {}{} ({}) SFUNC {} STYPE {} FINALFUNC {} INITCOND {}",
            if self.or_replace { "OR REPLACE " } else { "" },
            if self.not_exists {
                "IF NOT EXISTS "
            } else {
                ""
            },
            self.name,
            self.data_type,
            self.sfunc,
            self.stype,
            self.finalfunc,
            self.init_cond
        )
    }
}

#[derive(PartialEq, Debug, Clone)]
pub enum InitCondition {
    Constant(String),
    List(Vec<InitCondition>),
    Map(Vec<(String, InitCondition)>),
}

impl Display for InitCondition {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        match self {
            InitCondition::Constant(name) => write!(f, "{}", name),
            InitCondition::List(lst) => {
                write!(f, "({})", lst.iter().map(|x| x.to_string()).join(", "))
            }
            InitCondition::Map(entries) => write!(
                f,
                "({})",
                entries
                    .iter()
                    .map(|(k, v)| format!("{}:{}", k, v))
                    .join(", ")
            ),
        }
    }
}