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