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
use super::{super::combinator::*, *};
use crate::ast::*;
pub fn select_list(input: &str) -> ParseResult<Vec<String>> {
tuple((char('('), comma_separated(named_types), char(')')))
.map(|(_start, ids, _end)| ids)
.parse(input)
}
pub fn select_extension(input: &str) -> ParseResult<(String, Vec<String>)> {
let with = tuple((tag("WITH"), select_list)).map(|(_with, list)| list);
tuple((tag("BASED_ON"), type_ref, opt(with)))
.map(|(_based_on, id, opt)| (id, opt.unwrap_or_default()))
.parse(input)
}
pub fn select_type(input: &str) -> ParseResult<Type> {
let extensibility = tuple((
tag("EXTENSIBLE"),
opt(tuple((spaces, tag("GENERIC_ENTITY")))),
))
.map(|(_extensible, opt)| {
if opt.is_some() {
Extensibility::GenericEntity
} else {
Extensibility::Extensible
}
});
tuple((
opt(tuple((extensibility, spaces))),
tag("SELECT"),
select_list,
))
.map(|(opt, _select, types)| {
if let Some((extensibility, _spaces)) = opt {
Type::Select {
extensibility,
types,
}
} else {
Type::Select {
extensibility: Extensibility::None,
types,
}
}
})
.parse(input)
}
#[cfg(test)]
mod tests {
use super::*;
use nom::Finish;
#[test]
fn select() {
let (res, (s, _remarks)) = super::select_type("SELECT (a, b)").finish().unwrap();
assert_eq!(res, "");
if let Type::Select {
extensibility,
types,
} = s
{
assert_eq!(extensibility, Extensibility::None);
assert_eq!(types[0], "a");
assert_eq!(types[1], "b");
} else {
panic!()
}
}
}