1use crate::compat::catalog::{ApiMethod, EventDefinition, EventKind};
2use crate::compat::types::PublicDuration;
3#[cfg(feature = "surrealism")]
4use crate::compat::types::PublicFile;
5use crate::upstream::sql::access::AccessDuration;
6use crate::upstream::sql::access_type::JwtAccessVerify;
7use crate::upstream::sql::base::Base;
8use crate::upstream::sql::filter::Filter;
9use crate::upstream::sql::index::{Distance, HnswParams, VectorType};
10use crate::upstream::sql::kind::KindLiteral;
11use crate::upstream::sql::statements::define::config::api::{ApiConfig, Middleware};
12use crate::upstream::sql::statements::define::config::defaults::DefaultConfig;
13use crate::upstream::sql::statements::define::config::graphql::{GraphQLConfig, TableConfig};
14use crate::upstream::sql::statements::define::config::{ConfigInner, graphql};
15use crate::upstream::sql::statements::define::user::PassType;
16use crate::upstream::sql::statements::define::{
17 ApiAction, DefineAccessStatement, DefineAnalyzerStatement, DefineApiStatement,
18 DefineBucketStatement, DefineConfigStatement, DefineDatabaseStatement, DefineDefault,
19 DefineEventStatement, DefineFieldStatement, DefineFunctionStatement, DefineIndexStatement,
20 DefineKind, DefineNamespaceStatement, DefineParamStatement, DefineSequenceStatement,
21 DefineStatement, DefineTableStatement, DefineUserStatement,
22};
23use crate::upstream::sql::tokenizer::Tokenizer;
24use crate::upstream::sql::{
25 AccessType, DefineModuleStatement, Expr, Index, Kind, Literal, Param, Permission, Permissions,
26 Scoring, TableType, access_type, table_type,
27};
28#[cfg(feature = "surrealism")]
29use crate::upstream::sql::{ModuleExecutable, SiloExecutable, SurrealismExecutable};
30use crate::upstream::syn::error::bail;
31use crate::upstream::syn::parser::mac::{expected, unexpected};
32use crate::upstream::syn::parser::{ParseResult, Parser};
33use crate::upstream::syn::token::{Token, TokenKind, t};
34use reblessive::Stk;
35impl Parser<'_> {
36 pub async fn parse_define_stmt(&mut self, stk: &mut Stk) -> ParseResult<DefineStatement> {
37 let next = self.next();
38 match next.kind {
39 t!("NAMESPACE") => self
40 .parse_define_namespace(stk)
41 .await
42 .map(DefineStatement::Namespace),
43 t!("DATABASE") => self
44 .parse_define_database(stk)
45 .await
46 .map(DefineStatement::Database),
47 t!("FUNCTION") => self
48 .parse_define_function(stk)
49 .await
50 .map(DefineStatement::Function),
51 t!("USER") => self.parse_define_user(stk).await.map(DefineStatement::User),
52 t!("PARAM") => self
53 .parse_define_param(stk)
54 .await
55 .map(DefineStatement::Param),
56 t!("TABLE") => self
57 .parse_define_table(stk)
58 .await
59 .map(DefineStatement::Table),
60 t!("API") => self.parse_define_api(stk).await.map(DefineStatement::Api),
61 t!("EVENT") => stk
62 .run(|stk| self.parse_define_event(stk))
63 .await
64 .map(DefineStatement::Event),
65 t!("FIELD") => stk
66 .run(|stk| self.parse_define_field(stk))
67 .await
68 .map(DefineStatement::Field),
69 t!("INDEX") => stk
70 .run(|stk| self.parse_define_index(stk))
71 .await
72 .map(DefineStatement::Index),
73 t!("ANALYZER") => self
74 .parse_define_analyzer(stk)
75 .await
76 .map(DefineStatement::Analyzer),
77 t!("ACCESS") => self
78 .parse_define_access(stk)
79 .await
80 .map(DefineStatement::Access),
81 t!("CONFIG") => self
82 .parse_define_config(stk)
83 .await
84 .map(DefineStatement::Config),
85 t!("BUCKET") => self
86 .parse_define_bucket(stk, next)
87 .await
88 .map(DefineStatement::Bucket),
89 t!("SEQUENCE") => self
90 .parse_define_sequence(stk)
91 .await
92 .map(DefineStatement::Sequence),
93 t!("MODULE") => self
94 .parse_define_module(stk)
95 .await
96 .map(DefineStatement::Module),
97 _ => unexpected!(self, next, "a define statement keyword"),
98 }
99 }
100 pub async fn parse_define_namespace(
101 &mut self,
102 stk: &mut Stk,
103 ) -> ParseResult<DefineNamespaceStatement> {
104 let kind = if self.eat(t!("IF")) {
105 expected!(self, t!("NOT"));
106 expected!(self, t!("EXISTS"));
107 DefineKind::IfNotExists
108 } else if self.eat(t!("OVERWRITE")) {
109 DefineKind::Overwrite
110 } else {
111 DefineKind::Default
112 };
113 let name = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
114 let mut res = DefineNamespaceStatement {
115 id: None,
116 name,
117 kind,
118 ..Default::default()
119 };
120 while let t!("COMMENT") = self.peek_kind() {
121 self.pop_peek();
122 res.comment = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
123 }
124 Ok(res)
125 }
126 pub async fn parse_define_database(
127 &mut self,
128 stk: &mut Stk,
129 ) -> ParseResult<DefineDatabaseStatement> {
130 let kind = if self.eat(t!("IF")) {
131 expected!(self, t!("NOT"));
132 expected!(self, t!("EXISTS"));
133 DefineKind::IfNotExists
134 } else if self.eat(t!("OVERWRITE")) {
135 DefineKind::Overwrite
136 } else {
137 DefineKind::Default
138 };
139 let name = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
140 let mut res = DefineDatabaseStatement {
141 name,
142 kind,
143 ..Default::default()
144 };
145 loop {
146 match self.peek_kind() {
147 t!("COMMENT") => {
148 self.pop_peek();
149 res.comment = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
150 }
151 t!("CHANGEFEED") => {
152 self.pop_peek();
153 res.changefeed = Some(self.parse_changefeed()?);
154 }
155 t!("STRICT") => {
156 self.pop_peek();
157 res.strict = true;
158 }
159 _ => break,
160 }
161 }
162 Ok(res)
163 }
164 pub async fn parse_define_function(
165 &mut self,
166 stk: &mut Stk,
167 ) -> ParseResult<DefineFunctionStatement> {
168 let kind = if self.eat(t!("IF")) {
169 expected!(self, t!("NOT"));
170 expected!(self, t!("EXISTS"));
171 DefineKind::IfNotExists
172 } else if self.eat(t!("OVERWRITE")) {
173 DefineKind::Overwrite
174 } else {
175 DefineKind::Default
176 };
177 let name = self.parse_custom_function_name()?;
178 let token = expected!(self, t!("(")).span;
179 let mut args = Vec::new();
180 loop {
181 if self.eat(t!(")")) {
182 break;
183 }
184 let param = self.next_token_value::<Param>()?.to_string();
185 expected!(self, t!(":"));
186 let kind = stk.run(|ctx| self.parse_inner_kind(ctx)).await?;
187 args.push((param, kind));
188 if !self.eat(t!(",")) {
189 self.expect_closing_delimiter(t!(")"), token)?;
190 break;
191 }
192 }
193 let returns = if self.eat(t!("->")) {
194 Some(stk.run(|ctx| self.parse_inner_kind(ctx)).await?)
195 } else {
196 None
197 };
198 let next = expected!(self, t!("{")).span;
199 let block = self.parse_block(stk, next).await?;
200 let mut res = DefineFunctionStatement {
201 name,
202 args,
203 block,
204 kind,
205 returns,
206 comment: Expr::Literal(Literal::None),
207 permissions: Permission::default(),
208 };
209 loop {
210 match self.peek_kind() {
211 t!("COMMENT") => {
212 self.pop_peek();
213 res.comment = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
214 }
215 t!("PERMISSIONS") => {
216 self.pop_peek();
217 res.permissions = stk.run(|ctx| self.parse_permission_value(ctx)).await?;
218 }
219 _ => break,
220 }
221 }
222 Ok(res)
223 }
224 #[cfg(not(feature = "surrealism"))]
225 pub async fn parse_define_module(
226 &mut self,
227 _stk: &mut Stk,
228 ) -> ParseResult<DefineModuleStatement> {
229 bail!(
230 "Surrealism modules are not supported in WASM environments", @ self
231 .last_span() =>
232 "Use of `DEFINE MODULE` is not supported in WASM environments"
233 )
234 }
235 #[cfg(feature = "surrealism")]
236 pub async fn parse_define_module(
237 &mut self,
238 stk: &mut Stk,
239 ) -> ParseResult<DefineModuleStatement> {
240 if !self.settings.surrealism_enabled {
241 bail!(
242 "Experimental capability `surrealism` is not enabled", @ self.last_span()
243 => "Use of `DEFINE MODULE` is still experimental"
244 )
245 }
246 let kind = if self.eat(t!("IF")) {
247 expected!(self, t!("NOT"));
248 expected!(self, t!("EXISTS"));
249 DefineKind::IfNotExists
250 } else if self.eat(t!("OVERWRITE")) {
251 DefineKind::Overwrite
252 } else {
253 DefineKind::Default
254 };
255 let name = if self.eat(t!("mod")) {
256 expected!(self, t!("::"));
257 let name = self.parse_ident()?;
258 expected!(self, t!("AS"));
259 Some(name)
260 } else {
261 None
262 };
263 let peek = self.peek();
264 let executable = match peek.kind {
265 t!("silo") => {
266 self.pop_peek();
267 expected!(self, t!("::"));
268 let organisation = self.parse_ident()?;
269 expected!(self, t!("::"));
270 let package = self.parse_ident()?;
271 expected!(self, t!("<"));
272 let major = self.next_token_value::<u32>()?;
273 expected!(self, t!("."));
274 let minor = self.next_token_value::<u32>()?;
275 expected!(self, t!("."));
276 let patch = self.next_token_value::<u32>()?;
277 expected!(self, t!(">"));
278 ModuleExecutable::Silo(SiloExecutable {
279 organisation,
280 package,
281 major,
282 minor,
283 patch,
284 })
285 }
286 t!("f\"") | t!("f'") => {
287 let file = self.next_token_value::<PublicFile>()?;
288 ModuleExecutable::Surrealism(SurrealismExecutable(file.into()))
289 }
290 _ => {
291 unexpected!(self, peek, "a module executable");
292 }
293 };
294 let mut definition = DefineModuleStatement {
295 kind,
296 name,
297 executable,
298 comment: Expr::Literal(Literal::None),
299 permissions: Permission::default(),
300 };
301 loop {
302 match self.peek_kind() {
303 t!("COMMENT") => {
304 self.pop_peek();
305 definition.comment = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
306 }
307 t!("PERMISSIONS") => {
308 self.pop_peek();
309 definition.permissions =
310 stk.run(|ctx| self.parse_permission_value(ctx)).await?;
311 }
312 _ => break,
313 }
314 }
315 Ok(definition)
316 }
317 pub async fn parse_define_user(&mut self, stk: &mut Stk) -> ParseResult<DefineUserStatement> {
318 let kind = if self.eat(t!("IF")) {
319 expected!(self, t!("NOT"));
320 expected!(self, t!("EXISTS"));
321 DefineKind::IfNotExists
322 } else if self.eat(t!("OVERWRITE")) {
323 DefineKind::Overwrite
324 } else {
325 DefineKind::Default
326 };
327 let name = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
328 expected!(self, t!("ON"));
329 let base = self.parse_base()?;
330 let mut res = DefineUserStatement {
331 kind,
332 name,
333 base,
334 roles: vec!["Viewer".to_owned()],
335 token_duration: Expr::Literal(Literal::Duration(PublicDuration::from_secs(3600))),
336 ..DefineUserStatement::default()
337 };
338 loop {
339 match self.peek_kind() {
340 t!("COMMENT") => {
341 self.pop_peek();
342 res.comment = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
343 }
344 t!("PASSWORD") => {
345 let token = self.pop_peek();
346 if let PassType::Hash(_) = res.pass_type {
347 bail!(
348 "Unexpected token `PASSWORD`", @ token.span =>
349 "Can't set both a passhash and a password"
350 );
351 }
352 res.pass_type = PassType::Password(self.parse_string_lit()?);
353 }
354 t!("PASSHASH") => {
355 let token = self.pop_peek();
356 if let PassType::Password(_) = res.pass_type {
357 bail!(
358 "Unexpected token `PASSHASH`", @ token.span =>
359 "Can't set both a passhash and a password"
360 );
361 }
362 res.pass_type = PassType::Hash(self.parse_string_lit()?);
363 }
364 t!("ROLES") => {
365 self.pop_peek();
366 let mut roles = Vec::new();
367 loop {
368 let token = self.peek();
369 let role = self.parse_ident()?;
370 if !matches!(role.to_lowercase().as_str(), "viewer" | "editor" | "owner") {
371 unexpected!(self, token, "an existent role");
372 }
373 roles.push(role);
374 if !self.eat(t!(",")) {
375 break;
376 }
377 }
378 res.roles = roles;
379 }
380 t!("DURATION") => {
381 self.pop_peek();
382 expected!(self, t!("FOR"));
383 loop {
384 let token = self.peek();
385 match token.kind {
386 t!("TOKEN") => {
387 self.pop_peek();
388 res.token_duration =
389 stk.run(|ctx| self.parse_expr_field(ctx)).await?;
390 }
391 t!("SESSION") => {
392 self.pop_peek();
393 res.session_duration =
394 stk.run(|ctx| self.parse_expr_field(ctx)).await?;
395 }
396 _ => unexpected!(self, token, "`TOKEN` or `SESSION`"),
397 }
398 self.eat(t!(","));
399 if !self.eat(t!("FOR")) {
400 break;
401 }
402 }
403 }
404 _ => break,
405 }
406 }
407 Ok(res)
408 }
409 pub async fn parse_define_access(
410 &mut self,
411 stk: &mut Stk,
412 ) -> ParseResult<DefineAccessStatement> {
413 let kind = if self.eat(t!("IF")) {
414 expected!(self, t!("NOT"));
415 expected!(self, t!("EXISTS"));
416 DefineKind::IfNotExists
417 } else if self.eat(t!("OVERWRITE")) {
418 DefineKind::Overwrite
419 } else {
420 DefineKind::Default
421 };
422 let name = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
423 expected!(self, t!("ON"));
424 let base = self.parse_base()?;
425 let mut res = DefineAccessStatement {
426 name,
427 base,
428 kind,
429 authenticate: None,
430 access_type: AccessType::default(),
431 duration: AccessDuration::default(),
432 comment: Expr::Literal(Literal::None),
433 };
434 loop {
435 match self.peek_kind() {
436 t!("COMMENT") => {
437 self.pop_peek();
438 res.comment = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
439 }
440 t!("TYPE") => {
441 self.pop_peek();
442 let peek = self.peek();
443 match peek.kind {
444 t!("JWT") => {
445 self.pop_peek();
446 res.access_type = AccessType::Jwt(self.parse_jwt(stk).await?);
447 }
448 t!("RECORD") => {
449 let token = self.pop_peek();
450 if !matches!(res.base, Base::Db) {
451 unexpected!(self, token, "a valid access type at this level");
452 }
453 let mut ac = access_type::RecordAccess::default();
454 loop {
455 match self.peek_kind() {
456 t!("SIGNUP") => {
457 self.pop_peek();
458 ac.signup =
459 Some(stk.run(|stk| self.parse_expr_field(stk)).await?);
460 }
461 t!("SIGNIN") => {
462 self.pop_peek();
463 ac.signin =
464 Some(stk.run(|stk| self.parse_expr_field(stk)).await?);
465 }
466 _ => break,
467 }
468 }
469 while self.eat(t!("WITH")) {
470 let token = self.peek();
471 match token.kind {
472 t!("JWT") => {
473 self.pop_peek();
474 let jwt = self.parse_jwt(stk).await?;
475 ac.jwt = jwt.clone();
476 if let Some(mut bearer) = ac.bearer {
477 bearer.jwt = jwt;
478 ac.bearer = Some(bearer);
479 }
480 }
481 t!("REFRESH") => {
482 self.pop_peek();
483 ac.bearer = Some(access_type::BearerAccess {
484 kind: access_type::BearerAccessType::Refresh,
485 subject: access_type::BearerAccessSubject::Record,
486 jwt: ac.jwt.clone(),
487 });
488 }
489 _ => unexpected!(self, token, "JWT or REFRESH"),
490 }
491 self.eat(t!(","));
492 }
493 res.access_type = AccessType::Record(ac);
494 }
495 t!("BEARER") => {
496 self.pop_peek();
497 let mut ac = access_type::BearerAccess {
498 ..Default::default()
499 };
500 expected!(self, t!("FOR"));
501 let peek = self.peek();
502 match peek.kind {
503 t!("USER") => {
504 self.pop_peek();
505 ac.subject = access_type::BearerAccessSubject::User;
506 }
507 t!("RECORD") => {
508 match &res.base {
509 Base::Db => {}
510 _ => {
511 unexpected!(
512 self, peek, "USER", =>
513 "`RECORD` bearer can only be defined on a database"
514 )
515 }
516 }
517 self.pop_peek();
518 ac.subject = access_type::BearerAccessSubject::Record;
519 }
520 _ => match &res.base {
521 Base::Db => unexpected!(self, peek, "USER or RECORD"),
522 _ => unexpected!(self, peek, "USER"),
523 },
524 }
525 if self.eat(t!("WITH")) {
526 expected!(self, t!("JWT"));
527 ac.jwt = self.parse_jwt(stk).await?;
528 }
529 res.access_type = AccessType::Bearer(ac);
530 }
531 _ => break,
532 }
533 }
534 t!("AUTHENTICATE") => {
535 self.pop_peek();
536 res.authenticate = Some(stk.run(|stk| self.parse_expr_field(stk)).await?);
537 }
538 t!("DURATION") => {
539 self.pop_peek();
540 while self.eat(t!("FOR")) {
541 let peek = self.peek();
542 match peek.kind {
543 t!("GRANT") => {
544 self.pop_peek();
545 res.duration.grant =
546 stk.run(|ctx| self.parse_expr_field(ctx)).await?;
547 }
548 t!("TOKEN") => {
549 self.pop_peek();
550 res.duration.token =
551 stk.run(|ctx| self.parse_expr_field(ctx)).await?;
552 }
553 t!("SESSION") => {
554 self.pop_peek();
555 res.duration.session =
556 stk.run(|ctx| self.parse_expr_field(ctx)).await?;
557 }
558 _ => unexpected!(self, peek, "GRANT, TOKEN or SESSIONS"),
559 }
560 self.eat(t!(","));
561 }
562 }
563 _ => break,
564 }
565 }
566 Ok(res)
567 }
568 pub async fn parse_define_param(&mut self, stk: &mut Stk) -> ParseResult<DefineParamStatement> {
569 let kind = if self.eat(t!("IF")) {
570 expected!(self, t!("NOT"));
571 expected!(self, t!("EXISTS"));
572 DefineKind::IfNotExists
573 } else if self.eat(t!("OVERWRITE")) {
574 DefineKind::Overwrite
575 } else {
576 DefineKind::Default
577 };
578 let name = self.next_token_value::<Param>()?.to_string();
579 let mut res = DefineParamStatement {
580 name,
581 kind,
582 value: Expr::Literal(Literal::None),
583 comment: Expr::Literal(Literal::None),
584 permissions: Permission::default(),
585 };
586 loop {
587 match self.peek_kind() {
588 t!("VALUE") => {
589 self.pop_peek();
590 res.value = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
591 }
592 t!("COMMENT") => {
593 self.pop_peek();
594 res.comment = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
595 }
596 t!("PERMISSIONS") => {
597 self.pop_peek();
598 res.permissions = stk.run(|ctx| self.parse_permission_value(ctx)).await?;
599 }
600 _ => break,
601 }
602 }
603 Ok(res)
604 }
605 pub async fn parse_define_table(&mut self, stk: &mut Stk) -> ParseResult<DefineTableStatement> {
606 let kind = if self.eat(t!("IF")) {
607 expected!(self, t!("NOT"));
608 expected!(self, t!("EXISTS"));
609 DefineKind::IfNotExists
610 } else if self.eat(t!("OVERWRITE")) {
611 DefineKind::Overwrite
612 } else {
613 DefineKind::Default
614 };
615 let name = stk.run(|ctx| self.parse_expr_table(ctx)).await?;
616 let mut res = DefineTableStatement {
617 name,
618 permissions: Permissions::none(),
619 kind,
620 ..Default::default()
621 };
622 let mut set_table_type = false;
623 loop {
624 match self.peek_kind() {
625 t!("COMMENT") => {
626 self.pop_peek();
627 res.comment = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
628 }
629 t!("DROP") => {
630 self.pop_peek();
631 res.drop = true;
632 }
633 t!("TYPE") => {
634 self.pop_peek();
635 let peek = self.peek();
636 match peek.kind {
637 t!("NORMAL") => {
638 self.pop_peek();
639 res.table_type = TableType::Normal;
640 }
641 t!("RELATION") => {
642 self.pop_peek();
643 res.table_type = TableType::Relation(self.parse_relation_schema()?);
644 }
645 t!("ANY") => {
646 self.pop_peek();
647 res.table_type = TableType::Any;
648 }
649 _ => unexpected!(self, peek, "`NORMAL`, `RELATION`, or `ANY`"),
650 }
651 set_table_type = true;
652 }
653 t!("SCHEMALESS") => {
654 self.pop_peek();
655 res.full = false;
656 }
657 t!("SCHEMAFULL") => {
658 self.pop_peek();
659 res.full = true;
660 if !set_table_type {
661 res.table_type = TableType::Normal;
662 }
663 }
664 t!("PERMISSIONS") => {
665 self.pop_peek();
666 res.permissions = stk.run(|stk| self.parse_permission(stk, false)).await?;
667 }
668 t!("CHANGEFEED") => {
669 self.pop_peek();
670 res.changefeed = Some(self.parse_changefeed()?);
671 }
672 t!("AS") => {
673 self.pop_peek();
674 let peek = self.peek();
675 match peek.kind {
676 t!("(") => {
677 let open = self.pop_peek().span;
678 res.view = Some(self.parse_view(stk).await?);
679 self.expect_closing_delimiter(t!(")"), open)?;
680 }
681 t!("SELECT") => {
682 res.view = Some(self.parse_view(stk).await?);
683 }
684 _ => unexpected!(self, peek, "`SELECT`"),
685 }
686 }
687 _ => break,
688 }
689 }
690 Ok(res)
691 }
692 pub async fn parse_define_api(&mut self, stk: &mut Stk) -> ParseResult<DefineApiStatement> {
693 let kind = if self.eat(t!("IF")) {
694 expected!(self, t!("NOT"));
695 expected!(self, t!("EXISTS"));
696 DefineKind::IfNotExists
697 } else if self.eat(t!("OVERWRITE")) {
698 DefineKind::Overwrite
699 } else {
700 DefineKind::Default
701 };
702 let path = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
703 let mut res = DefineApiStatement {
704 path,
705 kind,
706 actions: Vec::new(),
707 fallback: None,
708 config: ApiConfig {
709 middleware: Vec::new(),
710 permissions: Permission::Full,
711 },
712 comment: Expr::Literal(Literal::None),
713 };
714 loop {
715 if !self.eat(t!("FOR")) {
716 break;
717 }
718 let peek = self.peek();
719 match peek.kind {
720 t!("ANY") => {
721 self.pop_peek();
722 res.config = self.parse_api_config(stk).await?;
723 if self.eat(t!("THEN")) {
724 res.fallback = Some(stk.run(|ctx| self.parse_expr_field(ctx)).await?);
725 }
726 }
727 t!("DELETE") | t!("GET") | t!("PATCH") | t!("POST") | t!("PUT") | t!("TRACE") => {
728 let mut methods: Vec<ApiMethod> = vec![];
729 loop {
730 let method = match self.peek().kind {
731 t!("DELETE") => ApiMethod::Delete,
732 t!("GET") => ApiMethod::Get,
733 t!("PATCH") => ApiMethod::Patch,
734 t!("POST") => ApiMethod::Post,
735 t!("PUT") => ApiMethod::Put,
736 t!("TRACE") => ApiMethod::Trace,
737 _ => {
738 unexpected!(
739 self,
740 peek,
741 "one of `DELETE`, `GET`, `PATCH`, `POST`, `PUT` or `TRACE`"
742 )
743 }
744 };
745 self.pop_peek();
746 methods.push(method);
747 if !self.eat(t!(",")) {
748 break;
749 }
750 }
751 let config = self.parse_api_config(stk).await?;
752 expected!(self, t!("THEN"));
753 let action = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
754 res.actions.push(ApiAction {
755 methods,
756 action,
757 config,
758 });
759 }
760 _ => {
761 unexpected!(
762 self,
763 peek,
764 "one of `DELETE`, `GET`, `PATCH`, `POST`, `PUT` or `TRACE`"
765 )
766 }
767 }
768 }
769 if self.eat(t!("COMMENT")) {
770 res.comment = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
771 }
772 Ok(res)
773 }
774 pub async fn parse_define_event(&mut self, stk: &mut Stk) -> ParseResult<DefineEventStatement> {
775 let kind = if self.eat(t!("IF")) {
776 expected!(self, t!("NOT"));
777 expected!(self, t!("EXISTS"));
778 DefineKind::IfNotExists
779 } else if self.eat(t!("OVERWRITE")) {
780 DefineKind::Overwrite
781 } else {
782 DefineKind::Default
783 };
784 let name = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
785 expected!(self, t!("ON"));
786 self.eat(t!("TABLE"));
787 let what = stk.run(|ctx| self.parse_expr_table(ctx)).await?;
788 let mut res = DefineEventStatement {
789 kind,
790 name,
791 target_table: what,
792 when: Expr::Literal(Literal::Bool(true)),
793 then: Vec::new(),
794 comment: Expr::Literal(Literal::None),
795 event_kind: EventKind::Sync,
796 };
797 loop {
798 match self.peek_kind() {
799 t!("WHEN") => {
800 self.pop_peek();
801 res.when = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
802 }
803 t!("THEN") => {
804 let token = self.pop_peek();
805 res.then = vec![stk.run(|ctx| self.parse_expr_field(ctx)).await?];
806 while self.eat(t!(",")) {
807 res.then
808 .push(stk.run(|ctx| self.parse_expr_field(ctx)).await?)
809 }
810 if res.then.is_empty() {
811 bail!(
812 "Expected at least one `THEN` statement", @ token.span =>
813 "`THEN` statement required"
814 );
815 }
816 }
817 t!("COMMENT") => {
818 self.pop_peek();
819 res.comment = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
820 }
821 t!("ASYNC") => {
822 self.pop_peek();
823 res.event_kind = EventKind::Async {
824 retry: EventDefinition::DEFAULT_RETRY,
825 max_depth: EventDefinition::DEFAULT_MAX_DEPTH,
826 };
827 }
828 t!("RETRY") => {
829 let token = self.pop_peek();
830 if let EventKind::Async { retry, .. } = &mut res.event_kind {
831 *retry = self.next_token_value()?;
832 } else {
833 bail!(
834 "Unexpected token `RETRY`", @ token.span =>
835 "RETRY must be set after ASYNC"
836 );
837 }
838 }
839 t!("MAXDEPTH") => {
840 let token = self.pop_peek();
841 if let EventKind::Async { max_depth, .. } = &mut res.event_kind {
842 *max_depth = self.next_token_value()?;
843 } else {
844 bail!(
845 "Unexpected token `MAXDEPTH`", @ token.span =>
846 "MAXDEPTH must be set after ASYNC"
847 );
848 }
849 }
850 _ => break,
851 }
852 }
853 if res.then.is_empty() {
854 bail!(
855 "Expected at least one `THEN` statement", @ self.last_span =>
856 "`THEN` statement required"
857 );
858 }
859 Ok(res)
860 }
861 pub async fn parse_define_field(&mut self, stk: &mut Stk) -> ParseResult<DefineFieldStatement> {
862 let kind = if self.eat(t!("IF")) {
863 expected!(self, t!("NOT"));
864 expected!(self, t!("EXISTS"));
865 DefineKind::IfNotExists
866 } else if self.eat(t!("OVERWRITE")) {
867 DefineKind::Overwrite
868 } else {
869 DefineKind::Default
870 };
871 let name = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
872 expected!(self, t!("ON"));
873 self.eat(t!("TABLE"));
874 let what = stk.run(|ctx| self.parse_expr_table(ctx)).await?;
875 let mut res = DefineFieldStatement {
876 name,
877 what,
878 kind,
879 ..Default::default()
880 };
881 loop {
882 match self.peek_kind() {
883 t!("FLEXIBLE") => {
884 self.pop_peek();
885 bail!("FLEXIBLE must be specified after TYPE", @ self.last_span);
886 }
887 t!("TYPE") => {
888 self.pop_peek();
889 res.field_kind = Some(stk.run(|ctx| self.parse_inner_kind(ctx)).await?);
890 if self.eat(t!("FLEXIBLE")) {
891 fn kind_contains_object(kind: &Kind) -> bool {
892 match kind {
893 Kind::Object => true,
894 Kind::Either(kinds) => kinds.iter().any(kind_contains_object),
895 Kind::Array(inner, _) | Kind::Set(inner, _) => {
896 kind_contains_object(inner)
897 }
898 Kind::Literal(KindLiteral::Object(_)) => true,
899 Kind::Literal(KindLiteral::Array(x)) => {
900 x.iter().any(kind_contains_object)
901 }
902 _ => false,
903 }
904 }
905 let is_valid_for_flexible =
906 res.field_kind.as_ref().is_some_and(kind_contains_object);
907 if !is_valid_for_flexible {
908 bail!(
909 "FLEXIBLE can only be used with types containing object", @
910 self.last_span
911 );
912 }
913 res.flexible = true;
914 }
915 }
916 t!("READONLY") => {
917 self.pop_peek();
918 res.readonly = true;
919 }
920 t!("VALUE") => {
921 self.pop_peek();
922 res.value = Some(stk.run(|ctx| self.parse_expr_field(ctx)).await?);
923 }
924 t!("ASSERT") => {
925 self.pop_peek();
926 res.assert = Some(stk.run(|ctx| self.parse_expr_field(ctx)).await?);
927 }
928 t!("DEFAULT") => {
929 self.pop_peek();
930 if self.eat(t!("ALWAYS")) {
931 res.default =
932 DefineDefault::Always(stk.run(|ctx| self.parse_expr_field(ctx)).await?);
933 } else {
934 res.default =
935 DefineDefault::Set(stk.run(|ctx| self.parse_expr_field(ctx)).await?);
936 }
937 }
938 t!("PERMISSIONS") => {
939 self.pop_peek();
940 res.permissions = stk.run(|ctx| self.parse_permission(ctx, true)).await?;
941 }
942 t!("COMMENT") => {
943 self.pop_peek();
944 res.comment = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
945 }
946 t!("REFERENCE") => {
947 self.pop_peek();
948 res.reference = Some(self.parse_reference(stk).await?);
949 }
950 t!("COMPUTED") => {
951 self.pop_peek();
952 res.computed = Some(stk.run(|stk| self.parse_expr_field(stk)).await?);
953 }
954 _ => break,
955 }
956 }
957 Ok(res)
958 }
959 pub async fn parse_define_index(&mut self, stk: &mut Stk) -> ParseResult<DefineIndexStatement> {
960 let kind = if self.eat(t!("IF")) {
961 expected!(self, t!("NOT"));
962 expected!(self, t!("EXISTS"));
963 DefineKind::IfNotExists
964 } else if self.eat(t!("OVERWRITE")) {
965 DefineKind::Overwrite
966 } else {
967 DefineKind::Default
968 };
969 let name = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
970 expected!(self, t!("ON"));
971 self.eat(t!("TABLE"));
972 let what = stk.run(|ctx| self.parse_expr_table(ctx)).await?;
973 let mut res = DefineIndexStatement {
974 name,
975 what,
976 kind,
977 cols: Vec::new(),
978 index: Index::Idx,
979 comment: Expr::Literal(Literal::None),
980 concurrently: false,
981 };
982 let mut field_span = None;
983 loop {
984 match self.peek_kind() {
985 t!("FIELDS") => {
986 self.pop_peek();
987 res.cols = vec![stk.run(|ctx| self.parse_expr_field(ctx)).await?];
988 while self.eat(t!(",")) {
989 res.cols
990 .push(stk.run(|ctx| self.parse_expr_field(ctx)).await?);
991 }
992 field_span = Some(self.last_span);
993 }
994 t!("UNIQUE") => {
995 self.pop_peek();
996 res.index = Index::Uniq;
997 }
998 t!("COUNT") => {
999 self.pop_peek();
1000 let cond = self.try_parse_condition(stk).await?;
1001 res.index = Index::Count(cond);
1002 }
1003 t!("FULLTEXT") => {
1004 self.pop_peek();
1005 let mut analyzer: Option<String> = None;
1006 let mut scoring = None;
1007 let mut hl = false;
1008 loop {
1009 match self.peek_kind() {
1010 t!("ANALYZER") => {
1011 self.pop_peek();
1012 analyzer = Some(self.parse_ident()).transpose()?;
1013 }
1014 t!("BM25") => {
1015 self.pop_peek();
1016 if self.eat(t!("(")) {
1017 let open = self.last_span();
1018 let k1 = self.next_token_value()?;
1019 expected!(self, t!(","));
1020 let b = self.next_token_value()?;
1021 self.expect_closing_delimiter(t!(")"), open)?;
1022 scoring = Some(Scoring::Bm { k1, b });
1023 } else {
1024 scoring = Some(Default::default());
1025 };
1026 }
1027 t!("HIGHLIGHTS") => {
1028 self.pop_peek();
1029 hl = true;
1030 }
1031 _ => break,
1032 }
1033 }
1034 res.index = Index::FullText(crate::upstream::sql::index::FullTextParams {
1035 az: analyzer.unwrap_or_else(|| "like".to_owned()),
1036 sc: scoring.unwrap_or_else(Default::default),
1037 hl,
1038 });
1039 }
1040 t!("HNSW") => {
1041 self.pop_peek();
1042 expected!(self, t!("DIMENSION"));
1043 let dimension = self.next_token_value()?;
1044 let mut distance = Distance::Euclidean;
1045 let mut vector_type = VectorType::F32;
1046 let mut m = None;
1047 let mut m0 = None;
1048 let mut ml = None;
1049 let mut ef_construction = 150;
1050 let mut extend_candidates = false;
1051 let mut keep_pruned_connections = false;
1052 let mut use_hashed_vector = false;
1053 loop {
1054 match self.peek_kind() {
1055 t!("DISTANCE") => {
1056 self.pop_peek();
1057 distance = self.parse_distance()?;
1058 }
1059 t!("TYPE") => {
1060 self.pop_peek();
1061 vector_type = self.parse_vector_type()?;
1062 }
1063 t!("LM") => {
1064 self.pop_peek();
1065 ml = Some(self.next_token_value()?);
1066 }
1067 t!("M0") => {
1068 self.pop_peek();
1069 m0 = Some(self.next_token_value()?);
1070 }
1071 t!("M") => {
1072 self.pop_peek();
1073 let v = self.next_token_value()?;
1074 let span = self.last_span();
1075 m = Some((v, span));
1076 }
1077 t!("EFC") => {
1078 self.pop_peek();
1079 ef_construction = self.next_token_value()?;
1080 }
1081 t!("EXTEND_CANDIDATES") => {
1082 self.pop_peek();
1083 extend_candidates = true;
1084 }
1085 t!("KEEP_PRUNED_CONNECTIONS") => {
1086 self.pop_peek();
1087 keep_pruned_connections = true;
1088 }
1089 t!("HASHED_VECTOR") => {
1090 self.pop_peek();
1091 use_hashed_vector = true;
1092 }
1093 _ => {
1094 break;
1095 }
1096 }
1097 }
1098 let m = if let Some((m, span)) = m {
1099 if m > 127 {
1100 bail!(
1101 "Invalid value for HNSW parameter `M`", @ span =>
1102 "`M` cannot be larger then 127"
1103 )
1104 }
1105 m
1106 } else {
1107 12u8
1108 };
1109 let m0 = m0.unwrap_or(m.saturating_mul(2));
1110 let ml = ml.unwrap_or((1.0 / (m as f64).ln()).into());
1111 res.index = Index::Hnsw(HnswParams {
1112 dimension,
1113 distance,
1114 vector_type,
1115 m,
1116 m0,
1117 ml,
1118 ef_construction,
1119 extend_candidates,
1120 keep_pruned_connections,
1121 use_hashed_vector,
1122 });
1123 }
1124 t!("CONCURRENTLY") => {
1125 self.pop_peek();
1126 res.concurrently = true;
1127 }
1128 t!("COMMENT") => {
1129 self.pop_peek();
1130 res.comment = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
1131 }
1132 _ => break,
1133 }
1134 }
1135 match (field_span, &res.index) {
1136 (Some(field_span), Index::Count(_)) => {
1137 if !res.cols.is_empty() {
1138 bail!("Cannot create a count index with fields", @ field_span);
1139 }
1140 }
1141 (field_span, Index::FullText(_) | Index::Hnsw(_)) => {
1142 if res.cols.len() != 1 {
1143 if let Some(field_span) = field_span {
1144 bail!(
1145 "Expected one column, found {}", res.cols.len(), @ field_span
1146 );
1147 } else {
1148 bail!("Expected one column, found none", @ self.recent_span());
1149 }
1150 }
1151 }
1152 (None, Index::Uniq | Index::Idx) => {
1153 if res.cols.is_empty() {
1154 bail!(
1155 "Expected at least one column - Use FIELDS to define columns", @
1156 self.recent_span()
1157 );
1158 }
1159 }
1160 (_, _) => {}
1161 }
1162 Ok(res)
1163 }
1164 pub async fn parse_define_analyzer(
1165 &mut self,
1166 stk: &mut Stk,
1167 ) -> ParseResult<DefineAnalyzerStatement> {
1168 let kind = if self.eat(t!("IF")) {
1169 expected!(self, t!("NOT"));
1170 expected!(self, t!("EXISTS"));
1171 DefineKind::IfNotExists
1172 } else if self.eat(t!("OVERWRITE")) {
1173 DefineKind::Overwrite
1174 } else {
1175 DefineKind::Default
1176 };
1177 let name = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
1178 let mut res = DefineAnalyzerStatement {
1179 name,
1180 function: None,
1181 tokenizers: None,
1182 filters: None,
1183 comment: Expr::Literal(Literal::None),
1184 kind,
1185 };
1186 loop {
1187 match self.peek_kind() {
1188 t!("FILTERS") => {
1189 self.pop_peek();
1190 let mut filters = Vec::new();
1191 loop {
1192 let next = self.next();
1193 match next.kind {
1194 t!("ASCII") => {
1195 filters.push(Filter::Ascii);
1196 }
1197 t!("LOWERCASE") => {
1198 filters.push(Filter::Lowercase);
1199 }
1200 t!("UPPERCASE") => {
1201 filters.push(Filter::Uppercase);
1202 }
1203 t!("EDGENGRAM") => {
1204 let open_span = expected!(self, t!("(")).span;
1205 let a = self.next_token_value()?;
1206 expected!(self, t!(","));
1207 let b = self.next_token_value()?;
1208 self.expect_closing_delimiter(t!(")"), open_span)?;
1209 filters.push(Filter::EdgeNgram(a, b));
1210 }
1211 t!("NGRAM") => {
1212 let open_span = expected!(self, t!("(")).span;
1213 let a = self.next_token_value()?;
1214 expected!(self, t!(","));
1215 let b = self.next_token_value()?;
1216 self.expect_closing_delimiter(t!(")"), open_span)?;
1217 filters.push(Filter::Ngram(a, b));
1218 }
1219 t!("SNOWBALL") => {
1220 let open_span = expected!(self, t!("(")).span;
1221 let language = self.next_token_value()?;
1222 self.expect_closing_delimiter(t!(")"), open_span)?;
1223 filters.push(Filter::Snowball(language))
1224 }
1225 t!("MAPPER") => {
1226 let open_span = expected!(self, t!("(")).span;
1227 let path: String = self.parse_string_lit()?;
1228 self.expect_closing_delimiter(t!(")"), open_span)?;
1229 filters.push(Filter::Mapper(path))
1230 }
1231 _ => unexpected!(self, next, "a filter"),
1232 }
1233 if !self.eat(t!(",")) {
1234 break;
1235 }
1236 }
1237 res.filters = Some(filters);
1238 }
1239 t!("TOKENIZERS") => {
1240 self.pop_peek();
1241 let mut tokenizers = Vec::new();
1242 loop {
1243 let next = self.next();
1244 let tokenizer = match next.kind {
1245 t!("BLANK") => Tokenizer::Blank,
1246 t!("CAMEL") => Tokenizer::Camel,
1247 t!("CLASS") => Tokenizer::Class,
1248 t!("PUNCT") => Tokenizer::Punct,
1249 _ => unexpected!(self, next, "a tokenizer"),
1250 };
1251 tokenizers.push(tokenizer);
1252 if !self.eat(t!(",")) {
1253 break;
1254 }
1255 }
1256 res.tokenizers = Some(tokenizers);
1257 }
1258 t!("FUNCTION") => {
1259 self.pop_peek();
1260 expected!(self, t!("fn"));
1261 expected!(self, t!("::"));
1262 let mut ident = self.parse_ident()?;
1263 while self.eat(t!("::")) {
1264 let value = self.parse_ident()?;
1265 ident.push_str("::");
1266 ident.push_str(&value);
1267 }
1268 res.function = Some(ident);
1269 }
1270 t!("COMMENT") => {
1271 self.pop_peek();
1272 res.comment = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
1273 }
1274 _ => break,
1275 }
1276 }
1277 Ok(res)
1278 }
1279 pub async fn parse_define_bucket(
1280 &mut self,
1281 stk: &mut Stk,
1282 token: Token,
1283 ) -> ParseResult<DefineBucketStatement> {
1284 if !self.settings.files_enabled {
1285 unexpected!(self, token, "the experimental files feature to be enabled");
1286 }
1287 let kind = if self.eat(t!("IF")) {
1288 expected!(self, t!("NOT"));
1289 expected!(self, t!("EXISTS"));
1290 DefineKind::IfNotExists
1291 } else if self.eat(t!("OVERWRITE")) {
1292 DefineKind::Overwrite
1293 } else {
1294 DefineKind::Default
1295 };
1296 let name = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
1297 let mut res = DefineBucketStatement {
1298 name,
1299 kind,
1300 ..Default::default()
1301 };
1302 loop {
1303 match self.peek_kind() {
1304 t!("BACKEND") => {
1305 self.pop_peek();
1306 res.backend = Some(stk.run(|stk| self.parse_expr_field(stk)).await?);
1307 }
1308 t!("PERMISSIONS") => {
1309 self.pop_peek();
1310 res.permissions = stk.run(|stk| self.parse_permission_value(stk)).await?;
1311 }
1312 t!("READONLY") => {
1313 self.pop_peek();
1314 res.readonly = true;
1315 }
1316 t!("COMMENT") => {
1317 self.pop_peek();
1318 res.comment = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
1319 }
1320 _ => {
1321 break;
1322 }
1323 }
1324 }
1325 Ok(res)
1326 }
1327 pub async fn parse_define_sequence(
1328 &mut self,
1329 stk: &mut Stk,
1330 ) -> ParseResult<DefineSequenceStatement> {
1331 let kind = if self.eat(t!("IF")) {
1332 expected!(self, t!("NOT"));
1333 expected!(self, t!("EXISTS"));
1334 DefineKind::IfNotExists
1335 } else if self.eat(t!("OVERWRITE")) {
1336 DefineKind::Overwrite
1337 } else {
1338 DefineKind::Default
1339 };
1340 let name = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
1341 let batch = if self.eat(t!("BATCH")) {
1342 stk.run(|ctx| self.parse_expr_field(ctx)).await?
1343 } else {
1344 Expr::Literal(Literal::Integer(1000))
1345 };
1346 let start = if self.eat(t!("START")) {
1347 stk.run(|ctx| self.parse_expr_field(ctx)).await?
1348 } else {
1349 Expr::Literal(Literal::Integer(0))
1350 };
1351 let timeout = self.try_parse_timeout(stk).await?;
1352 Ok(DefineSequenceStatement {
1353 name,
1354 kind,
1355 batch,
1356 start,
1357 timeout,
1358 })
1359 }
1360 pub async fn parse_define_config(
1361 &mut self,
1362 stk: &mut Stk,
1363 ) -> ParseResult<DefineConfigStatement> {
1364 let kind = if self.eat(t!("IF")) {
1365 expected!(self, t!("NOT"));
1366 expected!(self, t!("EXISTS"));
1367 DefineKind::IfNotExists
1368 } else if self.eat(t!("OVERWRITE")) {
1369 DefineKind::Overwrite
1370 } else {
1371 DefineKind::Default
1372 };
1373 let next = self.next();
1374 let inner = match next.kind {
1375 t!("API") => self.parse_api_config(stk).await.map(ConfigInner::Api)?,
1376 t!("GRAPHQL") => self.parse_graphql_config().map(ConfigInner::GraphQL)?,
1377 t!("DEFAULT") => self
1378 .parse_default_config(stk)
1379 .await
1380 .map(ConfigInner::Default)?,
1381 _ => unexpected!(self, next, "a type of config"),
1382 };
1383 Ok(DefineConfigStatement { inner, kind })
1384 }
1385 pub async fn parse_default_config(&mut self, stk: &mut Stk) -> ParseResult<DefaultConfig> {
1386 let mut config = DefaultConfig::default();
1387 let peek = self.peek();
1388 if !matches!(peek.kind, t!("NAMESPACE") | t!("DATABASE")) {
1389 unexpected!(self, peek, "a namespace or database name");
1390 }
1391 loop {
1392 match self.peek_kind() {
1393 t!("NAMESPACE") => {
1394 self.pop_peek();
1395 config.namespace = stk.run(|stk| self.parse_expr_field(stk)).await?;
1396 }
1397 t!("DATABASE") => {
1398 self.pop_peek();
1399 config.database = stk.run(|stk| self.parse_expr_field(stk)).await?;
1400 }
1401 _ => break,
1402 }
1403 }
1404 Ok(config)
1405 }
1406 pub async fn parse_api_config(&mut self, stk: &mut Stk) -> ParseResult<ApiConfig> {
1407 let mut config = ApiConfig::default();
1408 loop {
1409 match self.peek_kind() {
1410 t!("PERMISSIONS") => {
1411 self.pop_peek();
1412 config.permissions = self.parse_permission_value(stk).await?;
1413 }
1414 t!("MIDDLEWARE") => {
1415 self.pop_peek();
1416 let mut middleware = Vec::new();
1417 loop {
1418 let name = self.parse_function_name().await?.to_string();
1419 expected!(self, t!("("));
1420 let args = self.parse_function_args(stk).await?;
1421 middleware.push(Middleware { name, args });
1422 if !self.eat(t!(",")) {
1423 break;
1424 }
1425 }
1426 config.middleware = middleware;
1427 }
1428 _ => {
1429 break;
1430 }
1431 }
1432 }
1433 Ok(config)
1434 }
1435 fn parse_graphql_config(&mut self) -> ParseResult<GraphQLConfig> {
1436 use graphql::{FunctionsConfig, IntrospectionConfig, TablesConfig};
1437 let mut tmp_tables = Option::<TablesConfig>::None;
1438 let mut tmp_fncs = Option::<FunctionsConfig>::None;
1439 let mut tmp_depth = Option::<u32>::None;
1440 let mut tmp_complexity = Option::<u32>::None;
1441 let mut tmp_introspection = Option::<IntrospectionConfig>::None;
1442 loop {
1443 match self.peek_kind() {
1444 t!("NONE") => {
1445 self.pop_peek();
1446 tmp_tables = Some(TablesConfig::None);
1447 tmp_fncs = Some(FunctionsConfig::None);
1448 }
1449 t!("AUTO") => {
1450 self.pop_peek();
1451 tmp_tables = Some(TablesConfig::Auto);
1452 tmp_fncs = Some(FunctionsConfig::Auto);
1453 }
1454 t!("TABLES") => {
1455 self.pop_peek();
1456 let next = self.next();
1457 match next.kind {
1458 t!("INCLUDE") => {
1459 tmp_tables =
1460 Some(TablesConfig::Include(self.parse_graphql_table_configs()?));
1461 }
1462 t!("EXCLUDE") => {
1463 tmp_tables =
1464 Some(TablesConfig::Exclude(self.parse_graphql_table_configs()?));
1465 }
1466 t!("NONE") => {
1467 tmp_tables = Some(TablesConfig::None);
1468 }
1469 t!("AUTO") => {
1470 tmp_tables = Some(TablesConfig::Auto);
1471 }
1472 _ => {
1473 unexpected!(self, next, "`NONE`, `AUTO`, `INCLUDE` or `EXCLUDE`")
1474 }
1475 }
1476 }
1477 t!("FUNCTIONS") => {
1478 self.pop_peek();
1479 let next = self.next();
1480 match next.kind {
1481 t!("NONE") => {
1482 tmp_fncs = Some(FunctionsConfig::None);
1483 }
1484 t!("AUTO") => {
1485 tmp_fncs = Some(FunctionsConfig::Auto);
1486 }
1487 _ => unexpected!(self, next, "`NONE`, `AUTO`"),
1488 }
1489 }
1490 TokenKind::Identifier => {
1491 let token = self.peek();
1492 let ident = self.span_str(token.span);
1493 if ident.eq_ignore_ascii_case("DEPTH") {
1494 self.pop_peek();
1495 tmp_depth = Some(self.next_token_value::<u32>()?);
1496 } else if ident.eq_ignore_ascii_case("COMPLEXITY") {
1497 self.pop_peek();
1498 tmp_complexity = Some(self.next_token_value::<u32>()?);
1499 } else if ident.eq_ignore_ascii_case("INTROSPECTION") {
1500 self.pop_peek();
1501 let next = self.next();
1502 match next.kind {
1503 t!("AUTO") => {
1504 tmp_introspection = Some(IntrospectionConfig::Auto);
1505 }
1506 t!("NONE") => {
1507 tmp_introspection = Some(IntrospectionConfig::None);
1508 }
1509 _ => unexpected!(self, next, "`AUTO` or `NONE`"),
1510 }
1511 } else {
1512 break;
1513 }
1514 }
1515 _ => break,
1516 }
1517 }
1518 Ok(GraphQLConfig {
1519 tables: tmp_tables.unwrap_or_default(),
1520 functions: tmp_fncs.unwrap_or_default(),
1521 depth_limit: tmp_depth,
1522 complexity_limit: tmp_complexity,
1523 introspection: tmp_introspection.unwrap_or_default(),
1524 })
1525 }
1526 fn parse_graphql_table_configs(&mut self) -> ParseResult<Vec<graphql::TableConfig>> {
1527 let mut acc = vec![];
1528 loop {
1529 match self.peek_kind() {
1530 x if Self::kind_is_identifier(x) => {
1531 let name = self.parse_ident()?;
1532 acc.push(TableConfig { name });
1533 }
1534 _ => unexpected!(self, self.next(), "a table config"),
1535 }
1536 if !self.eat(t!(",")) {
1537 break;
1538 }
1539 }
1540 Ok(acc)
1541 }
1542 pub fn parse_relation_schema(&mut self) -> ParseResult<table_type::Relation> {
1543 let mut res = table_type::Relation {
1544 from: Vec::new(),
1545 to: Vec::new(),
1546 enforced: false,
1547 };
1548 loop {
1549 match self.peek_kind() {
1550 t!("FROM") | t!("IN") => {
1551 self.pop_peek();
1552 res.from = self.parse_tables()?;
1553 }
1554 t!("TO") | t!("OUT") => {
1555 self.pop_peek();
1556 res.to = self.parse_tables()?;
1557 }
1558 _ => break,
1559 }
1560 }
1561 if self.eat(t!("ENFORCED")) {
1562 res.enforced = true;
1563 }
1564 Ok(res)
1565 }
1566 pub fn parse_tables(&mut self) -> ParseResult<Vec<String>> {
1567 let mut names = vec![self.parse_ident()?];
1568 while self.eat(t!("|")) {
1569 names.push(self.parse_ident()?);
1570 }
1571 Ok(names)
1572 }
1573 async fn parse_jwt(&mut self, stk: &mut Stk) -> ParseResult<access_type::JwtAccess> {
1574 let mut res = access_type::JwtAccess {
1575 issue: None,
1576 ..Default::default()
1577 };
1578 let mut iss = access_type::JwtAccessIssue::default();
1579 let peek = self.peek();
1580 match peek.kind {
1581 t!("ALGORITHM") => {
1582 self.pop_peek();
1583 let next = self.next();
1584 match next.kind {
1585 TokenKind::Algorithm(alg) => {
1586 let next = self.next();
1587 match next.kind {
1588 t!("KEY") => {
1589 let key = stk.run(|stk| self.parse_expr_field(stk)).await?;
1590 res.verify = access_type::JwtAccessVerify::Key(
1591 access_type::JwtAccessVerifyKey {
1592 alg,
1593 key: key.clone(),
1594 },
1595 );
1596 iss.alg = alg;
1597 if alg.is_symmetric() {
1598 iss.key = key;
1599 res.issue = Some(iss.clone());
1600 }
1601 }
1602 _ => unexpected!(self, next, "a key"),
1603 }
1604 }
1605 _ => unexpected!(self, next, "a valid algorithm"),
1606 }
1607 }
1608 t!("URL") => {
1609 self.pop_peek();
1610 let url = stk.run(|stk| self.parse_expr_field(stk)).await?;
1611 res.verify =
1612 access_type::JwtAccessVerify::Jwks(access_type::JwtAccessVerifyJwks { url });
1613 }
1614 _ => unexpected!(self, peek, "`ALGORITHM`, or `URL`"),
1615 }
1616 if self.eat(t!("WITH")) {
1617 expected!(self, t!("ISSUER"));
1618 loop {
1619 let peek = self.peek();
1620 match peek.kind {
1621 t!("ALGORITHM") => {
1622 self.pop_peek();
1623 let next = self.next();
1624 match next.kind {
1625 TokenKind::Algorithm(alg) => {
1626 if let JwtAccessVerify::Key(ref ver) = res.verify
1627 && alg != ver.alg
1628 {
1629 unexpected!(
1630 self,
1631 next,
1632 "a compatible algorithm or no algorithm"
1633 );
1634 }
1635 iss.alg = alg;
1636 }
1637 _ => unexpected!(self, next, "a valid algorithm"),
1638 }
1639 }
1640 t!("KEY") => {
1641 self.pop_peek();
1642 iss.key = stk.run(|stk| self.parse_expr_field(stk)).await?;
1643 }
1644 _ => break,
1645 }
1646 }
1647 res.issue = Some(iss);
1648 }
1649 Ok(res)
1650 }
1651}