surrealdb_core/syn/parser/stmt/
relate.rs1use reblessive::Stk;
2
3use crate::{
4 sql::{statements::RelateStatement, Subquery, Value},
5 syn::{
6 parser::{
7 mac::{expected, expected_whitespace, unexpected},
8 ParseResult, Parser,
9 },
10 token::t,
11 },
12};
13
14impl Parser<'_> {
15 pub async fn parse_relate_stmt(&mut self, stk: &mut Stk) -> ParseResult<RelateStatement> {
16 let only = self.eat(t!("ONLY"));
17 let (kind, from, with) = stk.run(|stk| self.parse_relation(stk)).await?;
18 let uniq = self.eat(t!("UNIQUE"));
19
20 let data = self.try_parse_data(stk).await?;
21 let output = self.try_parse_output(stk).await?;
22 let timeout = self.try_parse_timeout()?;
23 let parallel = self.eat(t!("PARALLEL"));
24 Ok(RelateStatement {
25 only,
26 kind,
27 from,
28 with,
29 uniq,
30 data,
31 output,
32 timeout,
33 parallel,
34 })
35 }
36
37 pub async fn parse_relation(&mut self, stk: &mut Stk) -> ParseResult<(Value, Value, Value)> {
38 let first = self.parse_relate_value(stk).await?;
39 let next = self.next();
40 let is_o = match next.kind {
41 t!("->") => true,
42 t!("<") => {
43 expected_whitespace!(self, t!("-"));
44 false
45 }
46 _ => unexpected!(self, next, "a relation arrow"),
47 };
48 let kind = self.parse_relate_kind(stk).await?;
49 if is_o {
50 expected!(self, t!("->"));
51 } else {
52 expected!(self, t!("<"));
53 expected_whitespace!(self, t!("-"));
54 };
55 let second = self.parse_relate_value(stk).await?;
56 if is_o {
57 Ok((kind, first, second))
58 } else {
59 Ok((kind, second, first))
60 }
61 }
62
63 pub async fn parse_relate_kind(&mut self, ctx: &mut Stk) -> ParseResult<Value> {
64 match self.peek_kind() {
65 t!("$param") => self.next_token_value().map(Value::Param),
66 t!("(") => {
67 let span = self.pop_peek().span;
68 let res = self
69 .parse_inner_subquery(ctx, Some(span))
70 .await
71 .map(|x| Value::Subquery(Box::new(x)))?;
72 Ok(res)
73 }
74 _ => self.parse_thing_or_table(ctx).await,
75 }
76 }
77 pub async fn parse_relate_value(&mut self, ctx: &mut Stk) -> ParseResult<Value> {
78 let old = self.table_as_field;
79 self.table_as_field = true;
80 let r = self.parse_relate_value_inner(ctx).await;
81 self.table_as_field = old;
82 r
83 }
84
85 async fn parse_relate_value_inner(&mut self, ctx: &mut Stk) -> ParseResult<Value> {
86 match self.peek_kind() {
87 t!("[") => {
88 let start = self.pop_peek().span;
89 self.parse_array(ctx, start).await.map(Value::Array)
90 }
91 t!("$param") => self.next_token_value().map(Value::Param),
92 t!("RETURN")
93 | t!("SELECT")
94 | t!("CREATE")
95 | t!("UPSERT")
96 | t!("UPDATE")
97 | t!("DELETE")
98 | t!("RELATE")
99 | t!("DEFINE")
100 | t!("ALTER")
101 | t!("REMOVE")
102 | t!("REBUILD") => {
103 self.parse_inner_subquery(ctx, None).await.map(|x| Value::Subquery(Box::new(x)))
104 }
105 t!("IF") => {
106 self.pop_peek();
107 ctx.run(|ctx| self.parse_if_stmt(ctx))
108 .await
109 .map(|x| Value::Subquery(Box::new(Subquery::Ifelse(x))))
110 }
111 t!("(") => {
112 let span = self.pop_peek().span;
113 let res = self
114 .parse_inner_subquery(ctx, Some(span))
115 .await
116 .map(|x| Value::Subquery(Box::new(x)))?;
117 Ok(res)
118 }
119 _ => self.parse_thing(ctx).await.map(Value::Thing),
120 }
121 }
122
123 pub async fn parse_thing_or_table(&mut self, ctx: &mut Stk) -> ParseResult<Value> {
124 if self.peek_whitespace1().kind == t!(":") {
125 self.parse_thing(ctx).await.map(Value::Thing)
126 } else {
127 self.next_token_value().map(Value::Table)
128 }
129 }
130}