surrealdb_core/syn/parser/
prime.rs

1use geo::Point;
2use reblessive::Stk;
3
4use super::{mac::pop_glued, ParseResult, Parser};
5use crate::{
6	sql::{
7		Array, Closure, Dir, Duration, Function, Geometry, Ident, Idiom, Kind, Mock, Number, Param,
8		Part, Script, Strand, Subquery, Table, Value,
9	},
10	syn::{
11		error::bail,
12		lexer::compound,
13		parser::{
14			enter_object_recursion, enter_query_recursion,
15			mac::{expected, unexpected},
16		},
17		token::{t, Glued, Span, TokenKind},
18	},
19};
20
21impl Parser<'_> {
22	/// Parse a what primary.
23	///
24	/// What's are values which are more restricted in what expressions they can contain.
25	pub(super) async fn parse_what_primary(&mut self, ctx: &mut Stk) -> ParseResult<Value> {
26		let token = self.peek();
27		match token.kind {
28			t!("r\"") => {
29				self.pop_peek();
30				Ok(Value::Thing(self.parse_record_string(ctx, true).await?))
31			}
32			t!("r'") => {
33				self.pop_peek();
34				Ok(Value::Thing(self.parse_record_string(ctx, false).await?))
35			}
36			t!("d\"") | t!("d'") | TokenKind::Glued(Glued::Datetime) => {
37				Ok(Value::Datetime(self.next_token_value()?))
38			}
39			t!("u\"") | t!("u'") | TokenKind::Glued(Glued::Uuid) => {
40				Ok(Value::Uuid(self.next_token_value()?))
41			}
42			t!("$param") => {
43				let value = Value::Param(self.next_token_value()?);
44				let value = self.try_parse_inline(ctx, &value).await?.unwrap_or(value);
45				Ok(value)
46			}
47			t!("FUNCTION") => {
48				self.pop_peek();
49				let func = self.parse_script(ctx).await?;
50				let value = Value::Function(Box::new(func));
51				Ok(self.try_parse_inline(ctx, &value).await?.unwrap_or(value))
52			}
53			t!("IF") => {
54				let stmt = ctx.run(|ctx| self.parse_if_stmt(ctx)).await?;
55				Ok(Value::Subquery(Box::new(Subquery::Ifelse(stmt))))
56			}
57			t!("(") => {
58				let token = self.pop_peek();
59				let value = self
60					.parse_inner_subquery(ctx, Some(token.span))
61					.await
62					.map(|x| Value::Subquery(Box::new(x)))?;
63				Ok(self.try_parse_inline(ctx, &value).await?.unwrap_or(value))
64			}
65			t!("<") => {
66				self.pop_peek();
67				expected!(self, t!("FUTURE"));
68				expected!(self, t!(">"));
69				let start = expected!(self, t!("{")).span;
70				let block = self.parse_block(ctx, start).await?;
71				Ok(Value::Future(Box::new(super::sql::Future(block))))
72			}
73			t!("|") => {
74				let start = self.pop_peek().span;
75				self.parse_closure_or_mock(ctx, start).await
76			}
77			t!("||") => self.parse_closure_after_args(ctx, Vec::new()).await,
78			t!("/") => self.next_token_value().map(Value::Regex),
79			t!("RETURN")
80			| t!("SELECT")
81			| t!("CREATE")
82			| t!("INSERT")
83			| t!("UPSERT")
84			| t!("UPDATE")
85			| t!("DELETE")
86			| t!("RELATE")
87			| t!("DEFINE")
88			| t!("REMOVE")
89			| t!("REBUILD") => {
90				self.parse_inner_subquery(ctx, None).await.map(|x| Value::Subquery(Box::new(x)))
91			}
92			t!("fn") => {
93				self.pop_peek();
94				let value =
95					self.parse_custom_function(ctx).await.map(|x| Value::Function(Box::new(x)))?;
96				Ok(self.try_parse_inline(ctx, &value).await?.unwrap_or(value))
97			}
98			t!("ml") => {
99				self.pop_peek();
100				let value = self.parse_model(ctx).await.map(|x| Value::Model(Box::new(x)))?;
101				Ok(self.try_parse_inline(ctx, &value).await?.unwrap_or(value))
102			}
103			x if Self::kind_is_identifier(x) => {
104				let peek = self.peek1();
105				match peek.kind {
106					t!("::") | t!("(") => {
107						self.pop_peek();
108						self.parse_builtin(ctx, token.span).await
109					}
110					t!(":") => {
111						let str = self.next_token_value::<Ident>()?.0;
112						self.parse_thing_or_range(ctx, str).await.map(Value::Thing)
113					}
114					_ => Ok(Value::Table(self.next_token_value()?)),
115				}
116			}
117			_ => unexpected!(self, token, "an expression"),
118		}
119	}
120
121	pub(super) async fn try_parse_inline(
122		&mut self,
123		ctx: &mut Stk,
124		subject: &Value,
125	) -> ParseResult<Option<Value>> {
126		if self.eat_whitespace(t!("(")) {
127			let start = self.last_span();
128			let mut args = Vec::new();
129			loop {
130				if self.eat(t!(")")) {
131					break;
132				}
133
134				let arg = ctx.run(|ctx| self.parse_value_inherit(ctx)).await?;
135				args.push(arg);
136
137				if !self.eat(t!(",")) {
138					self.expect_closing_delimiter(t!(")"), start)?;
139					break;
140				}
141			}
142
143			let value =
144				Value::Function(Box::new(Function::Anonymous(subject.clone(), args, false)));
145			let value = ctx.run(|ctx| self.try_parse_inline(ctx, &value)).await?.unwrap_or(value);
146			Ok(Some(value))
147		} else {
148			Ok(None)
149		}
150	}
151
152	pub(super) fn parse_number_like_prime(&mut self) -> ParseResult<Value> {
153		let token = self.peek();
154		match token.kind {
155			TokenKind::Glued(Glued::Duration) => {
156				let duration = pop_glued!(self, Duration);
157				Ok(Value::Duration(duration))
158			}
159			TokenKind::Glued(Glued::Number) => {
160				let v = self.next_token_value()?;
161				Ok(Value::Number(v))
162			}
163			_ => {
164				self.pop_peek();
165				let value = self.lexer.lex_compound(token, compound::numeric)?;
166				let v = match value.value {
167					compound::Numeric::Number(x) => Value::Number(x),
168					compound::Numeric::Duration(x) => Value::Duration(Duration(x)),
169				};
170				Ok(v)
171			}
172		}
173	}
174
175	/// Parse an expressions
176	pub(super) async fn parse_idiom_expression(&mut self, ctx: &mut Stk) -> ParseResult<Value> {
177		let token = self.peek();
178		let value = match token.kind {
179			t!("@") => {
180				self.pop_peek();
181				let mut res = vec![Part::Doc];
182				if !self.peek_continues_idiom() {
183					res.push(self.parse_dot_part(ctx).await?);
184				}
185
186				Value::Idiom(Idiom(res))
187			}
188			t!("NONE") => {
189				self.pop_peek();
190				Value::None
191			}
192			t!("NULL") => {
193				self.pop_peek();
194				Value::Null
195			}
196			t!("true") => {
197				self.pop_peek();
198				Value::Bool(true)
199			}
200			t!("false") => {
201				self.pop_peek();
202				Value::Bool(false)
203			}
204			t!("<") => {
205				self.pop_peek();
206				let peek = self.peek_whitespace();
207				if peek.kind == t!("-") {
208					self.pop_peek();
209					let graph = ctx.run(|ctx| self.parse_graph(ctx, Dir::In)).await?;
210					Value::Idiom(Idiom(vec![Part::Graph(graph)]))
211				} else if peek.kind == t!("->") {
212					self.pop_peek();
213					let graph = ctx.run(|ctx| self.parse_graph(ctx, Dir::Both)).await?;
214					Value::Idiom(Idiom(vec![Part::Graph(graph)]))
215				} else if self.eat(t!("FUTURE")) {
216					// Casting should already have been parsed.
217					self.expect_closing_delimiter(t!(">"), token.span)?;
218					let next = expected!(self, t!("{")).span;
219					let block = self.parse_block(ctx, next).await?;
220					Value::Future(Box::new(super::sql::Future(block)))
221				} else {
222					unexpected!(self, token, "expected either a `<-` or a future")
223				}
224			}
225			t!("r\"") => {
226				self.pop_peek();
227				Value::Thing(self.parse_record_string(ctx, true).await?)
228			}
229			t!("r'") => {
230				self.pop_peek();
231				Value::Thing(self.parse_record_string(ctx, false).await?)
232			}
233			t!("d\"") | t!("d'") | TokenKind::Glued(Glued::Datetime) => {
234				Value::Datetime(self.next_token_value()?)
235			}
236			t!("u\"") | t!("u'") | TokenKind::Glued(Glued::Uuid) => {
237				Value::Uuid(self.next_token_value()?)
238			}
239			t!("'") | t!("\"") | TokenKind::Glued(Glued::Strand) => {
240				let s = self.next_token_value::<Strand>()?;
241				if self.settings.legacy_strands {
242					if let Some(x) = self.reparse_legacy_strand(ctx, &s.0).await {
243						return Ok(x);
244					}
245				}
246				Value::Strand(s)
247			}
248			t!("+")
249			| t!("-")
250			| TokenKind::Digits
251			| TokenKind::Glued(Glued::Number | Glued::Duration) => self.parse_number_like_prime()?,
252			TokenKind::NaN => {
253				self.pop_peek();
254				Value::Number(Number::Float(f64::NAN))
255			}
256			t!("$param") => {
257				let value = Value::Param(self.next_token_value()?);
258				self.try_parse_inline(ctx, &value).await?.unwrap_or(value)
259			}
260			t!("FUNCTION") => {
261				self.pop_peek();
262				let script = self.parse_script(ctx).await?;
263				Value::Function(Box::new(script))
264			}
265			t!("->") => {
266				self.pop_peek();
267				let graph = ctx.run(|ctx| self.parse_graph(ctx, Dir::Out)).await?;
268				Value::Idiom(Idiom(vec![Part::Graph(graph)]))
269			}
270			t!("[") => {
271				self.pop_peek();
272				self.parse_array(ctx, token.span).await.map(Value::Array)?
273			}
274			t!("{") => {
275				self.pop_peek();
276				let value = self.parse_object_like(ctx, token.span).await?;
277				self.try_parse_inline(ctx, &value).await?.unwrap_or(value)
278			}
279			t!("|") => {
280				self.pop_peek();
281				self.parse_closure_or_mock(ctx, token.span).await?
282			}
283			t!("||") => {
284				self.pop_peek();
285				ctx.run(|ctx| self.parse_closure_after_args(ctx, Vec::new())).await?
286			}
287			t!("IF") => {
288				enter_query_recursion!(this = self => {
289					this.pop_peek();
290					let stmt = ctx.run(|ctx| this.parse_if_stmt(ctx)).await?;
291					Value::Subquery(Box::new(Subquery::Ifelse(stmt)))
292				})
293			}
294			t!("(") => {
295				self.pop_peek();
296				let value = self.parse_inner_subquery_or_coordinate(ctx, token.span).await?;
297				self.try_parse_inline(ctx, &value).await?.unwrap_or(value)
298			}
299			t!("/") => self.next_token_value().map(Value::Regex)?,
300			t!("RETURN")
301			| t!("SELECT")
302			| t!("CREATE")
303			| t!("INSERT")
304			| t!("UPSERT")
305			| t!("UPDATE")
306			| t!("DELETE")
307			| t!("RELATE")
308			| t!("DEFINE")
309			| t!("REMOVE")
310			| t!("REBUILD") => {
311				self.parse_inner_subquery(ctx, None).await.map(|x| Value::Subquery(Box::new(x)))?
312			}
313			t!("fn") => {
314				self.pop_peek();
315				self.parse_custom_function(ctx).await.map(|x| Value::Function(Box::new(x)))?
316			}
317			t!("ml") => {
318				self.pop_peek();
319				self.parse_model(ctx).await.map(|x| Value::Model(Box::new(x)))?
320			}
321			x if Self::kind_is_identifier(x) => {
322				let peek = self.peek1();
323				match peek.kind {
324					t!("::") | t!("(") => {
325						self.pop_peek();
326						self.parse_builtin(ctx, token.span).await?
327					}
328					t!(":") => {
329						let str = self.next_token_value::<Ident>()?.0;
330						self.parse_thing_or_range(ctx, str).await?.into()
331					}
332					_ => {
333						if self.table_as_field {
334							Value::Idiom(Idiom(vec![Part::Field(self.next_token_value()?)]))
335						} else {
336							Value::Table(self.next_token_value()?)
337						}
338					}
339				}
340			}
341			_ => {
342				unexpected!(self, token, "an expression")
343			}
344		};
345
346		// Parse the rest of the idiom if it is being continued.
347		if self.peek_continues_idiom() {
348			let value = match value {
349				Value::Idiom(Idiom(x)) => self.parse_remaining_value_idiom(ctx, x).await,
350				Value::Table(Table(x)) => {
351					self.parse_remaining_value_idiom(ctx, vec![Part::Field(Ident(x))]).await
352				}
353				x => self.parse_remaining_value_idiom(ctx, vec![Part::Start(x)]).await,
354			}?;
355			Ok(self.try_parse_inline(ctx, &value).await?.unwrap_or(value))
356		} else {
357			Ok(value)
358		}
359	}
360
361	/// Parses an array production
362	///
363	/// # Parser state
364	/// Expects the starting `[` to already be eaten and its span passed as an argument.
365	pub(crate) async fn parse_array(&mut self, ctx: &mut Stk, start: Span) -> ParseResult<Array> {
366		let mut values = Vec::new();
367		enter_object_recursion!(this = self => {
368			loop {
369				if this.eat(t!("]")) {
370					break;
371				}
372
373				let value = ctx.run(|ctx| this.parse_value_inherit(ctx)).await?;
374				values.push(value);
375
376				if !this.eat(t!(",")) {
377					this.expect_closing_delimiter(t!("]"), start)?;
378					break;
379				}
380			}
381		});
382
383		Ok(Array(values))
384	}
385
386	/// Parse a mock `|foo:1..3|`
387	///
388	/// # Parser State
389	/// Expects the starting `|` already be eaten and its span passed as an argument.
390	pub(super) fn parse_mock(&mut self, start: Span) -> ParseResult<Mock> {
391		let name = self.next_token_value::<Ident>()?.0;
392		expected!(self, t!(":"));
393		let from = self.next_token_value()?;
394		let to = self.eat(t!("..")).then(|| self.next_token_value()).transpose()?;
395		self.expect_closing_delimiter(t!("|"), start)?;
396		if let Some(to) = to {
397			Ok(Mock::Range(name, from, to))
398		} else {
399			Ok(Mock::Count(name, from))
400		}
401	}
402
403	pub(super) async fn parse_closure_or_mock(
404		&mut self,
405		ctx: &mut Stk,
406		start: Span,
407	) -> ParseResult<Value> {
408		match self.peek_kind() {
409			t!("$param") => ctx.run(|ctx| self.parse_closure(ctx, start)).await,
410			_ => self.parse_mock(start).map(Value::Mock),
411		}
412	}
413
414	pub(super) async fn parse_closure(&mut self, ctx: &mut Stk, start: Span) -> ParseResult<Value> {
415		let mut args = Vec::new();
416		loop {
417			if self.eat(t!("|")) {
418				break;
419			}
420
421			let param = self.next_token_value::<Param>()?.0;
422			let kind = if self.eat(t!(":")) {
423				if self.eat(t!("<")) {
424					let delim = self.last_span();
425					ctx.run(|ctx| self.parse_kind(ctx, delim)).await?
426				} else {
427					ctx.run(|ctx| self.parse_inner_single_kind(ctx)).await?
428				}
429			} else {
430				Kind::Any
431			};
432
433			args.push((param, kind));
434
435			if !self.eat(t!(",")) {
436				self.expect_closing_delimiter(t!("|"), start)?;
437				break;
438			}
439		}
440
441		self.parse_closure_after_args(ctx, args).await
442	}
443
444	pub(super) async fn parse_closure_after_args(
445		&mut self,
446		ctx: &mut Stk,
447		args: Vec<(Ident, Kind)>,
448	) -> ParseResult<Value> {
449		let (returns, body) = if self.eat(t!("->")) {
450			let returns = Some(ctx.run(|ctx| self.parse_inner_kind(ctx)).await?);
451			let start = expected!(self, t!("{")).span;
452			let body = Value::Block(Box::new(ctx.run(|ctx| self.parse_block(ctx, start)).await?));
453			(returns, body)
454		} else {
455			let body = ctx.run(|ctx| self.parse_value_inherit(ctx)).await?;
456			(None, body)
457		};
458
459		Ok(Value::Closure(Box::new(Closure {
460			args,
461			returns,
462			body,
463		})))
464	}
465
466	pub async fn parse_full_subquery(&mut self, ctx: &mut Stk) -> ParseResult<Subquery> {
467		let peek = self.peek();
468		match peek.kind {
469			t!("(") => {
470				self.pop_peek();
471				self.parse_inner_subquery(ctx, Some(peek.span)).await
472			}
473			t!("IF") => {
474				enter_query_recursion!(this = self => {
475					this.pop_peek();
476					let if_stmt = ctx.run(|ctx| this.parse_if_stmt(ctx)).await?;
477					Ok(Subquery::Ifelse(if_stmt))
478				})
479			}
480			_ => self.parse_inner_subquery(ctx, None).await,
481		}
482	}
483
484	pub(super) async fn parse_inner_subquery_or_coordinate(
485		&mut self,
486		ctx: &mut Stk,
487		start: Span,
488	) -> ParseResult<Value> {
489		enter_query_recursion!(this = self => {
490			this.parse_inner_subquery_or_coordinate_inner(ctx,start).await
491		})
492	}
493
494	async fn parse_inner_subquery_or_coordinate_inner(
495		&mut self,
496		ctx: &mut Stk,
497		start: Span,
498	) -> ParseResult<Value> {
499		let peek = self.peek();
500		let res = match peek.kind {
501			t!("RETURN") => {
502				self.pop_peek();
503				let stmt = ctx.run(|ctx| self.parse_return_stmt(ctx)).await?;
504				Subquery::Output(stmt)
505			}
506			t!("SELECT") => {
507				self.pop_peek();
508				let stmt = ctx.run(|ctx| self.parse_select_stmt(ctx)).await?;
509				Subquery::Select(stmt)
510			}
511			t!("CREATE") => {
512				self.pop_peek();
513				let stmt = ctx.run(|ctx| self.parse_create_stmt(ctx)).await?;
514				Subquery::Create(stmt)
515			}
516			t!("INSERT") => {
517				self.pop_peek();
518				let stmt = ctx.run(|ctx| self.parse_insert_stmt(ctx)).await?;
519				Subquery::Insert(stmt)
520			}
521			t!("UPSERT") => {
522				self.pop_peek();
523				let stmt = ctx.run(|ctx| self.parse_upsert_stmt(ctx)).await?;
524				Subquery::Upsert(stmt)
525			}
526			t!("UPDATE") => {
527				self.pop_peek();
528				let stmt = ctx.run(|ctx| self.parse_update_stmt(ctx)).await?;
529				Subquery::Update(stmt)
530			}
531			t!("DELETE") => {
532				self.pop_peek();
533				let stmt = ctx.run(|ctx| self.parse_delete_stmt(ctx)).await?;
534				Subquery::Delete(stmt)
535			}
536			t!("RELATE") => {
537				self.pop_peek();
538				let stmt = ctx.run(|ctx| self.parse_relate_stmt(ctx)).await?;
539				Subquery::Relate(stmt)
540			}
541			t!("DEFINE") => {
542				self.pop_peek();
543				let stmt = ctx.run(|ctx| self.parse_define_stmt(ctx)).await?;
544				Subquery::Define(stmt)
545			}
546			t!("REMOVE") => {
547				self.pop_peek();
548				let stmt = self.parse_remove_stmt(ctx).await?;
549				Subquery::Remove(stmt)
550			}
551			t!("REBUILD") => {
552				self.pop_peek();
553				let stmt = self.parse_rebuild_stmt()?;
554				Subquery::Rebuild(stmt)
555			}
556			TokenKind::Digits | TokenKind::Glued(Glued::Number) | t!("+") | t!("-") => {
557				if self.glue_and_peek1()?.kind == t!(",") {
558					let number_span = self.peek().span;
559					let number = self.next_token_value::<Number>()?;
560					// eat ','
561					self.next();
562
563					if matches!(number, Number::Decimal(_))
564						|| matches!(number, Number::Float(x) if x.is_nan())
565					{
566						bail!("Unexpected token, expected a non-decimal, non-NaN, number",
567								@number_span => "Coordinate numbers can't be NaN or a decimal");
568					}
569
570					let x = number.as_float();
571					let y = self.next_token_value::<f64>()?;
572					self.expect_closing_delimiter(t!(")"), start)?;
573					return Ok(Value::Geometry(Geometry::Point(Point::from((x, y)))));
574				} else {
575					let value = ctx.run(|ctx| self.parse_value_inherit(ctx)).await?;
576					Subquery::Value(value)
577				}
578			}
579			_ => {
580				let value = ctx.run(|ctx| self.parse_value_inherit(ctx)).await?;
581				Subquery::Value(value)
582			}
583		};
584		let token = self.peek();
585		if token.kind != t!(")") && Self::starts_disallowed_subquery_statement(peek.kind) {
586			if let Subquery::Value(Value::Idiom(Idiom(ref idiom))) = res {
587				if idiom.len() == 1 {
588					bail!("Unexpected token `{}` expected `)`",peek.kind,
589						@token.span,
590						@peek.span => "This is a reserved keyword here and can't be an identifier");
591				}
592			}
593		}
594		self.expect_closing_delimiter(t!(")"), start)?;
595		Ok(Value::Subquery(Box::new(res)))
596	}
597
598	pub(super) async fn parse_inner_subquery(
599		&mut self,
600		ctx: &mut Stk,
601		start: Option<Span>,
602	) -> ParseResult<Subquery> {
603		enter_query_recursion!(this = self => {
604			this.parse_inner_subquery_inner(ctx,start).await
605		})
606	}
607
608	async fn parse_inner_subquery_inner(
609		&mut self,
610		ctx: &mut Stk,
611		start: Option<Span>,
612	) -> ParseResult<Subquery> {
613		let peek = self.peek();
614		let res = match peek.kind {
615			t!("RETURN") => {
616				self.pop_peek();
617				let stmt = ctx.run(|ctx| self.parse_return_stmt(ctx)).await?;
618				Subquery::Output(stmt)
619			}
620			t!("SELECT") => {
621				self.pop_peek();
622				let stmt = ctx.run(|ctx| self.parse_select_stmt(ctx)).await?;
623				Subquery::Select(stmt)
624			}
625			t!("CREATE") => {
626				self.pop_peek();
627				let stmt = ctx.run(|ctx| self.parse_create_stmt(ctx)).await?;
628				Subquery::Create(stmt)
629			}
630			t!("INSERT") => {
631				self.pop_peek();
632				let stmt = ctx.run(|ctx| self.parse_insert_stmt(ctx)).await?;
633				Subquery::Insert(stmt)
634			}
635			t!("UPSERT") => {
636				self.pop_peek();
637				let stmt = ctx.run(|ctx| self.parse_upsert_stmt(ctx)).await?;
638				Subquery::Upsert(stmt)
639			}
640			t!("UPDATE") => {
641				self.pop_peek();
642				let stmt = ctx.run(|ctx| self.parse_update_stmt(ctx)).await?;
643				Subquery::Update(stmt)
644			}
645			t!("DELETE") => {
646				self.pop_peek();
647				let stmt = ctx.run(|ctx| self.parse_delete_stmt(ctx)).await?;
648				Subquery::Delete(stmt)
649			}
650			t!("RELATE") => {
651				self.pop_peek();
652				let stmt = ctx.run(|ctx| self.parse_relate_stmt(ctx)).await?;
653				Subquery::Relate(stmt)
654			}
655			t!("DEFINE") => {
656				self.pop_peek();
657				let stmt = ctx.run(|ctx| self.parse_define_stmt(ctx)).await?;
658				Subquery::Define(stmt)
659			}
660			t!("REMOVE") => {
661				self.pop_peek();
662				let stmt = self.parse_remove_stmt(ctx).await?;
663				Subquery::Remove(stmt)
664			}
665			t!("REBUILD") => {
666				self.pop_peek();
667				let stmt = self.parse_rebuild_stmt()?;
668				Subquery::Rebuild(stmt)
669			}
670			_ => {
671				let value = ctx.run(|ctx| self.parse_value_inherit(ctx)).await?;
672				Subquery::Value(value)
673			}
674		};
675		if let Some(start) = start {
676			let token = self.peek();
677			if token.kind != t!(")") && Self::starts_disallowed_subquery_statement(peek.kind) {
678				if let Subquery::Value(Value::Idiom(Idiom(ref idiom))) = res {
679					if idiom.len() == 1 {
680						// we parsed a single idiom and the next token was a dissallowed statement so
681						// it is likely that the used meant to use an invalid statement.
682						bail!("Unexpected token `{}` expected `)`",peek.kind,
683							@token.span,
684							@peek.span => "This is a reserved keyword here and can't be an identifier");
685					}
686				}
687			}
688
689			self.expect_closing_delimiter(t!(")"), start)?;
690		}
691		Ok(res)
692	}
693
694	/// Parses a strand with legacy rules, parsing to a record id, datetime or uuid if the string
695	/// matches.
696	pub(super) async fn reparse_legacy_strand(
697		&mut self,
698		ctx: &mut Stk,
699		text: &str,
700	) -> Option<Value> {
701		if let Ok(x) = Parser::new(text.as_bytes()).parse_thing(ctx).await {
702			return Some(Value::Thing(x));
703		}
704		if let Ok(x) = Parser::new(text.as_bytes()).next_token_value() {
705			return Some(Value::Datetime(x));
706		}
707		if let Ok(x) = Parser::new(text.as_bytes()).next_token_value() {
708			return Some(Value::Uuid(x));
709		}
710		None
711	}
712
713	async fn parse_script(&mut self, ctx: &mut Stk) -> ParseResult<Function> {
714		let start = expected!(self, t!("(")).span;
715		let mut args = Vec::new();
716		loop {
717			if self.eat(t!(")")) {
718				break;
719			}
720
721			let arg = ctx.run(|ctx| self.parse_value_inherit(ctx)).await?;
722			args.push(arg);
723
724			if !self.eat(t!(",")) {
725				self.expect_closing_delimiter(t!(")"), start)?;
726				break;
727			}
728		}
729		let token = expected!(self, t!("{"));
730		let mut span = self.lexer.lex_compound(token, compound::javascript)?.span;
731		// remove the starting `{` and ending `}`.
732		span.offset += 1;
733		span.len -= 2;
734		let body = self.lexer.span_str(span);
735		Ok(Function::Script(Script(body.to_string()), args))
736	}
737}
738
739#[cfg(test)]
740mod tests {
741	use super::*;
742	use crate::syn::Parse;
743
744	#[test]
745	fn subquery_expression_statement() {
746		let sql = "(1 + 2 + 3)";
747		let out = Value::parse(sql);
748		assert_eq!("(1 + 2 + 3)", format!("{}", out))
749	}
750
751	#[test]
752	fn subquery_ifelse_statement() {
753		let sql = "IF true THEN false END";
754		let out = Value::parse(sql);
755		assert_eq!("IF true THEN false END", format!("{}", out))
756	}
757
758	#[test]
759	fn subquery_select_statement() {
760		let sql = "(SELECT * FROM test)";
761		let out = Value::parse(sql);
762		assert_eq!("(SELECT * FROM test)", format!("{}", out))
763	}
764
765	#[test]
766	fn subquery_define_statement() {
767		let sql = "(DEFINE EVENT foo ON bar WHEN $event = 'CREATE' THEN (CREATE x SET y = 1))";
768		let out = Value::parse(sql);
769		assert_eq!(
770			"(DEFINE EVENT foo ON bar WHEN $event = 'CREATE' THEN (CREATE x SET y = 1))",
771			format!("{}", out)
772		)
773	}
774
775	#[test]
776	fn subquery_remove_statement() {
777		let sql = "(REMOVE EVENT foo_event ON foo)";
778		let out = Value::parse(sql);
779		assert_eq!("(REMOVE EVENT foo_event ON foo)", format!("{}", out))
780	}
781
782	#[test]
783	fn subquery_insert_statment() {
784		let sql = "(INSERT INTO test [])";
785		let out = Value::parse(sql);
786		assert_eq!("(INSERT INTO test [])", format!("{}", out))
787	}
788
789	#[test]
790	fn mock_count() {
791		let sql = "|test:1000|";
792		let out = Value::parse(sql);
793		assert_eq!("|test:1000|", format!("{}", out));
794		assert_eq!(out, Value::from(Mock::Count(String::from("test"), 1000)));
795	}
796
797	#[test]
798	fn mock_range() {
799		let sql = "|test:1..1000|";
800		let out = Value::parse(sql);
801		assert_eq!("|test:1..1000|", format!("{}", out));
802		assert_eq!(out, Value::from(Mock::Range(String::from("test"), 1, 1000)));
803	}
804
805	#[test]
806	fn regex_simple() {
807		let sql = "/test/";
808		let out = Value::parse(sql);
809		assert_eq!("/test/", format!("{}", out));
810		let Value::Regex(regex) = out else {
811			panic!()
812		};
813		assert_eq!(regex, "test".parse().unwrap());
814	}
815
816	#[test]
817	fn regex_complex() {
818		let sql = r"/(?i)test\/[a-z]+\/\s\d\w{1}.*/";
819		let out = Value::parse(sql);
820		assert_eq!(r"/(?i)test\/[a-z]+\/\s\d\w{1}.*/", format!("{}", out));
821		let Value::Regex(regex) = out else {
822			panic!()
823		};
824		assert_eq!(regex, r"(?i)test/[a-z]+/\s\d\w{1}.*".parse().unwrap());
825	}
826
827	#[test]
828	fn plain_string() {
829		let sql = r#""hello""#;
830		let out = Value::parse(sql);
831		assert_eq!(r#"'hello'"#, format!("{}", out));
832
833		let sql = r#"s"hello""#;
834		let out = Value::parse(sql);
835		assert_eq!(r#"'hello'"#, format!("{}", out));
836
837		let sql = r#"s'hello'"#;
838		let out = Value::parse(sql);
839		assert_eq!(r#"'hello'"#, format!("{}", out));
840	}
841
842	#[test]
843	fn params() {
844		let sql = "$hello";
845		let out = Value::parse(sql);
846		assert_eq!("$hello", format!("{}", out));
847
848		let sql = "$__hello";
849		let out = Value::parse(sql);
850		assert_eq!("$__hello", format!("{}", out));
851	}
852}