1use alloc::{boxed::Box, vec::Vec};
14
15use crate::{
16 Identifier, QualifiedName, Span, Spanned, Statement,
17 data_type::{DataType, DataTypeContext},
18 keywords::Keyword,
19 lexer::Token,
20 operator::parse_operator_name,
21 parser::{ParseError, Parser},
22 qualified_name::parse_qualified_name_unreserved,
23};
24
25#[derive(Debug, Clone)]
27pub enum CascadeOrRestrict {
28 Cascade(Span),
30 Restrict(Span),
32}
33
34impl Spanned for CascadeOrRestrict {
35 fn span(&self) -> Span {
36 match self {
37 CascadeOrRestrict::Cascade(s) => s.clone(),
38 CascadeOrRestrict::Restrict(s) => s.clone(),
39 }
40 }
41}
42
43pub(crate) fn parse_cascade_or_restrict<'a>(
44 parser: &mut Parser<'a, '_>,
45) -> Option<CascadeOrRestrict> {
46 let cascade_span = parser.skip_keyword(Keyword::CASCADE);
47 parser.postgres_only(&cascade_span);
48 let restrict_span = parser.skip_keyword(Keyword::RESTRICT);
49 parser.postgres_only(&restrict_span);
50 match (cascade_span, restrict_span) {
51 (Some(cascade), None) => Some(CascadeOrRestrict::Cascade(cascade)),
52 (None, Some(restrict)) => Some(CascadeOrRestrict::Restrict(restrict)),
53 (Some(cascade), Some(restrict)) => {
54 parser
55 .err("Cannot specify both CASCADE and RESTRICT", &cascade)
56 .frag("RESTRICT specified here", &restrict);
57 None
58 }
59 (None, None) => None,
60 }
61}
62
63#[derive(Debug, Clone)]
82pub struct DropTable<'a> {
83 pub drop_span: Span,
85 pub temporary: Option<Span>,
87 pub table_span: Span,
89 pub if_exists: Option<Span>,
91 pub tables: Vec<QualifiedName<'a>>,
93 pub restrict_or_cascade: Option<CascadeOrRestrict>,
95}
96
97impl<'a> Spanned for DropTable<'a> {
98 fn span(&self) -> Span {
99 self.drop_span
100 .join_span(&self.temporary)
101 .join_span(&self.table_span)
102 .join_span(&self.if_exists)
103 .join_span(&self.tables)
104 }
105}
106
107fn parse_drop_table<'a>(
108 parser: &mut Parser<'a, '_>,
109 drop_span: Span,
110 temporary: Option<Span>,
111) -> Result<DropTable<'a>, ParseError> {
112 let table_span = parser.consume_keyword(Keyword::TABLE)?;
113 let if_exists = if let Some(span) = parser.skip_keyword(Keyword::IF) {
114 Some(parser.consume_keyword(Keyword::EXISTS)?.join_span(&span))
115 } else {
116 None
117 };
118 let mut tables = Vec::new();
119 loop {
120 tables.push(parse_qualified_name_unreserved(parser)?);
121 if parser.skip_token(Token::Comma).is_none() {
122 break;
123 }
124 }
125 let restrict_or_cascade = parse_cascade_or_restrict(parser);
126 Ok(DropTable {
127 drop_span,
128 temporary,
129 table_span,
130 if_exists,
131 tables,
132 restrict_or_cascade,
133 })
134}
135
136#[derive(Debug, Clone)]
154pub struct DropView<'a> {
155 pub drop_span: Span,
157 pub temporary: Option<Span>,
159 pub view_span: Span,
161 pub if_exists: Option<Span>,
163 pub views: Vec<QualifiedName<'a>>,
165 pub restrict_or_cascade: Option<CascadeOrRestrict>,
167}
168
169impl<'a> Spanned for DropView<'a> {
170 fn span(&self) -> Span {
171 self.drop_span
172 .join_span(&self.temporary)
173 .join_span(&self.view_span)
174 .join_span(&self.if_exists)
175 .join_span(&self.views)
176 .join_span(&self.restrict_or_cascade)
177 }
178}
179
180fn parse_drop_view<'a>(
181 parser: &mut Parser<'a, '_>,
182 drop_span: Span,
183 temporary: Option<Span>,
184) -> Result<DropView<'a>, ParseError> {
185 let view_span = parser.consume_keyword(Keyword::VIEW)?;
186 let if_exists = if let Some(span) = parser.skip_keyword(Keyword::IF) {
187 Some(parser.consume_keyword(Keyword::EXISTS)?.join_span(&span))
188 } else {
189 None
190 };
191 let mut views = Vec::new();
192 loop {
193 views.push(parse_qualified_name_unreserved(parser)?);
194 if parser.skip_token(Token::Comma).is_none() {
195 break;
196 }
197 }
198 let restrict_or_cascade = parse_cascade_or_restrict(parser);
199 Ok(DropView {
200 drop_span,
201 temporary,
202 view_span,
203 if_exists,
204 views,
205 restrict_or_cascade,
206 })
207}
208
209#[derive(Debug, Clone)]
228pub struct DropDatabase<'a> {
229 pub drop_span: Span,
231 pub database_span: Span,
233 pub if_exists: Option<Span>,
235 pub database: Identifier<'a>,
237}
238
239impl<'a> Spanned for DropDatabase<'a> {
240 fn span(&self) -> Span {
241 self.drop_span
242 .join_span(&self.database_span)
243 .join_span(&self.if_exists)
244 .join_span(&self.database)
245 }
246}
247
248fn parse_drop_database<'a>(
249 parser: &mut Parser<'a, '_>,
250 drop_span: Span,
251 kw: Keyword,
252) -> Result<DropDatabase<'a>, ParseError> {
253 let database_span = parser.consume_keyword(kw)?;
255 let if_exists = if let Some(span) = parser.skip_keyword(Keyword::IF) {
256 Some(parser.consume_keyword(Keyword::EXISTS)?.join_span(&span))
257 } else {
258 None
259 };
260 let database = parser.consume_plain_identifier_unreserved()?;
261 Ok(DropDatabase {
262 drop_span,
263 database_span,
264 if_exists,
265 database,
266 })
267}
268
269#[derive(Debug, Clone)]
287pub struct DropEvent<'a> {
288 pub drop_span: Span,
290 pub event_span: Span,
292 pub if_exists: Option<Span>,
294 pub event: QualifiedName<'a>,
296}
297
298impl<'a> Spanned for DropEvent<'a> {
299 fn span(&self) -> Span {
300 self.drop_span
301 .join_span(&self.event_span)
302 .join_span(&self.if_exists)
303 .join_span(&self.event)
304 }
305}
306
307fn parse_drop_event<'a>(
308 parser: &mut Parser<'a, '_>,
309 drop_span: Span,
310) -> Result<DropEvent<'a>, ParseError> {
311 let event_span = parser.consume_keyword(Keyword::EVENT)?;
313 let if_exists = if let Some(span) = parser.skip_keyword(Keyword::IF) {
314 Some(parser.consume_keyword(Keyword::EXISTS)?.join_span(&span))
315 } else {
316 None
317 };
318 let event = parse_qualified_name_unreserved(parser)?;
319 Ok(DropEvent {
320 drop_span,
321 event_span,
322 if_exists,
323 event,
324 })
325}
326
327#[derive(Debug, Clone)]
328pub enum DropFunctionArgMode {
329 In(Span),
330 Out(Span),
331 InOut(Span),
332}
333
334impl Spanned for DropFunctionArgMode {
335 fn span(&self) -> Span {
336 match self {
337 DropFunctionArgMode::In(s) => s.clone(),
338 DropFunctionArgMode::Out(s) => s.clone(),
339 DropFunctionArgMode::InOut(s) => s.clone(),
340 }
341 }
342}
343
344#[derive(Debug, Clone)]
345pub struct DropFunctionArg<'a> {
346 pub mode: Option<DropFunctionArgMode>,
347 pub name: Option<Identifier<'a>>,
348 pub data_type: DataType<'a>,
349 pub default: Option<Span>, }
351
352impl<'a> Spanned for DropFunctionArg<'a> {
353 fn span(&self) -> Span {
354 self.data_type
355 .span()
356 .join_span(&self.mode)
357 .join_span(&self.name)
358 .join_span(&self.default)
359 }
360}
361
362#[derive(Debug, Clone)]
380pub struct DropFunction<'a> {
381 pub drop_span: Span,
383 pub function_span: Span,
385 pub if_exists: Option<Span>,
387 pub functions: Vec<(QualifiedName<'a>, Option<Vec<DropFunctionArg<'a>>>)>,
389 pub restrict_or_cascade: Option<CascadeOrRestrict>,
391}
392
393impl<'a> Spanned for DropFunction<'a> {
394 fn span(&self) -> Span {
395 let mut span = self
396 .drop_span
397 .join_span(&self.function_span)
398 .join_span(&self.if_exists)
399 .join_span(&self.restrict_or_cascade);
400 for (name, args) in &self.functions {
401 span = span.join_span(name);
402 if let Some(args) = args {
403 for arg in args {
404 span = span.join_span(arg);
405 }
406 }
407 }
408 span
409 }
410}
411
412fn parse_drop_function<'a>(
413 parser: &mut Parser<'a, '_>,
414 drop_span: Span,
415) -> Result<DropFunction<'a>, ParseError> {
416 let function_span = parser.consume_keyword(Keyword::FUNCTION)?;
417 let if_exists = if let Some(span) = parser.skip_keyword(Keyword::IF) {
418 Some(parser.consume_keyword(Keyword::EXISTS)?.join_span(&span))
419 } else {
420 None
421 };
422 let mut functions = Vec::new();
423 loop {
424 let name = parse_qualified_name_unreserved(parser)?;
425 let args = if parser.token == Token::LParen {
426 let lparen = parser.consume_token(Token::LParen)?;
427 let mut arg_list = Vec::new();
428 parser.recovered(")", &|t| t == &Token::RParen, |parser| {
429 loop {
430 let mode = match &parser.token {
432 Token::Ident(_, Keyword::IN) => Some(DropFunctionArgMode::In(
433 parser.consume_keyword(Keyword::IN)?,
434 )),
435 Token::Ident(_, Keyword::OUT) => Some(DropFunctionArgMode::Out(
436 parser.consume_keyword(Keyword::OUT)?,
437 )),
438 Token::Ident(_, Keyword::INOUT) => Some(DropFunctionArgMode::InOut(
439 parser.consume_keyword(Keyword::INOUT)?,
440 )),
441 _ => None,
442 };
443 let name = match &parser.token {
445 Token::Ident(_, kw) if !kw.restricted(parser.reserved()) => {
446 Some(parser.consume_plain_identifier_unreserved()?)
447 }
448 _ => None,
449 };
450 let data_type =
452 crate::data_type::parse_data_type(parser, DataTypeContext::FunctionParam)?;
453 let default = if parser.skip_token(Token::Eq).is_some() {
455 Some(parser.consume().clone())
457 } else {
458 None
459 };
460 arg_list.push(DropFunctionArg {
461 mode,
462 name,
463 data_type,
464 default,
465 });
466 if parser.skip_token(Token::Comma).is_none() {
467 break;
468 }
469 }
470 Ok(())
471 })?;
472 parser.consume_token(Token::RParen)?;
473 parser.postgres_only(&lparen.join_span(&arg_list));
474 Some(arg_list)
475 } else {
476 None
477 };
478 functions.push((name, args));
479 if parser.skip_token(Token::Comma).is_none() {
480 break;
481 }
482 }
483 if let [(first, _), (second, _), ..] = functions.as_slice()
484 && !parser.options.dialect.is_postgresql()
485 {
486 parser
487 .err("Multiple function only supported by ", second)
488 .frag("First function supplied here", first);
489 }
490 let restrict_or_cascade = parse_cascade_or_restrict(parser);
491 Ok(DropFunction {
492 drop_span,
493 function_span,
494 if_exists,
495 functions,
496 restrict_or_cascade,
497 })
498}
499
500#[derive(Debug, Clone)]
518pub struct DropProcedure<'a> {
519 pub drop_span: Span,
521 pub procedure_span: Span,
523 pub if_exists: Option<Span>,
525 pub procedure: QualifiedName<'a>,
527}
528
529impl<'a> Spanned for DropProcedure<'a> {
530 fn span(&self) -> Span {
531 self.drop_span
532 .join_span(&self.procedure_span)
533 .join_span(&self.if_exists)
534 .join_span(&self.procedure)
535 }
536}
537
538fn parse_drop_procedure<'a>(
539 parser: &mut Parser<'a, '_>,
540 drop_span: Span,
541) -> Result<DropProcedure<'a>, ParseError> {
542 let procedure_span = parser.consume_keyword(Keyword::PROCEDURE)?;
544 let if_exists = if let Some(span) = parser.skip_keyword(Keyword::IF) {
545 Some(parser.consume_keyword(Keyword::EXISTS)?.join_span(&span))
546 } else {
547 None
548 };
549 let procedure = parse_qualified_name_unreserved(parser)?;
550 Ok(DropProcedure {
551 drop_span,
552 procedure_span,
553 if_exists,
554 procedure,
555 })
556}
557
558#[derive(Debug, Clone)]
576pub struct DropSequence<'a> {
577 pub drop_span: Span,
579 pub sequence_span: Span,
581 pub if_exists: Option<Span>,
583 pub sequences: Vec<QualifiedName<'a>>,
585 pub restrict_or_cascade: Option<CascadeOrRestrict>,
587}
588
589impl<'a> Spanned for DropSequence<'a> {
590 fn span(&self) -> Span {
591 self.drop_span
592 .join_span(&self.sequence_span)
593 .join_span(&self.if_exists)
594 .join_span(&self.sequences)
595 .join_span(&self.restrict_or_cascade)
596 }
597}
598
599fn parse_drop_sequence<'a>(
600 parser: &mut Parser<'a, '_>,
601 drop_span: Span,
602) -> Result<DropSequence<'a>, ParseError> {
603 let sequence_span = parser.consume_keyword(Keyword::SEQUENCE)?;
605 parser.postgres_only(&sequence_span);
606 let if_exists = if let Some(span) = parser.skip_keyword(Keyword::IF) {
607 Some(parser.consume_keyword(Keyword::EXISTS)?.join_span(&span))
608 } else {
609 None
610 };
611 let mut sequences = Vec::new();
612 loop {
613 sequences.push(parse_qualified_name_unreserved(parser)?);
614 if parser.skip_token(Token::Comma).is_none() {
615 break;
616 }
617 }
618 let restrict_or_cascade = parse_cascade_or_restrict(parser);
619 Ok(DropSequence {
620 drop_span,
621 sequence_span,
622 if_exists,
623 sequences,
624 restrict_or_cascade,
625 })
626}
627
628#[derive(Debug, Clone)]
647pub struct DropServer<'a> {
648 pub drop_span: Span,
650 pub server_span: Span,
652 pub if_exists: Option<Span>,
654 pub server: Identifier<'a>,
656}
657
658impl<'a> Spanned for DropServer<'a> {
659 fn span(&self) -> Span {
660 self.drop_span
661 .join_span(&self.server_span)
662 .join_span(&self.if_exists)
663 .join_span(&self.server)
664 }
665}
666
667fn parse_drop_server<'a>(
668 parser: &mut Parser<'a, '_>,
669 drop_span: Span,
670) -> Result<DropServer<'a>, ParseError> {
671 let server_span = parser.consume_keyword(Keyword::SERVER)?;
673 parser.postgres_only(&server_span);
674 let if_exists = if let Some(span) = parser.skip_keyword(Keyword::IF) {
675 Some(parser.consume_keyword(Keyword::EXISTS)?.join_span(&span))
676 } else {
677 None
678 };
679 let server = parser.consume_plain_identifier_unreserved()?;
680 Ok(DropServer {
681 drop_span,
682 server_span,
683 if_exists,
684 server,
685 })
686}
687
688#[derive(Debug, Clone)]
706pub struct DropTrigger<'a> {
707 pub drop_span: Span,
709 pub trigger_span: Span,
711 pub if_exists: Option<Span>,
713 pub identifier: QualifiedName<'a>,
715 pub on: Option<(Span, QualifiedName<'a>)>,
717 pub restrict_or_cascade: Option<CascadeOrRestrict>,
719}
720
721impl<'a> Spanned for DropTrigger<'a> {
722 fn span(&self) -> Span {
723 self.drop_span
724 .join_span(&self.trigger_span)
725 .join_span(&self.if_exists)
726 .join_span(&self.identifier)
727 .join_span(&self.on)
728 .join_span(&self.restrict_or_cascade)
729 }
730}
731
732fn parse_drop_trigger<'a>(
733 parser: &mut Parser<'a, '_>,
734 drop_span: Span,
735) -> Result<DropTrigger<'a>, ParseError> {
736 let trigger_span = parser.consume_keyword(Keyword::TRIGGER)?;
737 let if_exists = if let Some(span) = parser.skip_keyword(Keyword::IF) {
738 Some(parser.consume_keyword(Keyword::EXISTS)?.join_span(&span))
739 } else {
740 None
741 };
742 let identifier = parse_qualified_name_unreserved(parser)?;
743 let on = if let Some(span) = parser.skip_keyword(Keyword::ON) {
744 let table_name = parse_qualified_name_unreserved(parser)?;
745 parser.postgres_only(&span);
746 Some((span, table_name))
747 } else {
748 if parser.options.dialect.is_postgresql() {
749 parser.err("ON required for trigger drops in PostgreSQL", &trigger_span);
750 }
751 None
752 };
753 let restrict_or_cascade = parse_cascade_or_restrict(parser);
754 Ok(DropTrigger {
755 drop_span,
756 trigger_span,
757 if_exists,
758 identifier,
759 on,
760 restrict_or_cascade,
761 })
762}
763
764#[derive(Debug, Clone)]
803pub struct DropIndex<'a> {
804 pub drop_span: Span,
806 pub index_span: Span,
808 pub if_exists: Option<Span>,
810 pub index_name: Identifier<'a>,
812 pub on: Option<(Span, QualifiedName<'a>)>,
814 pub restrict_or_cascade: Option<CascadeOrRestrict>,
816}
817
818impl<'a> Spanned for DropIndex<'a> {
819 fn span(&self) -> Span {
820 self.drop_span
821 .join_span(&self.index_span)
822 .join_span(&self.if_exists)
823 .join_span(&self.index_name)
824 .join_span(&self.on)
825 .join_span(&self.restrict_or_cascade)
826 }
827}
828
829fn parse_drop_index<'a>(
830 parser: &mut Parser<'a, '_>,
831 drop_span: Span,
832) -> Result<DropIndex<'a>, ParseError> {
833 let index_span = parser.consume_keyword(Keyword::INDEX)?;
835 let if_exists = if let Some(span) = parser.skip_keyword(Keyword::IF) {
836 Some(parser.consume_keyword(Keyword::EXISTS)?.join_span(&span))
837 } else {
838 None
839 };
840 let index_name = parser.consume_plain_identifier_unreserved()?;
841 let on = if let Some(span) = parser.skip_keyword(Keyword::ON) {
842 let table_name = parse_qualified_name_unreserved(parser)?;
843 Some((span, table_name))
844 } else {
845 None
846 };
847
848 if on.is_none() && parser.options.dialect.is_maria() {
849 parser.err("On required for index drops in MariaDb", &drop_span);
850 }
851 parser.maria_only(&on);
852
853 let restrict_or_cascade = parse_cascade_or_restrict(parser);
854
855 Ok(DropIndex {
856 drop_span,
857 index_span,
858 if_exists,
859 index_name,
860 on,
861 restrict_or_cascade,
862 })
863}
864
865#[derive(Debug, Clone)]
882pub struct DropDomain<'a> {
883 pub drop_span: Span,
885 pub domain_span: Span,
887 pub if_exists: Option<Span>,
889 pub domains: Vec<QualifiedName<'a>>,
891 pub restrict_or_cascade: Option<CascadeOrRestrict>,
893}
894
895impl<'a> Spanned for DropDomain<'a> {
896 fn span(&self) -> Span {
897 self.drop_span
898 .join_span(&self.domain_span)
899 .join_span(&self.if_exists)
900 .join_span(&self.domains)
901 .join_span(&self.restrict_or_cascade)
902 }
903}
904
905fn parse_drop_domain<'a>(
906 parser: &mut Parser<'a, '_>,
907 drop_span: Span,
908) -> Result<DropDomain<'a>, ParseError> {
909 let domain_span = parser.consume_keyword(Keyword::DOMAIN)?;
910 parser.postgres_only(&domain_span);
911 let if_exists = if let Some(span) = parser.skip_keyword(Keyword::IF) {
912 Some(parser.consume_keyword(Keyword::EXISTS)?.join_span(&span))
913 } else {
914 None
915 };
916 let mut domains = Vec::new();
917 loop {
918 domains.push(parse_qualified_name_unreserved(parser)?);
919 if parser.skip_token(Token::Comma).is_none() {
920 break;
921 }
922 }
923 let restrict_or_cascade = parse_cascade_or_restrict(parser);
924 Ok(DropDomain {
925 drop_span,
926 domain_span,
927 if_exists,
928 domains,
929 restrict_or_cascade,
930 })
931}
932
933#[derive(Debug, Clone)]
949pub struct DropExtension<'a> {
950 pub drop_span: Span,
952 pub extension_span: Span,
954 pub if_exists: Option<Span>,
956 pub extensions: Vec<Identifier<'a>>,
958 pub restrict_or_cascade: Option<CascadeOrRestrict>,
960}
961
962impl<'a> Spanned for DropExtension<'a> {
963 fn span(&self) -> Span {
964 self.drop_span
965 .join_span(&self.extension_span)
966 .join_span(&self.if_exists)
967 .join_span(&self.extensions)
968 .join_span(&self.restrict_or_cascade)
969 }
970}
971
972fn parse_drop_extension<'a>(
973 parser: &mut Parser<'a, '_>,
974 drop_span: Span,
975) -> Result<DropExtension<'a>, ParseError> {
976 let extension_span = parser.consume_keyword(Keyword::EXTENSION)?;
977 parser.postgres_only(&extension_span);
978 let if_exists = if let Some(span) = parser.skip_keyword(Keyword::IF) {
979 Some(parser.consume_keyword(Keyword::EXISTS)?.join_span(&span))
980 } else {
981 None
982 };
983 let mut extensions = Vec::new();
984 loop {
985 extensions.push(parser.consume_plain_identifier_unreserved()?);
986 if parser.skip_token(Token::Comma).is_none() {
987 break;
988 }
989 }
990 let restrict_or_cascade = parse_cascade_or_restrict(parser);
991
992 Ok(DropExtension {
993 drop_span,
994 extension_span,
995 if_exists,
996 extensions,
997 restrict_or_cascade,
998 })
999}
1000
1001#[derive(Debug, Clone)]
1018pub struct DropOperatorItem<'a> {
1019 pub name: QualifiedName<'a>,
1020 pub left_type: Option<DataType<'a>>,
1021 pub right_type: Option<DataType<'a>>,
1022}
1023
1024impl<'a> Spanned for DropOperatorItem<'a> {
1025 fn span(&self) -> Span {
1026 self.name
1027 .span()
1028 .join_span(&self.left_type)
1029 .join_span(&self.right_type)
1030 }
1031}
1032
1033#[derive(Debug, Clone)]
1034pub struct DropOperator<'a> {
1035 pub drop_operator_span: Span,
1037 pub if_exists: Option<Span>,
1039 pub operators: Vec<DropOperatorItem<'a>>,
1041 pub restrict_or_cascade: Option<CascadeOrRestrict>,
1043}
1044
1045impl<'a> Spanned for DropOperator<'a> {
1046 fn span(&self) -> Span {
1047 self.drop_operator_span
1048 .join_span(&self.if_exists)
1049 .join_span(&self.restrict_or_cascade)
1050 .join_span(&self.operators)
1051 }
1052}
1053
1054fn parse_drop_operator<'a>(
1055 parser: &mut Parser<'a, '_>,
1056 drop_operator_span: Span,
1057) -> Result<DropOperator<'a>, ParseError> {
1058 parser.postgres_only(&drop_operator_span);
1059 let if_exists = if let Some(span) = parser.skip_keyword(Keyword::IF) {
1060 Some(parser.consume_keyword(Keyword::EXISTS)?.join_span(&span))
1061 } else {
1062 None
1063 };
1064 let mut operators = Vec::new();
1066 loop {
1067 if parser.token == Token::LParen {
1068 return Err(parser.expected_failure("operator name")?);
1069 }
1070 let name = parse_operator_name(parser)?;
1071 let (left_type, right_type) = if parser.token == Token::LParen {
1072 parser.consume_token(Token::LParen)?;
1073 let mut left = None;
1074 let mut right = None;
1075 parser.recovered(")", &|t| t == &Token::RParen, |parser| {
1076 if parser.token != Token::Comma && parser.token != Token::RParen {
1077 left = Some(crate::data_type::parse_data_type(
1078 parser,
1079 DataTypeContext::TypeRef,
1080 )?);
1081 }
1082 if parser.skip_token(Token::Comma).is_some() && parser.token != Token::RParen {
1083 right = Some(crate::data_type::parse_data_type(
1084 parser,
1085 DataTypeContext::TypeRef,
1086 )?);
1087 }
1088 Ok(())
1089 })?;
1090 parser.consume_token(Token::RParen)?;
1091 (left, right)
1092 } else {
1093 (None, None)
1094 };
1095 operators.push(DropOperatorItem {
1096 name,
1097 left_type,
1098 right_type,
1099 });
1100 if parser.skip_token(Token::Comma).is_none() {
1101 break;
1102 }
1103 }
1104 let restrict_or_cascade = parse_cascade_or_restrict(parser);
1105 Ok(DropOperator {
1106 drop_operator_span,
1107 if_exists,
1108 operators,
1109 restrict_or_cascade,
1110 })
1111}
1112
1113#[derive(Debug, Clone)]
1129pub struct DropOperatorFamily<'a> {
1130 pub drop_operator_family_span: Span,
1132 pub if_exists: Option<Span>,
1134 pub family: QualifiedName<'a>,
1136 pub using: Option<(Span, Identifier<'a>)>,
1138 pub restrict_or_cascade: Option<CascadeOrRestrict>,
1140}
1141
1142impl<'a> Spanned for DropOperatorFamily<'a> {
1143 fn span(&self) -> Span {
1144 self.drop_operator_family_span
1145 .join_span(&self.if_exists)
1146 .join_span(&self.family)
1147 .join_span(&self.using)
1148 .join_span(&self.restrict_or_cascade)
1149 }
1150}
1151
1152fn parse_drop_operator_family<'a>(
1153 parser: &mut Parser<'a, '_>,
1154 drop_operator_family_span: Span,
1155) -> Result<DropOperatorFamily<'a>, ParseError> {
1156 parser.postgres_only(&drop_operator_family_span);
1157 let if_exists = if let Some(span) = parser.skip_keyword(Keyword::IF) {
1158 Some(parser.consume_keyword(Keyword::EXISTS)?.join_span(&span))
1159 } else {
1160 None
1161 };
1162 let family = parse_qualified_name_unreserved(parser)?;
1163 let using = if let Some(span) = parser.skip_keyword(Keyword::USING) {
1164 let method = parser.consume_plain_identifier_unreserved()?;
1165 Some((span, method))
1166 } else {
1167 None
1168 };
1169 let restrict_or_cascade = parse_cascade_or_restrict(parser);
1170 Ok(DropOperatorFamily {
1171 drop_operator_family_span,
1172 if_exists,
1173 family,
1174 using,
1175 restrict_or_cascade,
1176 })
1177}
1178
1179#[derive(Debug, Clone)]
1195pub struct DropOperatorClass<'a> {
1196 pub drop_operator_class_span: Span,
1198 pub if_exists: Option<Span>,
1200 pub class: QualifiedName<'a>,
1202 pub using: Option<(Span, Identifier<'a>)>,
1204 pub restrict_or_cascade: Option<CascadeOrRestrict>,
1206}
1207
1208impl<'a> Spanned for DropOperatorClass<'a> {
1209 fn span(&self) -> Span {
1210 self.drop_operator_class_span
1211 .join_span(&self.if_exists)
1212 .join_span(&self.class)
1213 .join_span(&self.using)
1214 .join_span(&self.restrict_or_cascade)
1215 }
1216}
1217
1218fn parse_drop_operator_class<'a>(
1219 parser: &mut Parser<'a, '_>,
1220 drop_operator_class_span: Span,
1221) -> Result<DropOperatorClass<'a>, ParseError> {
1222 parser.postgres_only(&drop_operator_class_span);
1223 let if_exists = if let Some(span) = parser.skip_keyword(Keyword::IF) {
1224 Some(parser.consume_keyword(Keyword::EXISTS)?.join_span(&span))
1225 } else {
1226 None
1227 };
1228 let class = parse_qualified_name_unreserved(parser)?;
1229 let using = if let Some(span) = parser.skip_keyword(Keyword::USING) {
1230 let method = parser.consume_plain_identifier_unreserved()?;
1231 Some((span, method))
1232 } else {
1233 None
1234 };
1235 let restrict_or_cascade = parse_cascade_or_restrict(parser);
1236 Ok(DropOperatorClass {
1237 drop_operator_class_span,
1238 if_exists,
1239 class,
1240 using,
1241 restrict_or_cascade,
1242 })
1243}
1244
1245pub(crate) fn parse_drop<'a>(parser: &mut Parser<'a, '_>) -> Result<Statement<'a>, ParseError> {
1246 let drop_span = parser.consume_keyword(Keyword::DROP)?;
1247 let temporary = parser.skip_keyword(Keyword::TEMPORARY);
1248 match &parser.token {
1249 Token::Ident(_, Keyword::TABLE) => Ok(Statement::DropTable(Box::new(parse_drop_table(
1250 parser, drop_span, temporary,
1251 )?))),
1252 Token::Ident(_, Keyword::VIEW) => Ok(Statement::DropView(Box::new(parse_drop_view(
1253 parser, drop_span, temporary,
1254 )?))),
1255 Token::Ident(_, kw @ Keyword::DATABASE | kw @ Keyword::SCHEMA) => Ok(
1256 Statement::DropDatabase(Box::new(parse_drop_database(parser, drop_span, *kw)?)),
1257 ),
1258 Token::Ident(_, Keyword::DOMAIN) => Ok(Statement::DropDomain(Box::new(parse_drop_domain(
1259 parser, drop_span,
1260 )?))),
1261 Token::Ident(_, Keyword::EXTENSION) => Ok(Statement::DropExtension(Box::new(
1262 parse_drop_extension(parser, drop_span)?,
1263 ))),
1264 Token::Ident(_, Keyword::EVENT) => Ok(Statement::DropEvent(Box::new(parse_drop_event(
1265 parser, drop_span,
1266 )?))),
1267 Token::Ident(_, Keyword::FUNCTION) => Ok(Statement::DropFunction(Box::new(
1268 parse_drop_function(parser, drop_span)?,
1269 ))),
1270 Token::Ident(_, Keyword::OPERATOR) => {
1271 let operator_span = parser.consume_keyword(Keyword::OPERATOR)?;
1272 match &parser.token {
1273 Token::Ident(_, Keyword::FAMILY) => {
1274 let family_span = parser.consume_keyword(Keyword::FAMILY)?;
1275 Ok(Statement::DropOperatorFamily(Box::new(
1276 parse_drop_operator_family(
1277 parser,
1278 drop_span.join_span(&operator_span).join_span(&family_span),
1279 )?,
1280 )))
1281 }
1282 Token::Ident(_, Keyword::CLASS) => {
1283 let class_span = parser.consume_keyword(Keyword::CLASS)?;
1284 Ok(Statement::DropOperatorClass(Box::new(
1285 parse_drop_operator_class(
1286 parser,
1287 drop_span.join_span(&operator_span).join_span(&class_span),
1288 )?,
1289 )))
1290 }
1291 _ => Ok(Statement::DropOperator(Box::new(parse_drop_operator(
1292 parser,
1293 drop_span.join_span(&operator_span),
1294 )?))),
1295 }
1296 }
1297 Token::Ident(_, Keyword::INDEX) => Ok(Statement::DropIndex(Box::new(parse_drop_index(
1298 parser, drop_span,
1299 )?))),
1300 Token::Ident(_, Keyword::PROCEDURE) => Ok(Statement::DropProcedure(Box::new(
1301 parse_drop_procedure(parser, drop_span)?,
1302 ))),
1303 Token::Ident(_, Keyword::SEQUENCE) => Ok(Statement::DropSequence(Box::new(
1304 parse_drop_sequence(parser, drop_span)?,
1305 ))),
1306 Token::Ident(_, Keyword::SERVER) => Ok(Statement::DropServer(Box::new(parse_drop_server(
1307 parser, drop_span,
1308 )?))),
1309 Token::Ident(_, Keyword::TRIGGER) => Ok(Statement::DropTrigger(Box::new(
1310 parse_drop_trigger(parser, drop_span)?,
1311 ))),
1312 Token::Ident(_, Keyword::USER) => {
1313 parser.todo(file!(), line!())
1315 }
1316 _ => parser.expected_failure("droppable"),
1317 }
1318}