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
108
109
110
111
112
113
114
115
116
117
118
119
use {
    crate::*,
    gluesql_core::{
        data::{LiteralError, ValueError},
        prelude::{Payload, Value::*},
    },
};

test_case!(unary_operator, async move {
    let test_cases = [
        (
            "CREATE TABLE Test (v1 INT, v2 FLOAT, v3 TEXT, v4 INT, v5 INT, v6 INT8)",
            Ok(Payload::Create),
        ),
        (
            r#"INSERT INTO Test VALUES (10, 10.5, "hello", -5, 1000, 20)"#,
            Ok(Payload::Insert(1)),
        ),
        (
            "SELECT -v1 as v1, -v2 as v2, v3, -v4 as v4, -v6 as v6 FROM Test",
            Ok(select_with_null!(
                v1      |   v2          |   v3                      |   v4      |  v6;
                I64(-10)    F64(-10.5)      Str("hello".to_owned())     I64(5)     I8(-20)
            )),
        ),
        (
            "SELECT -(-10) as v1, -(-10) as v2 FROM Test",
            Ok(select!(
                v1  |   v2
                I64 |   I64;
                10      10
            )),
        ),
        (
            "SELECT -v3 as v3 FROM Test",
            Err(ValueError::UnaryMinusOnNonNumeric.into()),
        ),
        (
            "SELECT -'errrr' as v1 FROM Test",
            Err(LiteralError::UnaryOperationOnNonNumeric.into()),
        ),
        (
            "SELECT +10 as v1, +(+10) as v2 FROM Test",
            Ok(select!(
                v1  |   v2
                I64 |   I64;
                10      10
            )),
        ),
        (
            "SELECT +v3 as v3 FROM Test",
            Err(ValueError::UnaryPlusOnNonNumeric.into()),
        ),
        (
            "SELECT +'errrr' as v1 FROM Test",
            Err(LiteralError::UnaryOperationOnNonNumeric.into()),
        ),
        (
            "SELECT v1! as v1 FROM Test",
            Ok(select!(
                v1
                I64;
                3628800
            )),
        ),
        (
            "SELECT 4! as v1 FROM Test",
            Ok(select!(
                v1
                I64;
                24
            )),
        ),
        (
            "SELECT v2! as v1 FROM Test",
            Err(ValueError::FactorialOnNonInteger.into()),
        ),
        (
            "SELECT v3! as v1 FROM Test",
            Err(ValueError::FactorialOnNonNumeric.into()),
        ),
        (
            "SELECT v4! as v4 FROM Test",
            Err(ValueError::FactorialOnNegativeNumeric.into()),
        ),
        (
            "SELECT v5! as v5 FROM Test",
            Err(ValueError::FactorialOverflow.into()),
        ),
        (
            "SELECT (-v6)! as v6 FROM Test",
            Err(ValueError::FactorialOnNegativeNumeric.into()),
        ),
        (
            "SELECT (v6 * 2)! as v6 FROM Test",
            Err(ValueError::FactorialOverflow.into()),
        ),
        (
            "SELECT (-5)! as v4 FROM Test",
            Err(ValueError::FactorialOnNegativeNumeric.into()),
        ),
        (
            "SELECT (5.5)! as v4 FROM Test",
            Err(ValueError::FactorialOnNonInteger.into()),
        ),
        (
            "SELECT 'errrr'! as v1 FROM Test",
            Err(ValueError::FactorialOnNonNumeric.into()),
        ),
        (
            "SELECT 1000! as v4 FROM Test",
            Err(ValueError::FactorialOverflow.into()),
        ),
    ];

    for (sql, expected) in test_cases {
        test!(sql, expected);
    }
});