Skip to main content

surql_parser/upstream/syn/parser/stmt/
alter.rs

1use crate::upstream::sql::TableType;
2use crate::upstream::sql::statements::alter::field::AlterDefault;
3use crate::upstream::sql::statements::alter::{
4	AlterDatabaseStatement, AlterFieldStatement, AlterIndexStatement, AlterKind,
5	AlterNamespaceStatement, AlterSequenceStatement, AlterSystemStatement,
6};
7use crate::upstream::sql::statements::{AlterStatement, AlterTableStatement};
8use crate::upstream::syn::parser::mac::{expected, unexpected};
9use crate::upstream::syn::parser::{ParseResult, Parser};
10use crate::upstream::syn::token::{TokenKind, t};
11use reblessive::Stk;
12impl Parser<'_> {
13	pub async fn parse_alter_stmt(&mut self, stk: &mut Stk) -> ParseResult<AlterStatement> {
14		let next = self.next();
15		match next.kind {
16			t!("SYSTEM") => self
17				.parse_alter_system(stk)
18				.await
19				.map(AlterStatement::System),
20			t!("NAMESPACE") => self
21				.parse_alter_namespace()
22				.await
23				.map(AlterStatement::Namespace),
24			t!("DATABASE") => self
25				.parse_alter_database()
26				.await
27				.map(AlterStatement::Database),
28			t!("TABLE") => self.parse_alter_table(stk).await.map(AlterStatement::Table),
29			t!("INDEX") => self.parse_alter_index().await.map(AlterStatement::Index),
30			t!("FIELD") => self.parse_alter_field(stk).await.map(AlterStatement::Field),
31			t!("SEQUENCE") => self
32				.parse_alter_sequence(stk)
33				.await
34				.map(AlterStatement::Sequence),
35			_ => unexpected!(self, next, "a alter statement keyword"),
36		}
37	}
38	pub async fn parse_alter_system(&mut self, stk: &mut Stk) -> ParseResult<AlterSystemStatement> {
39		let mut res = AlterSystemStatement::default();
40		loop {
41			match self.peek_kind() {
42				t!("DROP") => {
43					self.pop_peek();
44					let peek = self.peek();
45					match peek.kind {
46						TokenKind::Identifier => {
47							let name = self.parse_ident()?;
48							match name.as_str() {
49								"QUERY_TIMEOUT" => {
50									res.query_timeout = AlterKind::Drop;
51								}
52								_ => unexpected!(self, peek, "`QUERY_TIMEOUT`"),
53							}
54						}
55						_ => unexpected!(self, peek, "`QUERY_TIMEOUT`"),
56					}
57				}
58				t!("COMPACT") => {
59					self.pop_peek();
60					res.compact = true;
61				}
62				TokenKind::Identifier => {
63					let peek = self.peek();
64					let name = self.parse_ident()?;
65					match name.as_str() {
66						"QUERY_TIMEOUT" => {
67							let duration = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
68							res.query_timeout = AlterKind::Set(duration);
69						}
70						_ => unexpected!(self, peek, "`QUERY_TIMEOUT`"),
71					}
72				}
73				_ => break,
74			}
75		}
76		if !res.compact && matches!(res.query_timeout, AlterKind::None) {
77			unexpected!(self, self.peek(), "`COMPACT`, `DROP` or `QUERY_TIMEOUT`")
78		}
79		Ok(res)
80	}
81	pub async fn parse_alter_namespace(&mut self) -> ParseResult<AlterNamespaceStatement> {
82		if !self.eat(t!("COMPACT")) {
83			unexpected!(self, self.peek(), "`COMPACT`")
84		}
85		Ok(AlterNamespaceStatement { compact: true })
86	}
87	pub async fn parse_alter_database(&mut self) -> ParseResult<AlterDatabaseStatement> {
88		if !self.eat(t!("COMPACT")) {
89			unexpected!(self, self.peek(), "`COMPACT`")
90		}
91		Ok(AlterDatabaseStatement { compact: true })
92	}
93	pub async fn parse_alter_table(&mut self, stk: &mut Stk) -> ParseResult<AlterTableStatement> {
94		let if_exists = if self.eat(t!("IF")) {
95			expected!(self, t!("EXISTS"));
96			true
97		} else {
98			false
99		};
100		let name = self.parse_ident()?;
101		let mut res = AlterTableStatement {
102			name,
103			if_exists,
104			..Default::default()
105		};
106		loop {
107			match self.peek_kind() {
108				t!("DROP") => {
109					self.pop_peek();
110					let peek = self.peek();
111					match peek.kind {
112						t!("COMMENT") => {
113							self.pop_peek();
114							res.comment = AlterKind::Drop;
115						}
116						t!("CHANGEFEED") => {
117							self.pop_peek();
118							res.changefeed = AlterKind::Drop;
119						}
120						_ => unexpected!(self, peek, "`COMMENT` or `CHANGEFEED`"),
121					}
122				}
123				t!("COMMENT") => {
124					self.pop_peek();
125					res.comment = AlterKind::Set(self.parse_string_lit()?);
126				}
127				t!("COMPACT") => {
128					self.pop_peek();
129					res.compact = true;
130				}
131				t!("TYPE") => {
132					self.pop_peek();
133					let peek = self.peek();
134					match peek.kind {
135						t!("NORMAL") => {
136							self.pop_peek();
137							res.kind = Some(TableType::Normal);
138						}
139						t!("RELATION") => {
140							self.pop_peek();
141							res.kind = Some(TableType::Relation(self.parse_relation_schema()?));
142						}
143						t!("ANY") => {
144							self.pop_peek();
145							res.kind = Some(TableType::Any);
146						}
147						_ => unexpected!(self, peek, "`NORMAL`, `RELATION`, or `ANY`"),
148					}
149				}
150				t!("SCHEMALESS") => {
151					self.pop_peek();
152					res.schemafull = AlterKind::Drop;
153				}
154				t!("SCHEMAFULL") => {
155					self.pop_peek();
156					res.schemafull = AlterKind::Set(());
157				}
158				t!("PERMISSIONS") => {
159					self.pop_peek();
160					res.permissions = Some(stk.run(|stk| self.parse_permission(stk, false)).await?);
161				}
162				t!("CHANGEFEED") => {
163					self.pop_peek();
164					res.changefeed = AlterKind::Set(self.parse_changefeed()?);
165				}
166				_ => break,
167			}
168		}
169		Ok(res)
170	}
171	pub async fn parse_alter_index(&mut self) -> ParseResult<AlterIndexStatement> {
172		let if_exists = if self.eat(t!("IF")) {
173			expected!(self, t!("EXISTS"));
174			true
175		} else {
176			false
177		};
178		let name = self.parse_ident()?;
179		expected!(self, t!("ON"));
180		self.eat(t!("TABLE"));
181		let table = self.parse_ident()?;
182		let mut res = AlterIndexStatement {
183			name,
184			table,
185			if_exists,
186			..Default::default()
187		};
188		loop {
189			match self.peek_kind() {
190				t!("DROP") => {
191					self.pop_peek();
192					let peek = self.peek();
193					match peek.kind {
194						t!("COMMENT") => {
195							self.pop_peek();
196							res.comment = AlterKind::Drop;
197						}
198						_ => unexpected!(self, peek, "`COMMENT`"),
199					}
200				}
201				t!("COMMENT") => {
202					self.pop_peek();
203					res.comment = AlterKind::Set(self.parse_string_lit()?);
204				}
205				t!("PREPARE") => {
206					self.pop_peek();
207					self.eat(t!("REMOVE"));
208					res.prepare_remove = true;
209				}
210				_ => break,
211			}
212		}
213		if !res.prepare_remove && matches!(res.comment, AlterKind::None) {
214			unexpected!(self, self.peek(), "`PREPARE`, `DROP` or `COMMENT`")
215		}
216		Ok(res)
217	}
218	pub async fn parse_alter_field(&mut self, stk: &mut Stk) -> ParseResult<AlterFieldStatement> {
219		let if_exists = if self.eat(t!("IF")) {
220			expected!(self, t!("EXISTS"));
221			true
222		} else {
223			false
224		};
225		let name = self.parse_local_idiom()?;
226		expected!(self, t!("ON"));
227		self.eat(t!("TABLE"));
228		let what = self.parse_ident()?;
229		let mut res = AlterFieldStatement {
230			name,
231			what,
232			if_exists,
233			..Default::default()
234		};
235		loop {
236			match self.peek_kind() {
237				t!("DROP") => {
238					self.pop_peek();
239					let peek = self.peek();
240					match peek.kind {
241						t!("TYPE") => {
242							self.pop_peek();
243							res.kind = AlterKind::Drop;
244						}
245						t!("FLEXIBLE") => {
246							self.pop_peek();
247							res.flexible = AlterKind::Drop;
248						}
249						t!("READONLY") => {
250							self.pop_peek();
251							res.readonly = AlterKind::Drop;
252						}
253						t!("VALUE") => {
254							self.pop_peek();
255							res.value = AlterKind::Drop;
256						}
257						t!("ASSERT") => {
258							self.pop_peek();
259							res.assert = AlterKind::Drop;
260						}
261						t!("DEFAULT") => {
262							self.pop_peek();
263							res.default = AlterDefault::Drop;
264						}
265						t!("COMMENT") => {
266							self.pop_peek();
267							res.comment = AlterKind::Drop;
268						}
269						t!("REFERENCE") => {
270							self.pop_peek();
271							res.reference = AlterKind::Drop;
272						}
273						_ => {
274							unexpected!(
275								self,
276								peek,
277								"`FLEXIBLE`, `TYPE`, `READONLY`, `VALUE`, `ASSERT`, `DEFAULT`, `COMMENT`, or `REFERENCE`"
278							)
279						}
280					}
281				}
282				t!("TYPE") => {
283					self.pop_peek();
284					res.kind = AlterKind::Set(stk.run(|stk| self.parse_inner_kind(stk)).await?);
285				}
286				t!("FLEXIBLE") => {
287					self.pop_peek();
288					res.flexible = AlterKind::Set(());
289				}
290				t!("READONLY") => {
291					self.pop_peek();
292					res.readonly = AlterKind::Set(());
293				}
294				t!("VALUE") => {
295					self.pop_peek();
296					res.value = AlterKind::Set(stk.run(|stk| self.parse_expr_field(stk)).await?);
297				}
298				t!("ASSERT") => {
299					self.pop_peek();
300					res.assert = AlterKind::Set(stk.run(|stk| self.parse_expr_field(stk)).await?);
301				}
302				t!("DEFAULT") => {
303					self.pop_peek();
304					if self.eat(t!("ALWAYS")) {
305						res.default =
306							AlterDefault::Always(stk.run(|stk| self.parse_expr_field(stk)).await?);
307					} else {
308						res.default =
309							AlterDefault::Set(stk.run(|stk| self.parse_expr_field(stk)).await?);
310					}
311				}
312				t!("PERMISSIONS") => {
313					self.pop_peek();
314					res.permissions = Some(stk.run(|stk| self.parse_permission(stk, false)).await?);
315				}
316				t!("COMMENT") => {
317					self.pop_peek();
318					res.comment = AlterKind::Set(self.parse_string_lit()?);
319				}
320				t!("REFERENCE") => {
321					self.pop_peek();
322					res.reference = AlterKind::Set(self.parse_reference(stk).await?);
323				}
324				_ => break,
325			}
326		}
327		Ok(res)
328	}
329	pub async fn parse_alter_sequence(
330		&mut self,
331		stk: &mut Stk,
332	) -> ParseResult<AlterSequenceStatement> {
333		let if_exists = if self.eat(t!("IF")) {
334			expected!(self, t!("EXISTS"));
335			true
336		} else {
337			false
338		};
339		let name = self.parse_ident()?;
340		let mut res = AlterSequenceStatement {
341			name,
342			if_exists,
343			..Default::default()
344		};
345		if self.eat(t!("TIMEOUT")) {
346			res.timeout = Some(stk.run(|stk| self.parse_expr_field(stk)).await?);
347		}
348		Ok(res)
349	}
350}