kyu_parser/parser/
statement.rs1use chumsky::prelude::*;
4
5use crate::ast::*;
6use crate::span::Spanned;
7use crate::token::Token;
8
9use super::clause::{
10 reading_clause, return_clause, standalone_call, transaction_statement, updating_clause,
11 with_clause,
12};
13use super::ddl::{
14 alter_table, copy_from, create_node_table, create_rel_table, drop_statement, load_from,
15};
16
17type ParserError = Simple<Token>;
18
19fn query_parser() -> impl Parser<Token, Query, Error = ParserError> + Clone {
21 let query_part = reading_clause()
25 .repeated()
26 .then(updating_clause().repeated())
27 .then(
28 return_clause()
29 .map(|proj| (proj, true))
30 .or(with_clause().map(|(proj, _where)| (proj, false))),
31 )
32 .map(|((reading, updating), (projection, is_return))| QueryPart {
33 reading_clauses: reading,
34 updating_clauses: updating,
35 projection: Some(projection),
36 is_return,
37 });
38
39 let update_only = reading_clause()
41 .repeated()
42 .then(updating_clause().repeated().at_least(1))
43 .map(|(reading, updating)| QueryPart {
44 reading_clauses: reading,
45 updating_clauses: updating,
46 projection: None,
47 is_return: false,
48 });
49
50 let parts = query_part
51 .repeated()
52 .at_least(1)
53 .or(update_only.map(|p| vec![p]));
54
55 parts.map(|parts| Query {
56 parts,
57 union_all: vec![],
58 })
59}
60
61pub fn statement_parser() -> impl Parser<Token, Spanned<Statement>, Error = ParserError> {
63 let explain = just(Token::Explain)
64 .ignore_then(
65 query_parser()
66 .map(Statement::Query)
67 .map_with_span(|s, span| (s, span)),
68 )
69 .map_with_span(|(inner, _), span| (Statement::Explain(Box::new(inner)), span));
70
71 let profile = just(Token::Profile)
72 .ignore_then(
73 query_parser()
74 .map(Statement::Query)
75 .map_with_span(|s, span| (s, span)),
76 )
77 .map_with_span(|(inner, _), span| (Statement::Profile(Box::new(inner)), span));
78
79 let query = query_parser()
80 .map(Statement::Query)
81 .map_with_span(|s, span| (s, span));
82
83 let create_node = create_node_table()
84 .map(Statement::CreateNodeTable)
85 .map_with_span(|s, span| (s, span));
86
87 let create_rel = create_rel_table()
88 .map(Statement::CreateRelTable)
89 .map_with_span(|s, span| (s, span));
90
91 let drop = drop_statement()
92 .map(Statement::Drop)
93 .map_with_span(|s, span| (s, span));
94
95 let alter = alter_table()
96 .map(Statement::AlterTable)
97 .map_with_span(|s, span| (s, span));
98
99 let copy = copy_from()
100 .map(Statement::CopyFrom)
101 .map_with_span(|s, span| (s, span));
102
103 let load = load_from()
104 .map(Statement::LoadFrom)
105 .map_with_span(|s, span| (s, span));
106
107 let call = standalone_call()
108 .map(Statement::StandaloneCall)
109 .map_with_span(|s, span| (s, span));
110
111 let txn = transaction_statement()
112 .map(Statement::Transaction)
113 .map_with_span(|s, span| (s, span));
114
115 choice((
116 explain,
117 profile,
118 create_node,
119 create_rel,
120 drop,
121 alter,
122 copy,
123 load,
124 call,
125 txn,
126 query,
127 ))
128 .then_ignore(just(Token::Semicolon).or_not())
129 .then_ignore(end())
130}