surrealdb_core/syn/parser/stmt/
relate.rs

1use 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}