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.repeated().at_least(1).or(update_only.map(|p| vec![p]));
49
50 parts.map(|parts| Query {
51 parts,
52 union_all: vec![],
53 })
54}
55
56pub fn statement_parser() -> impl Parser<Token, Spanned<Statement>, Error = ParserError> {
58 let explain = just(Token::Explain)
59 .ignore_then(
60 query_parser()
61 .map(Statement::Query)
62 .map_with_span(|s, span| (s, span)),
63 )
64 .map_with_span(|(inner, _), span| (Statement::Explain(Box::new(inner)), span));
65
66 let profile = just(Token::Profile)
67 .ignore_then(
68 query_parser()
69 .map(Statement::Query)
70 .map_with_span(|s, span| (s, span)),
71 )
72 .map_with_span(|(inner, _), span| (Statement::Profile(Box::new(inner)), span));
73
74 let query = query_parser()
75 .map(Statement::Query)
76 .map_with_span(|s, span| (s, span));
77
78 let create_node = create_node_table()
79 .map(Statement::CreateNodeTable)
80 .map_with_span(|s, span| (s, span));
81
82 let create_rel = create_rel_table()
83 .map(Statement::CreateRelTable)
84 .map_with_span(|s, span| (s, span));
85
86 let drop = drop_statement()
87 .map(Statement::Drop)
88 .map_with_span(|s, span| (s, span));
89
90 let alter = alter_table()
91 .map(Statement::AlterTable)
92 .map_with_span(|s, span| (s, span));
93
94 let copy = copy_from()
95 .map(Statement::CopyFrom)
96 .map_with_span(|s, span| (s, span));
97
98 let call = standalone_call()
99 .map(Statement::StandaloneCall)
100 .map_with_span(|s, span| (s, span));
101
102 let txn = transaction_statement()
103 .map(Statement::Transaction)
104 .map_with_span(|s, span| (s, span));
105
106 choice((
107 explain,
108 profile,
109 create_node,
110 create_rel,
111 drop,
112 alter,
113 copy,
114 call,
115 txn,
116 query,
117 ))
118 .then_ignore(just(Token::Semicolon).or_not())
119 .then_ignore(end())
120}