1use crate::storage::query::ast::{
35 AlterUserAttribute, AlterUserStmt, GrantObject, GrantObjectKind, GrantPrincipalRef, GrantStmt,
36 PolicyPrincipalRef, PolicyResourceRef, PolicyUserRef, QueryExpr, RevokeStmt,
37};
38use crate::storage::query::lexer::Token;
39use crate::storage::query::parser::{ParseError, Parser};
40
41impl<'a> Parser<'a> {
42 pub fn parse_grant_statement(&mut self) -> Result<GrantStmt, ParseError> {
46 self.advance()?;
48
49 let (actions, all, columns) = self.parse_privilege_list()?;
50 self.expect(Token::On)?;
51 let object_kind = self.parse_grant_object_kind()?;
52 let objects = self.parse_grant_object_list(&object_kind)?;
53 self.expect(Token::To)?;
54 let principals = self.parse_grant_principal_list()?;
55
56 let with_grant_option = self.consume_grant_option_suffix()?;
57
58 Ok(GrantStmt {
59 actions,
60 columns,
61 object_kind,
62 objects,
63 principals,
64 with_grant_option,
65 all,
66 })
67 }
68
69 pub fn parse_revoke_statement(&mut self) -> Result<RevokeStmt, ParseError> {
72 self.advance()?;
74
75 let grant_option_for = self.consume_grant_option_for_prefix()?;
77
78 let (actions, all, columns) = self.parse_privilege_list()?;
79 self.expect(Token::On)?;
80 let object_kind = self.parse_grant_object_kind()?;
81 let objects = self.parse_grant_object_list(&object_kind)?;
82 self.expect(Token::From)?;
83 let principals = self.parse_grant_principal_list()?;
84
85 Ok(RevokeStmt {
86 actions,
87 columns,
88 object_kind,
89 objects,
90 principals,
91 grant_option_for,
92 all,
93 })
94 }
95
96 pub fn parse_alter_user_statement(&mut self) -> Result<AlterUserStmt, ParseError> {
99 if !self.consume_ident_ci("USER")? {
101 return Err(ParseError::expected(
102 vec!["USER"],
103 self.peek(),
104 self.position(),
105 ));
106 }
107 let (tenant, username) = self.parse_user_name()?;
108
109 let mut attributes = Vec::new();
110 loop {
111 if self.consume_ident_ci("VALID")? {
112 if !self.consume_ident_ci("UNTIL")? {
113 return Err(ParseError::expected(
114 vec!["UNTIL"],
115 self.peek(),
116 self.position(),
117 ));
118 }
119 let ts = self.parse_string()?;
120 attributes.push(AlterUserAttribute::ValidUntil(ts));
121 } else if self.consume_ident_ci("CONNECTION")? {
122 if !self.consume(&Token::Limit)? && !self.consume_ident_ci("LIMIT")? {
123 return Err(ParseError::expected(
124 vec!["LIMIT"],
125 self.peek(),
126 self.position(),
127 ));
128 }
129 let n = self.parse_integer()?;
130 attributes.push(AlterUserAttribute::ConnectionLimit(n));
131 } else if self.consume(&Token::Enable)? {
132 attributes.push(AlterUserAttribute::Enable);
133 } else if self.consume(&Token::Disable)? {
134 attributes.push(AlterUserAttribute::Disable);
135 } else if self.consume(&Token::Set)? {
136 if !self.consume_ident_ci("SEARCH_PATH")? {
138 return Err(ParseError::expected(
139 vec!["search_path"],
140 self.peek(),
141 self.position(),
142 ));
143 }
144 if !self.consume(&Token::Eq)? && !self.consume(&Token::To)? {
145 return Err(ParseError::expected(
146 vec!["="],
147 self.peek(),
148 self.position(),
149 ));
150 }
151 let value = self.parse_string()?;
152 attributes.push(AlterUserAttribute::SetSearchPath(value));
153 } else if self.consume(&Token::Add)? || self.consume_ident_ci("ADD")? {
154 if !self.consume(&Token::Group)? && !self.consume_ident_ci("GROUP")? {
155 return Err(ParseError::expected(
156 vec!["GROUP"],
157 self.peek(),
158 self.position(),
159 ));
160 }
161 let group = self.expect_ident()?;
162 attributes.push(AlterUserAttribute::AddGroup(group));
163 } else if self.consume(&Token::Drop)? || self.consume_ident_ci("DROP")? {
164 if !self.consume(&Token::Group)? && !self.consume_ident_ci("GROUP")? {
165 return Err(ParseError::expected(
166 vec!["GROUP"],
167 self.peek(),
168 self.position(),
169 ));
170 }
171 let group = self.expect_ident()?;
172 attributes.push(AlterUserAttribute::DropGroup(group));
173 } else if self.consume_ident_ci("PASSWORD")? {
174 let pw = self.parse_string()?;
175 attributes.push(AlterUserAttribute::Password(pw));
176 } else {
177 break;
178 }
179 }
180
181 if attributes.is_empty() {
182 return Err(ParseError::expected(
183 vec![
184 "VALID",
185 "CONNECTION",
186 "ENABLE",
187 "DISABLE",
188 "SET",
189 "ADD",
190 "DROP",
191 "PASSWORD",
192 ],
193 self.peek(),
194 self.position(),
195 ));
196 }
197
198 Ok(AlterUserStmt {
199 tenant,
200 username,
201 attributes,
202 })
203 }
204
205 pub fn parse_create_iam_policy_after_keywords(&mut self) -> Result<QueryExpr, ParseError> {
214 let id = self.parse_string()?;
215 if !self.consume(&Token::As)? && !self.consume_ident_ci("AS")? {
216 return Err(ParseError::expected(
217 vec!["AS"],
218 self.peek(),
219 self.position(),
220 ));
221 }
222 let json = self.parse_string()?;
223 Ok(QueryExpr::CreateIamPolicy { id, json })
224 }
225
226 pub fn parse_drop_iam_policy_after_keywords(&mut self) -> Result<QueryExpr, ParseError> {
229 let id = self.parse_string()?;
230 Ok(QueryExpr::DropIamPolicy { id })
231 }
232
233 pub fn parse_attach_policy(&mut self) -> Result<QueryExpr, ParseError> {
237 self.advance()?; if !self.consume(&Token::Policy)? && !self.consume_ident_ci("POLICY")? {
239 return Err(ParseError::expected(
240 vec!["POLICY"],
241 self.peek(),
242 self.position(),
243 ));
244 }
245 let policy_id = self.parse_string()?;
246 self.expect(Token::To)?;
247 let principal = self.parse_iam_principal_kind()?;
248 Ok(QueryExpr::AttachPolicy {
249 policy_id,
250 principal,
251 })
252 }
253
254 pub fn parse_detach_policy(&mut self) -> Result<QueryExpr, ParseError> {
256 self.advance()?; if !self.consume(&Token::Policy)? && !self.consume_ident_ci("POLICY")? {
258 return Err(ParseError::expected(
259 vec!["POLICY"],
260 self.peek(),
261 self.position(),
262 ));
263 }
264 let policy_id = self.parse_string()?;
265 self.expect(Token::From)?;
266 let principal = self.parse_iam_principal_kind()?;
267 Ok(QueryExpr::DetachPolicy {
268 policy_id,
269 principal,
270 })
271 }
272
273 pub fn parse_simulate_policy(&mut self) -> Result<QueryExpr, ParseError> {
275 self.advance()?; let user = self.parse_iam_user_ref()?;
277 if !self.consume_ident_ci("ACTION")? {
278 return Err(ParseError::expected(
279 vec!["ACTION"],
280 self.peek(),
281 self.position(),
282 ));
283 }
284 let action = self.parse_iam_action_token()?;
285 self.expect(Token::On)?;
286 let resource = self.parse_iam_resource_ref()?;
287 Ok(QueryExpr::SimulatePolicy {
288 user,
289 action,
290 resource,
291 })
292 }
293
294 pub fn parse_show_iam_after_show(&mut self) -> Result<Option<QueryExpr>, ParseError> {
298 if self.consume_ident_ci("POLICIES")? {
300 if self.consume(&Token::For)? || self.consume_ident_ci("FOR")? {
302 let principal = self.parse_iam_principal_kind()?;
303 return Ok(Some(QueryExpr::ShowPolicies {
304 filter: Some(principal),
305 }));
306 }
307 return Ok(Some(QueryExpr::ShowPolicies { filter: None }));
308 }
309 if self.consume_ident_ci("EFFECTIVE")? {
310 if !self.consume_ident_ci("PERMISSIONS")? {
311 return Err(ParseError::expected(
312 vec!["PERMISSIONS"],
313 self.peek(),
314 self.position(),
315 ));
316 }
317 if !self.consume(&Token::For)? && !self.consume_ident_ci("FOR")? {
318 return Err(ParseError::expected(
319 vec!["FOR"],
320 self.peek(),
321 self.position(),
322 ));
323 }
324 let user = self.parse_iam_user_ref()?;
325 let resource = if self.consume(&Token::On)? || self.consume_ident_ci("ON")? {
326 Some(self.parse_iam_resource_ref()?)
327 } else {
328 None
329 };
330 return Ok(Some(QueryExpr::ShowEffectivePermissions { user, resource }));
331 }
332 Ok(None)
333 }
334
335 pub(crate) fn parse_iam_principal_kind(&mut self) -> Result<PolicyPrincipalRef, ParseError> {
338 if self.consume_ident_ci("USER")? {
339 let user = self.parse_iam_user_ref()?;
340 Ok(PolicyPrincipalRef::User(user))
341 } else if self.consume(&Token::Group)? || self.consume_ident_ci("GROUP")? {
342 let g = self.expect_ident()?;
343 Ok(PolicyPrincipalRef::Group(g))
344 } else {
345 Err(ParseError::expected(
346 vec!["USER", "GROUP"],
347 self.peek(),
348 self.position(),
349 ))
350 }
351 }
352
353 fn parse_iam_user_ref(&mut self) -> Result<PolicyUserRef, ParseError> {
354 let (tenant, username) = self.parse_user_name()?;
355 Ok(PolicyUserRef { tenant, username })
356 }
357
358 fn parse_iam_resource_ref(&mut self) -> Result<PolicyResourceRef, ParseError> {
359 if matches!(self.peek(), Token::String(_)) {
363 let raw = self.parse_string()?;
364 let (kind, name) = raw.split_once(':').ok_or_else(|| {
365 ParseError::new(
366 format!("resource must be `kind:name`, got {raw:?}"),
371 self.position(),
372 )
373 })?;
374 return Ok(PolicyResourceRef {
375 kind: kind.to_string(),
376 name: name.to_string(),
377 });
378 }
379 let kind = self.expect_ident_or_keyword()?.to_ascii_lowercase();
383 if !self.consume(&Token::Colon)? {
384 return Err(ParseError::expected(
385 vec![":"],
386 self.peek(),
387 self.position(),
388 ));
389 }
390 let mut name = self.expect_ident_or_keyword()?;
393 while self.consume(&Token::Dot)? {
394 let next = self.expect_ident_or_keyword()?;
395 name.push('.');
396 name.push_str(&next);
397 }
398 Ok(PolicyResourceRef { kind, name })
399 }
400
401 fn parse_iam_action_token(&mut self) -> Result<String, ParseError> {
402 if matches!(self.peek(), Token::String(_)) {
403 return self.parse_string();
404 }
405 match self.peek() {
408 Token::Select => {
409 self.advance()?;
410 Ok("select".into())
411 }
412 Token::Insert => {
413 self.advance()?;
414 Ok("insert".into())
415 }
416 Token::Update => {
417 self.advance()?;
418 Ok("update".into())
419 }
420 Token::Delete => {
421 self.advance()?;
422 Ok("delete".into())
423 }
424 Token::Ident(_) => {
425 let raw = self.expect_ident()?;
426 Ok(raw.to_ascii_lowercase())
427 }
428 other => Err(ParseError::expected(
429 vec!["action keyword"],
430 other,
431 self.position(),
432 )),
433 }
434 }
435
436 fn parse_privilege_list(
445 &mut self,
446 ) -> Result<(Vec<String>, bool, Option<Vec<String>>), ParseError> {
447 if self.consume(&Token::All)? || self.consume_ident_ci("ALL")? {
449 let _ = self.consume_ident_ci("PRIVILEGES")?;
450 let columns = self.parse_optional_column_list()?;
451 return Ok((vec!["ALL".to_string()], true, columns));
452 }
453
454 let mut actions = Vec::new();
456 loop {
457 actions.push(self.parse_privilege_keyword()?);
458 if !self.consume(&Token::Comma)? {
459 break;
460 }
461 }
462 let columns = self.parse_optional_column_list()?;
463 Ok((actions, false, columns))
464 }
465
466 fn parse_privilege_keyword(&mut self) -> Result<String, ParseError> {
470 match self.peek() {
471 Token::Select => {
472 self.advance()?;
473 Ok("SELECT".to_string())
474 }
475 Token::Insert => {
476 self.advance()?;
477 Ok("INSERT".to_string())
478 }
479 Token::Update => {
480 self.advance()?;
481 Ok("UPDATE".to_string())
482 }
483 Token::Delete => {
484 self.advance()?;
485 Ok("DELETE".to_string())
486 }
487 Token::Truncate => {
488 self.advance()?;
489 Ok("TRUNCATE".to_string())
490 }
491 Token::Ident(name)
492 if matches!(
493 name.to_ascii_uppercase().as_str(),
494 "REFERENCES" | "EXECUTE" | "USAGE"
495 ) =>
496 {
497 let upper = name.to_ascii_uppercase();
498 self.advance()?;
499 Ok(upper)
500 }
501 other => Err(ParseError::expected(
502 vec![
503 "SELECT",
504 "INSERT",
505 "UPDATE",
506 "DELETE",
507 "TRUNCATE",
508 "REFERENCES",
509 "EXECUTE",
510 "USAGE",
511 ],
512 other,
513 self.position(),
514 )),
515 }
516 }
517
518 fn parse_optional_column_list(&mut self) -> Result<Option<Vec<String>>, ParseError> {
521 if !self.check(&Token::LParen) {
522 return Ok(None);
523 }
524 self.expect(Token::LParen)?;
525 let mut cols = Vec::new();
526 loop {
527 cols.push(self.expect_ident()?);
528 if !self.consume(&Token::Comma)? {
529 break;
530 }
531 }
532 self.expect(Token::RParen)?;
533 Ok(Some(cols))
534 }
535
536 fn parse_grant_object_kind(&mut self) -> Result<GrantObjectKind, ParseError> {
540 if self.consume(&Token::Table)? {
541 Ok(GrantObjectKind::Table)
542 } else if self.consume(&Token::Schema)? {
543 Ok(GrantObjectKind::Schema)
544 } else if self.consume_ident_ci("DATABASE")? {
545 Ok(GrantObjectKind::Database)
546 } else if self.consume_ident_ci("FUNCTION")? {
547 Ok(GrantObjectKind::Function)
548 } else {
549 Ok(GrantObjectKind::Table)
551 }
552 }
553
554 fn parse_grant_object_list(
556 &mut self,
557 kind: &GrantObjectKind,
558 ) -> Result<Vec<GrantObject>, ParseError> {
559 let mut out = Vec::new();
560 loop {
561 if matches!(kind, GrantObjectKind::Database) {
564 let name = self.expect_ident()?;
565 out.push(GrantObject { schema: None, name });
566 } else {
567 let first = self.expect_ident()?;
568 let (schema, name) = if self.consume(&Token::Dot)? {
569 let second = self.expect_ident_or_keyword()?;
570 (Some(first), second)
571 } else {
572 (None, first)
573 };
574 out.push(GrantObject { schema, name });
575 }
576 if !self.consume(&Token::Comma)? {
577 break;
578 }
579 }
580 Ok(out)
581 }
582
583 fn parse_grant_principal_list(&mut self) -> Result<Vec<GrantPrincipalRef>, ParseError> {
588 let mut out = Vec::new();
589 loop {
590 if self.consume_ident_ci("PUBLIC")? {
591 out.push(GrantPrincipalRef::Public);
592 } else if self.consume(&Token::Group)? || self.consume_ident_ci("GROUP")? {
593 let g = self.expect_ident()?;
594 out.push(GrantPrincipalRef::Group(g));
595 } else {
596 let (tenant, name) = self.parse_user_name()?;
597 out.push(GrantPrincipalRef::User { tenant, name });
598 }
599 if !self.consume(&Token::Comma)? {
600 break;
601 }
602 }
603 Ok(out)
604 }
605
606 fn parse_user_name(&mut self) -> Result<(Option<String>, String), ParseError> {
608 let first = self.expect_ident()?;
609 if self.consume(&Token::Dot)? {
610 let name = self.expect_ident()?;
611 Ok((Some(first), name))
612 } else {
613 Ok((None, first))
614 }
615 }
616
617 fn consume_grant_option_suffix(&mut self) -> Result<bool, ParseError> {
619 if self.consume(&Token::With)? {
620 if !self.consume_ident_ci("GRANT")? {
621 return Err(ParseError::expected(
622 vec!["GRANT"],
623 self.peek(),
624 self.position(),
625 ));
626 }
627 if !self.consume_ident_ci("OPTION")? {
628 return Err(ParseError::expected(
629 vec!["OPTION"],
630 self.peek(),
631 self.position(),
632 ));
633 }
634 Ok(true)
635 } else {
636 Ok(false)
637 }
638 }
639
640 fn consume_grant_option_for_prefix(&mut self) -> Result<bool, ParseError> {
642 let saved_pos = self.position();
645 if !matches!(self.peek(), Token::Ident(s) if s.eq_ignore_ascii_case("GRANT")) {
646 return Ok(false);
647 }
648 self.advance()?;
650 if !self.consume_ident_ci("OPTION")? {
651 return Err(ParseError::expected(vec!["OPTION"], self.peek(), saved_pos));
655 }
656 if !self.consume(&Token::For)? && !self.consume_ident_ci("FOR")? {
657 return Err(ParseError::expected(vec!["FOR"], self.peek(), saved_pos));
658 }
659 Ok(true)
660 }
661}