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!("SEARCH") => {
1056					self.pop_peek();
1057					let mut analyzer: Option<Ident> = None;
1058					let mut scoring = None;
1059					let mut doc_ids_order = 100;
1060					let mut doc_lengths_order = 100;
1061					let mut postings_order = 100;
1062					let mut terms_order = 100;
1063					let mut doc_ids_cache = 100;
1064					let mut doc_lengths_cache = 100;
1065					let mut postings_cache = 100;
1066					let mut terms_cache = 100;
1067					let mut hl = false;
1068
1069					loop {
1070						match self.peek_kind() {
1071							t!("ANALYZER") => {
1072								self.pop_peek();
1073								analyzer = Some(self.next_token_value()).transpose()?;
1074							}
1075							t!("VS") => {
1076								self.pop_peek();
1077								scoring = Some(Scoring::Vs);
1078							}
1079							t!("BM25") => {
1080								self.pop_peek();
1081								if self.eat(t!("(")) {
1082									let open = self.last_span();
1083									let k1 = self.next_token_value()?;
1084									expected!(self, t!(","));
1085									let b = self.next_token_value()?;
1086									self.expect_closing_delimiter(t!(")"), open)?;
1087									scoring = Some(Scoring::Bm {
1088										k1,
1089										b,
1090									})
1091								} else {
1092									scoring = Some(Default::default());
1093								};
1094							}
1095							t!("DOC_IDS_ORDER") => {
1096								self.pop_peek();
1097								doc_ids_order = self.next_token_value()?;
1098							}
1099							t!("DOC_LENGTHS_ORDER") => {
1100								self.pop_peek();
1101								doc_lengths_order = self.next_token_value()?;
1102							}
1103							t!("POSTINGS_ORDER") => {
1104								self.pop_peek();
1105								postings_order = self.next_token_value()?;
1106							}
1107							t!("TERMS_ORDER") => {
1108								self.pop_peek();
1109								terms_order = self.next_token_value()?;
1110							}
1111							t!("DOC_IDS_CACHE") => {
1112								self.pop_peek();
1113								doc_ids_cache = self.next_token_value()?;
1114							}
1115							t!("DOC_LENGTHS_CACHE") => {
1116								self.pop_peek();
1117								doc_lengths_cache = self.next_token_value()?;
1118							}
1119							t!("POSTINGS_CACHE") => {
1120								self.pop_peek();
1121								postings_cache = self.next_token_value()?;
1122							}
1123							t!("TERMS_CACHE") => {
1124								self.pop_peek();
1125								terms_cache = self.next_token_value()?;
1126							}
1127							t!("HIGHLIGHTS") => {
1128								self.pop_peek();
1129								hl = true;
1130							}
1131							_ => break,
1132						}
1133					}
1134
1135					res.index = Index::Search(crate::sql::index::SearchParams {
1136						az: analyzer.unwrap_or_else(|| Ident::from("like")),
1137						sc: scoring.unwrap_or_else(Default::default),
1138						hl,
1139						doc_ids_order,
1140						doc_lengths_order,
1141						postings_order,
1142						terms_order,
1143						doc_ids_cache,
1144						doc_lengths_cache,
1145						postings_cache,
1146						terms_cache,
1147					});
1148				}
1149				t!("MTREE") => {
1150					self.pop_peek();
1151					expected!(self, t!("DIMENSION"));
1152					let dimension = self.next_token_value()?;
1153					let mut distance = Distance::Euclidean;
1154					let mut vector_type = VectorType::F64;
1155					let mut capacity = 40;
1156					let mut doc_ids_cache = 100;
1157					let mut doc_ids_order = 100;
1158					let mut mtree_cache = 100;
1159					loop {
1160						match self.peek_kind() {
1161							t!("DISTANCE") => {
1162								self.pop_peek();
1163								distance = self.parse_distance()?
1164							}
1165							t!("TYPE") => {
1166								self.pop_peek();
1167								vector_type = self.parse_vector_type()?
1168							}
1169							t!("CAPACITY") => {
1170								self.pop_peek();
1171								capacity = self.next_token_value()?
1172							}
1173							t!("DOC_IDS_CACHE") => {
1174								self.pop_peek();
1175								doc_ids_cache = self.next_token_value()?
1176							}
1177							t!("DOC_IDS_ORDER") => {
1178								self.pop_peek();
1179								doc_ids_order = self.next_token_value()?
1180							}
1181							t!("MTREE_CACHE") => {
1182								self.pop_peek();
1183								mtree_cache = self.next_token_value()?
1184							}
1185							_ => break,
1186						}
1187					}
1188					res.index = Index::MTree(crate::sql::index::MTreeParams::new(
1189						dimension,
1190						distance,
1191						vector_type,
1192						capacity,
1193						doc_ids_order,
1194						doc_ids_cache,
1195						mtree_cache,
1196					))
1197				}
1198				t!("HNSW") => {
1199					self.pop_peek();
1200					expected!(self, t!("DIMENSION"));
1201					let dimension = self.next_token_value()?;
1202					let mut distance = Distance::Euclidean;
1203					let mut vector_type = VectorType::F64;
1204					let mut m = None;
1205					let mut m0 = None;
1206					let mut ml = None;
1207					let mut ef_construction = 150;
1208					let mut extend_candidates = false;
1209					let mut keep_pruned_connections = false;
1210					loop {
1211						match self.peek_kind() {
1212							t!("DISTANCE") => {
1213								self.pop_peek();
1214								distance = self.parse_distance()?;
1215							}
1216							t!("TYPE") => {
1217								self.pop_peek();
1218								vector_type = self.parse_vector_type()?;
1219							}
1220							t!("LM") => {
1221								self.pop_peek();
1222								ml = Some(self.next_token_value()?);
1223							}
1224							t!("M0") => {
1225								self.pop_peek();
1226								m0 = Some(self.next_token_value()?);
1227							}
1228							t!("M") => {
1229								self.pop_peek();
1230								m = Some(self.next_token_value()?);
1231							}
1232							t!("EFC") => {
1233								self.pop_peek();
1234								ef_construction = self.next_token_value()?;
1235							}
1236							t!("EXTEND_CANDIDATES") => {
1237								self.pop_peek();
1238								extend_candidates = true;
1239							}
1240							t!("KEEP_PRUNED_CONNECTIONS") => {
1241								self.pop_peek();
1242								keep_pruned_connections = true;
1243							}
1244							_ => {
1245								break;
1246							}
1247						}
1248					}
1249
1250					let m = m.unwrap_or(12);
1251					let m0 = m0.unwrap_or(m * 2);
1252					let ml = ml.unwrap_or(1.0 / (m as f64).ln()).into();
1253					res.index = Index::Hnsw(HnswParams::new(
1254						dimension,
1255						distance,
1256						vector_type,
1257						m,
1258						m0,
1259						ml,
1260						ef_construction,
1261						extend_candidates,
1262						keep_pruned_connections,
1263					));
1264				}
1265				t!("CONCURRENTLY") => {
1266					self.pop_peek();
1267					res.concurrently = true;
1268				}
1269				t!("COMMENT") => {
1270					self.pop_peek();
1271					res.comment = Some(self.next_token_value()?);
1272				}
1273				_ => break,
1274			}
1275		}
1276
1277		Ok(res)
1278	}
1279
1280	pub fn parse_define_analyzer(&mut self) -> ParseResult<DefineAnalyzerStatement> {
1281		let (if_not_exists, overwrite) = if self.eat(t!("IF")) {
1282			expected!(self, t!("NOT"));
1283			expected!(self, t!("EXISTS"));
1284			(true, false)
1285		} else if self.eat(t!("OVERWRITE")) {
1286			(false, true)
1287		} else {
1288			(false, false)
1289		};
1290		let name = self.next_token_value()?;
1291		let mut res = DefineAnalyzerStatement {
1292			name,
1293
1294			function: None,
1295			tokenizers: None,
1296			filters: None,
1297			comment: None,
1298
1299			if_not_exists,
1300			overwrite,
1301		};
1302		loop {
1303			match self.peek_kind() {
1304				t!("FILTERS") => {
1305					self.pop_peek();
1306					let mut filters = Vec::new();
1307					loop {
1308						let next = self.next();
1309						match next.kind {
1310							t!("ASCII") => {
1311								filters.push(Filter::Ascii);
1312							}
1313							t!("LOWERCASE") => {
1314								filters.push(Filter::Lowercase);
1315							}
1316							t!("UPPERCASE") => {
1317								filters.push(Filter::Uppercase);
1318							}
1319							t!("EDGENGRAM") => {
1320								let open_span = expected!(self, t!("(")).span;
1321								let a = self.next_token_value()?;
1322								expected!(self, t!(","));
1323								let b = self.next_token_value()?;
1324								self.expect_closing_delimiter(t!(")"), open_span)?;
1325								filters.push(Filter::EdgeNgram(a, b));
1326							}
1327							t!("NGRAM") => {
1328								let open_span = expected!(self, t!("(")).span;
1329								let a = self.next_token_value()?;
1330								expected!(self, t!(","));
1331								let b = self.next_token_value()?;
1332								self.expect_closing_delimiter(t!(")"), open_span)?;
1333								filters.push(Filter::Ngram(a, b));
1334							}
1335							t!("SNOWBALL") => {
1336								let open_span = expected!(self, t!("(")).span;
1337								let language = self.next_token_value()?;
1338								self.expect_closing_delimiter(t!(")"), open_span)?;
1339								filters.push(Filter::Snowball(language))
1340							}
1341							t!("MAPPER") => {
1342								let open_span = expected!(self, t!("(")).span;
1343								let path: Strand = self.next_token_value()?;
1344								self.expect_closing_delimiter(t!(")"), open_span)?;
1345								filters.push(Filter::Mapper(path.into()))
1346							}
1347							_ => unexpected!(self, next, "a filter"),
1348						}
1349						if !self.eat(t!(",")) {
1350							break;
1351						}
1352					}
1353					res.filters = Some(filters);
1354				}
1355				t!("TOKENIZERS") => {
1356					self.pop_peek();
1357					let mut tokenizers = Vec::new();
1358
1359					loop {
1360						let next = self.next();
1361						let tokenizer = match next.kind {
1362							t!("BLANK") => Tokenizer::Blank,
1363							t!("CAMEL") => Tokenizer::Camel,
1364							t!("CLASS") => Tokenizer::Class,
1365							t!("PUNCT") => Tokenizer::Punct,
1366							_ => unexpected!(self, next, "a tokenizer"),
1367						};
1368						tokenizers.push(tokenizer);
1369						if !self.eat(t!(",")) {
1370							break;
1371						}
1372					}
1373					res.tokenizers = Some(tokenizers);
1374				}
1375
1376				t!("FUNCTION") => {
1377					self.pop_peek();
1378					expected!(self, t!("fn"));
1379					expected!(self, t!("::"));
1380					let mut ident = self.next_token_value::<Ident>()?;
1381					while self.eat(t!("::")) {
1382						let value = self.next_token_value::<Ident>()?;
1383						ident.0.push_str("::");
1384						ident.0.push_str(&value);
1385					}
1386					res.function = Some(ident);
1387				}
1388				t!("COMMENT") => {
1389					self.pop_peek();
1390					res.comment = Some(self.next_token_value()?);
1391				}
1392				_ => break,
1393			}
1394		}
1395		Ok(res)
1396	}
1397
1398	pub async fn parse_define_config(
1399		&mut self,
1400		stk: &mut Stk,
1401	) -> ParseResult<DefineConfigStatement> {
1402		let (if_not_exists, overwrite) = if self.eat(t!("IF")) {
1403			expected!(self, t!("NOT"));
1404			expected!(self, t!("EXISTS"));
1405			(true, false)
1406		} else if self.eat(t!("OVERWRITE")) {
1407			(false, true)
1408		} else {
1409			(false, false)
1410		};
1411
1412		let next = self.next();
1413		let inner = match next.kind {
1414			t!("API") => self.parse_api_config(stk).await.map(ConfigInner::Api)?,
1415			t!("GRAPHQL") => self.parse_graphql_config().map(ConfigInner::GraphQL)?,
1416			_ => unexpected!(self, next, "a type of config"),
1417		};
1418
1419		Ok(DefineConfigStatement {
1420			inner,
1421			if_not_exists,
1422			overwrite,
1423		})
1424	}
1425
1426	pub async fn parse_api_config(&mut self, stk: &mut Stk) -> ParseResult<ApiConfig> {
1427		let mut config = ApiConfig::default();
1428		loop {
1429			match self.peek_kind() {
1430				t!("PERMISSIONS") => {
1431					self.pop_peek();
1432					config.permissions = Some(self.parse_permission_value(stk).await?);
1433				}
1434				t!("MIDDLEWARE") => {
1435					self.pop_peek();
1436
1437					let mut middleware: Vec<(String, Vec<Value>)> = Vec::new();
1438					// let mut parsed_custom = false;
1439
1440					loop {
1441						let mut name = match self.peek_kind() {
1442							t!("API") => {
1443								// if parsed_custom {
1444								// 	bail!("Cannot specify builtin middlewares after custom middlewares");
1445								// }
1446
1447								self.pop_peek();
1448								expected!(self, t!("::"));
1449								"api::".to_string()
1450							}
1451							t!("fn") => {
1452								bail!("Custom middlewares are not yet supported")
1453							}
1454							_ => {
1455								break;
1456							}
1457						};
1458
1459						let part = self.next_token_value::<Ident>()?;
1460						name.push_str(part.0.to_lowercase().as_str());
1461
1462						while self.eat(t!("::")) {
1463							let part = self.next_token_value::<Ident>()?;
1464							name.push_str("::");
1465							name.push_str(part.0.to_lowercase().as_str());
1466						}
1467
1468						expected!(self, t!("("));
1469						let args = self.parse_function_args(stk).await?;
1470
1471						middleware.push((name, args));
1472
1473						if !self.eat(t!(",")) {
1474							break;
1475						}
1476					}
1477
1478					config.middleware = Some(RequestMiddleware(middleware));
1479				}
1480				_ => {
1481					break;
1482				}
1483			}
1484		}
1485		Ok(config)
1486	}
1487
1488	fn parse_graphql_config(&mut self) -> ParseResult<GraphQLConfig> {
1489		use graphql::{FunctionsConfig, TablesConfig};
1490		let mut tmp_tables = Option::<TablesConfig>::None;
1491		let mut tmp_fncs = Option::<FunctionsConfig>::None;
1492		loop {
1493			match self.peek_kind() {
1494				t!("NONE") => {
1495					self.pop_peek();
1496					tmp_tables = Some(TablesConfig::None);
1497					tmp_fncs = Some(FunctionsConfig::None);
1498				}
1499				t!("AUTO") => {
1500					self.pop_peek();
1501					tmp_tables = Some(TablesConfig::Auto);
1502					tmp_fncs = Some(FunctionsConfig::Auto);
1503				}
1504				t!("TABLES") => {
1505					self.pop_peek();
1506
1507					let next = self.next();
1508					match next.kind {
1509						t!("INCLUDE") => {
1510							tmp_tables =
1511								Some(TablesConfig::Include(self.parse_graphql_table_configs()?))
1512						}
1513						t!("EXCLUDE") => {
1514							tmp_tables =
1515								Some(TablesConfig::Include(self.parse_graphql_table_configs()?))
1516						}
1517						t!("NONE") => {
1518							tmp_tables = Some(TablesConfig::None);
1519						}
1520						t!("AUTO") => {
1521							tmp_tables = Some(TablesConfig::Auto);
1522						}
1523						_ => unexpected!(self, next, "`NONE`, `AUTO`, `INCLUDE` or `EXCLUDE`"),
1524					}
1525				}
1526				t!("FUNCTIONS") => {
1527					self.pop_peek();
1528
1529					let next = self.next();
1530					match next.kind {
1531						t!("INCLUDE") => {}
1532						t!("EXCLUDE") => {}
1533						t!("NONE") => {
1534							tmp_fncs = Some(FunctionsConfig::None);
1535						}
1536						t!("AUTO") => {
1537							tmp_fncs = Some(FunctionsConfig::Auto);
1538						}
1539						_ => unexpected!(self, next, "`NONE`, `AUTO`, `INCLUDE` or `EXCLUDE`"),
1540					}
1541				}
1542				_ => break,
1543			}
1544		}
1545
1546		Ok(GraphQLConfig {
1547			tables: tmp_tables.unwrap_or_default(),
1548			functions: tmp_fncs.unwrap_or_default(),
1549		})
1550	}
1551
1552	fn parse_graphql_table_configs(&mut self) -> ParseResult<Vec<graphql::TableConfig>> {
1553		let mut acc = vec![];
1554		loop {
1555			match self.peek_kind() {
1556				x if Self::kind_is_identifier(x) => {
1557					let name: Ident = self.next_token_value()?;
1558					acc.push(TableConfig {
1559						name: name.0,
1560					});
1561				}
1562				_ => unexpected!(self, self.next(), "a table config"),
1563			}
1564			if !self.eat(t!(",")) {
1565				break;
1566			}
1567		}
1568		Ok(acc)
1569	}
1570
1571	pub fn parse_relation_schema(&mut self) -> ParseResult<table_type::Relation> {
1572		let mut res = table_type::Relation {
1573			from: None,
1574			to: None,
1575			enforced: false,
1576		};
1577		loop {
1578			match self.peek_kind() {
1579				t!("FROM") | t!("IN") => {
1580					self.pop_peek();
1581					let from = self.parse_tables()?;
1582					res.from = Some(from);
1583				}
1584				t!("TO") | t!("OUT") => {
1585					self.pop_peek();
1586					let to = self.parse_tables()?;
1587					res.to = Some(to);
1588				}
1589				_ => break,
1590			}
1591		}
1592		if self.eat(t!("ENFORCED")) {
1593			res.enforced = true;
1594		}
1595		Ok(res)
1596	}
1597
1598	pub fn parse_tables(&mut self) -> ParseResult<Kind> {
1599		let mut names = vec![self.next_token_value()?];
1600		while self.eat(t!("|")) {
1601			names.push(self.next_token_value()?);
1602		}
1603		Ok(Kind::Record(names))
1604	}
1605
1606	pub fn parse_jwt(&mut self) -> ParseResult<access_type::JwtAccess> {
1607		let mut res = access_type::JwtAccess {
1608			// By default, a JWT access method is only used to verify.
1609			issue: None,
1610			..Default::default()
1611		};
1612
1613		let mut iss = access_type::JwtAccessIssue {
1614			..Default::default()
1615		};
1616
1617		let peek = self.peek();
1618		match peek.kind {
1619			t!("ALGORITHM") => {
1620				self.pop_peek();
1621				let next = self.next();
1622				match next.kind {
1623					TokenKind::Algorithm(alg) => {
1624						let next = self.next();
1625						match next.kind {
1626							t!("KEY") => {
1627								let key = self.next_token_value::<Strand>()?.0;
1628								res.verify = access_type::JwtAccessVerify::Key(
1629									access_type::JwtAccessVerifyKey {
1630										alg,
1631										key: key.to_owned(),
1632									},
1633								);
1634
1635								// Currently, issuer and verifier must use the same algorithm.
1636								iss.alg = alg;
1637
1638								// If the algorithm is symmetric, the issuer and verifier keys are the same.
1639								// For asymmetric algorithms, the key needs to be explicitly defined.
1640								if alg.is_symmetric() {
1641									iss.key = key;
1642									// Since all the issuer data is known, it can already be assigned.
1643									// Cloning allows updating the original with any explicit issuer data.
1644									res.issue = Some(iss.clone());
1645								}
1646							}
1647							_ => unexpected!(self, next, "a key"),
1648						}
1649					}
1650					_ => unexpected!(self, next, "a valid algorithm"),
1651				}
1652			}
1653			t!("URL") => {
1654				self.pop_peek();
1655				let url = self.next_token_value::<Strand>()?.0;
1656				res.verify = access_type::JwtAccessVerify::Jwks(access_type::JwtAccessVerifyJwks {
1657					url,
1658				});
1659			}
1660			_ => unexpected!(self, peek, "`ALGORITHM`, or `URL`"),
1661		}
1662
1663		if self.eat(t!("WITH")) {
1664			expected!(self, t!("ISSUER"));
1665			loop {
1666				let peek = self.peek();
1667				match peek.kind {
1668					t!("ALGORITHM") => {
1669						self.pop_peek();
1670						let next = self.next();
1671						match next.kind {
1672							TokenKind::Algorithm(alg) => {
1673								// If an algorithm is already defined, a different value is not expected.
1674								if let JwtAccessVerify::Key(ref ver) = res.verify {
1675									if alg != ver.alg {
1676										unexpected!(
1677											self,
1678											next,
1679											"a compatible algorithm or no algorithm"
1680										);
1681									}
1682								}
1683								iss.alg = alg;
1684							}
1685							_ => unexpected!(self, next, "a valid algorithm"),
1686						}
1687					}
1688					t!("KEY") => {
1689						self.pop_peek();
1690						let key = self.next_token_value::<Strand>()?.0;
1691						// If the algorithm is symmetric and a key is already defined, a different key is not expected.
1692						if let JwtAccessVerify::Key(ref ver) = res.verify {
1693							if ver.alg.is_symmetric() && key != ver.key {
1694								unexpected!(self, peek, "a symmetric key or no key");
1695							}
1696						}
1697						iss.key = key;
1698					}
1699					_ => break,
1700				}
1701			}
1702			res.issue = Some(iss);
1703		}
1704
1705		Ok(res)
1706	}
1707}