surrealdb_core/syn/parser/stmt/
define.rs

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