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