Skip to main content

surql_parser/upstream/syn/parser/stmt/
relate.rs

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