surql_parser/upstream/syn/parser/stmt/
relate.rs1use crate::upstream::sql::statements::RelateStatement;
2use crate::upstream::sql::{Expr, Literal};
3use crate::upstream::syn::parser::mac::{expected, expected_whitespace, unexpected};
4use crate::upstream::syn::parser::{ParseResult, Parser};
5use crate::upstream::syn::token::t;
6use reblessive::Stk;
7impl Parser<'_> {
8 pub async fn parse_relate_stmt(&mut self, stk: &mut Stk) -> ParseResult<RelateStatement> {
9 let only = self.eat(t!("ONLY"));
10 let (from, through, to) = stk.run(|stk| self.parse_relation(stk)).await?;
11 self.eat(t!("UNIQUE"));
12 let data = self.try_parse_data(stk).await?;
13 let output = self.try_parse_output(stk).await?;
14 let timeout = self.try_parse_timeout(stk).await?;
15 Ok(RelateStatement {
16 only,
17 through,
18 from,
19 to,
20 data,
21 output,
22 timeout,
23 })
24 }
25 pub async fn parse_relation(&mut self, stk: &mut Stk) -> ParseResult<(Expr, Expr, Expr)> {
26 let first = self.parse_relate_expr(stk).await?;
27 let next = self.next();
28 let is_o = match next.kind {
29 t!("->") => true,
30 t!("<") => {
31 expected_whitespace!(self, t!("-"));
32 false
33 }
34 _ => unexpected!(self, next, "a relation arrow"),
35 };
36 let through = self.parse_relate_kind(stk).await?;
37 if is_o {
38 expected!(self, t!("->"));
39 } else {
40 expected!(self, t!("<"));
41 expected_whitespace!(self, t!("-"));
42 };
43 let second = self.parse_relate_expr(stk).await?;
44 if is_o {
45 Ok((first, through, second))
46 } else {
47 Ok((second, through, first))
48 }
49 }
50 pub async fn parse_relate_kind(&mut self, stk: &mut Stk) -> ParseResult<Expr> {
51 match self.peek_kind() {
52 t!("$param") => self.next_token_value().map(Expr::Param),
53 t!("(") => {
54 let span = self.pop_peek().span;
55 let res = stk.run(|ctx| self.parse_expr_inherit(ctx)).await?;
56 self.expect_closing_delimiter(t!(")"), span)?;
57 Ok(res)
58 }
59 _ => self.parse_thing_or_table(stk).await,
60 }
61 }
62 pub async fn parse_relate_expr(&mut self, stk: &mut Stk) -> ParseResult<Expr> {
63 match self.peek_kind() {
64 t!("[") => {
65 let start = self.pop_peek().span;
66 self.parse_array(stk, start)
67 .await
68 .map(|x| Expr::Literal(Literal::Array(x)))
69 }
70 t!("$param") => self.next_token_value().map(Expr::Param),
71 t!("RETURN")
72 | t!("SELECT")
73 | t!("CREATE")
74 | t!("UPSERT")
75 | t!("UPDATE")
76 | t!("DELETE")
77 | t!("RELATE")
78 | t!("DEFINE")
79 | t!("ALTER")
80 | t!("REMOVE")
81 | t!("REBUILD")
82 | t!("INFO")
83 | t!("IF") => self.parse_expr_field(stk).await,
84 t!("(") => {
85 let open = self.pop_peek().span;
86 let res = self.parse_expr_field(stk).await?;
87 self.expect_closing_delimiter(t!(")"), open)?;
88 Ok(res)
89 }
90 _ => self
91 .parse_record_id(stk)
92 .await
93 .map(|x| Expr::Literal(Literal::RecordId(x))),
94 }
95 }
96 pub async fn parse_thing_or_table(&mut self, stk: &mut Stk) -> ParseResult<Expr> {
97 if let Some(t!(":")) = self.peek_whitespace1().map(|x| x.kind) {
98 self.parse_record_id(stk)
99 .await
100 .map(|x| Expr::Literal(Literal::RecordId(x)))
101 } else {
102 self.parse_ident().map(Expr::Table)
103 }
104 }
105}