1use alloc::{boxed::Box, vec::Vec};
2
3use crate::{
15 data_type::parse_data_type,
16 expression::parse_expression,
17 keywords::Keyword,
18 lexer::Token,
19 parser::{ParseError, Parser},
20 qualified_name::parse_qualified_name,
21 statement::{parse_compound_query, parse_statement},
22 DataType, Expression, Identifier, QualifiedName, SString, Span, Spanned, Statement,
23};
24
25#[derive(Clone, Debug)]
27pub enum TableOption<'a> {
28 AutoExtendSize {
29 identifier: Span,
30 value: Identifier<'a>,
31 },
32 AutoIncrement {
33 identifier: Span,
34 value: Identifier<'a>,
35 },
36 AvgRowLength {
37 identifier: Span,
38 value: Identifier<'a>,
39 },
40 CharSet {
41 identifier: Span,
42 value: Identifier<'a>,
43 },
44 DefaultCharSet {
45 identifier: Span,
46 value: Identifier<'a>,
47 },
48 Checksum {
49 identifier: Span,
50 value: (bool, Span),
51 },
52 Collate {
53 identifier: Span,
54 value: Identifier<'a>,
55 },
56 DefaultCollate {
57 identifier: Span,
58 value: Identifier<'a>,
59 },
60 Comment {
61 identifier: Span,
62 value: SString<'a>,
63 },
64 Compression {
65 identifier: Span,
66 value: SString<'a>,
67 },
68 Connection {
69 identifier: Span,
70 value: SString<'a>,
71 },
72 DataDirectory {
73 identifier: Span,
74 value: SString<'a>,
75 },
76 IndexDirectory {
77 identifier: Span,
78 value: SString<'a>,
79 },
80 DelayKeyWrite {
81 identifier: Span,
82 value: (bool, Span),
83 },
84 Encryption {
85 identifier: Span,
86 value: (bool, Span),
87 },
88 Engine {
89 identifier: Span,
90 value: Identifier<'a>,
91 },
92 EngineAttribute {
93 identifier: Span,
94 value: SString<'a>,
95 },
96 InsertMethod {
97 identifier: Span,
98 value: Identifier<'a>,
99 },
100 KeyBlockSize {
101 identifier: Span,
102 value: (usize, Span),
103 },
104 MaxRows {
105 identifier: Span,
106 value: (usize, Span),
107 },
108 MinRows {
109 identifier: Span,
110 value: (usize, Span),
111 },
112 Password {
114 identifier: Span,
115 value: SString<'a>,
116 },
117 RowFormat {
118 identifier: Span,
119 value: Identifier<'a>,
120 },
121 SecondaryEngineAttribute {
122 identifier: Span,
123 value: SString<'a>,
124 },
125 Strict {
126 identifier: Span,
127 },
128 }
134
135impl<'a> Spanned for TableOption<'a> {
136 fn span(&self) -> Span {
137 match &self {
138 TableOption::AutoExtendSize { identifier, value } => identifier.span().join_span(value),
139 TableOption::AutoIncrement { identifier, value } => identifier.span().join_span(value),
140 TableOption::AvgRowLength { identifier, value } => identifier.span().join_span(value),
141 TableOption::CharSet { identifier, value } => identifier.span().join_span(value),
142 TableOption::DefaultCharSet { identifier, value } => identifier.span().join_span(value),
143 TableOption::Checksum { identifier, value } => identifier.span().join_span(value),
144 TableOption::Collate { identifier, value } => identifier.span().join_span(value),
145 TableOption::DefaultCollate { identifier, value } => identifier.span().join_span(value),
146 TableOption::Comment { identifier, value } => identifier.span().join_span(value),
147 TableOption::Compression { identifier, value } => identifier.span().join_span(value),
148 TableOption::Connection { identifier, value } => identifier.span().join_span(value),
149 TableOption::DataDirectory { identifier, value } => identifier.span().join_span(value),
150 TableOption::IndexDirectory { identifier, value } => identifier.span().join_span(value),
151 TableOption::DelayKeyWrite { identifier, value } => identifier.span().join_span(value),
152 TableOption::Encryption { identifier, value } => identifier.span().join_span(value),
153 TableOption::Engine { identifier, value } => identifier.span().join_span(value),
154 TableOption::EngineAttribute { identifier, value } => {
155 identifier.span().join_span(value)
156 }
157 TableOption::InsertMethod { identifier, value } => identifier.span().join_span(value),
158 TableOption::KeyBlockSize { identifier, value } => identifier.span().join_span(value),
159 TableOption::MaxRows { identifier, value } => identifier.span().join_span(value),
160 TableOption::MinRows { identifier, value } => identifier.span().join_span(value),
161 TableOption::Password { identifier, value } => identifier.span().join_span(value),
162 TableOption::RowFormat { identifier, value } => identifier.span().join_span(value),
163 TableOption::SecondaryEngineAttribute { identifier, value } => {
164 identifier.span().join_span(value)
165 }
166 TableOption::Strict { identifier } => identifier.span(),
167 }
168 }
169}
170
171#[derive(Clone, Debug)]
173pub enum CreateDefinition<'a> {
174 ColumnDefinition {
175 identifier: Identifier<'a>,
177 data_type: DataType<'a>,
179 },
180 ConstraintDefinition {
181 span: Span,
182 identifier: Identifier<'a>,
183 },
184}
185
186impl<'a> Spanned for CreateDefinition<'a> {
187 fn span(&self) -> Span {
188 match &self {
189 CreateDefinition::ColumnDefinition {
190 identifier,
191 data_type,
192 } => identifier.span().join_span(data_type),
193 CreateDefinition::ConstraintDefinition { span, identifier } => {
194 span.join_span(identifier)
195 }
196 }
197 }
198}
199
200#[derive(Clone, Debug)]
202pub enum CreateAlgorithm {
203 Undefined(Span),
204 Merge(Span),
205 TempTable(Span),
206}
207impl Spanned for CreateAlgorithm {
208 fn span(&self) -> Span {
209 match &self {
210 CreateAlgorithm::Undefined(s) => s.span(),
211 CreateAlgorithm::Merge(s) => s.span(),
212 CreateAlgorithm::TempTable(s) => s.span(),
213 }
214 }
215}
216
217#[derive(Clone, Debug)]
219pub enum CreateOption<'a> {
220 OrReplace(Span),
221 Temporary(Span),
222 Unique(Span),
223 Algorithm(Span, CreateAlgorithm),
224 Definer {
225 definer_span: Span,
226 user: Identifier<'a>,
227 host: Identifier<'a>,
228 },
229 SqlSecurityDefiner(Span, Span),
230 SqlSecurityUser(Span, Span),
231}
232impl<'a> Spanned for CreateOption<'a> {
233 fn span(&self) -> Span {
234 match &self {
235 CreateOption::OrReplace(v) => v.span(),
236 CreateOption::Temporary(v) => v.span(),
237 CreateOption::Algorithm(s, a) => s.join_span(a),
238 CreateOption::Definer {
239 definer_span,
240 user,
241 host,
242 } => definer_span.join_span(user).join_span(host),
243 CreateOption::SqlSecurityDefiner(a, b) => a.join_span(b),
244 CreateOption::SqlSecurityUser(a, b) => a.join_span(b),
245 CreateOption::Unique(v) => v.span(),
246 }
247 }
248}
249
250#[derive(Clone, Debug)]
276pub struct CreateTable<'a> {
277 pub create_span: Span,
279 pub create_options: Vec<CreateOption<'a>>,
281 pub table_span: Span,
283 pub identifier: QualifiedName<'a>,
285 pub if_not_exists: Option<Span>,
287 pub create_definitions: Vec<CreateDefinition<'a>>,
289 pub options: Vec<TableOption<'a>>,
291}
292
293impl<'a> Spanned for CreateTable<'a> {
294 fn span(&self) -> Span {
295 self.create_span
296 .join_span(&self.create_options)
297 .join_span(&self.table_span)
298 .join_span(&self.identifier)
299 .join_span(&self.if_not_exists)
300 .join_span(&self.create_definitions)
301 .join_span(&self.options)
302 }
303}
304
305#[derive(Clone, Debug)]
331pub struct CreateView<'a> {
332 pub create_span: Span,
334 pub create_options: Vec<CreateOption<'a>>,
336 pub view_span: Span,
338 pub if_not_exists: Option<Span>,
340 pub name: QualifiedName<'a>,
342 pub as_span: Span,
344 pub select: Box<Statement<'a>>,
346}
347
348impl<'a> Spanned for CreateView<'a> {
349 fn span(&self) -> Span {
350 self.create_span
351 .join_span(&self.create_options)
352 .join_span(&self.view_span)
353 .join_span(&self.if_not_exists)
354 .join_span(&self.name)
355 .join_span(&self.as_span)
356 .join_span(&self.select)
357 }
358}
359
360pub(crate) fn parse_create_constraint_definition<'a>(
361 parser: &mut Parser<'a, '_>,
362) -> Result<CreateDefinition<'a>, ParseError> {
363 let span = parser.consume_keyword(Keyword::CONSTRAINT)?;
364 let identifier = parser.consume_plain_identifier()?;
365 parser.consume_keywords(&[Keyword::FOREIGN, Keyword::KEY])?;
366 parser.consume_token(Token::LParen)?;
367 parser.consume_plain_identifier()?;
368 while parser.skip_token(Token::Comma).is_some() {
369 parser.consume_plain_identifier()?;
370 }
371 parser.consume_token(Token::RParen)?;
372 parser.consume_keyword(Keyword::REFERENCES)?;
373 parser.consume_plain_identifier()?;
374 parser.consume_token(Token::LParen)?;
375 parser.consume_plain_identifier()?;
376 while parser.skip_token(Token::Comma).is_some() {
377 parser.consume_plain_identifier()?;
378 }
379
380 parser.consume_token(Token::RParen)?;
381 if parser.skip_keyword(Keyword::ON).is_some() {
382 parser.consume_keyword(Keyword::DELETE)?;
383 match parser.token {
384 Token::Ident(_, Keyword::CASCADE) => {
385 parser.consume_keyword(Keyword::CASCADE)?;
386 }
387 Token::Ident(_, Keyword::DELETE) => {
388 parser.consume_keyword(Keyword::DELETE)?;
389 }
390 Token::Ident(_, Keyword::RESTRICT) => {
391 parser.consume_keyword(Keyword::RESTRICT)?;
392 }
393 Token::Ident(_, Keyword::SET) => {
394 parser.consume_keywords(&[Keyword::SET, Keyword::NULL])?;
395 }
396 _ => parser.expected_failure("CASCADE, DELETE OR SET NULL")?,
397 }
398 }
399 Ok(CreateDefinition::ConstraintDefinition { span, identifier })
400}
401
402pub(crate) fn parse_create_definition<'a>(
403 parser: &mut Parser<'a, '_>,
404) -> Result<CreateDefinition<'a>, ParseError> {
405 match &parser.token {
406 Token::Ident(_, Keyword::CONSTRAINT) => parse_create_constraint_definition(parser),
407 Token::Ident(_, _) => Ok(CreateDefinition::ColumnDefinition {
408 identifier: parser.consume_plain_identifier()?,
409 data_type: parse_data_type(parser, false)?,
410 }),
411 _ => parser.expected_failure("identifier"),
412 }
413}
414
415fn parse_create_view<'a>(
416 parser: &mut Parser<'a, '_>,
417 create_span: Span,
418 create_options: Vec<CreateOption<'a>>,
419) -> Result<Statement<'a>, ParseError> {
420 let view_span = parser.consume_keyword(Keyword::VIEW)?;
421
422 let if_not_exists = if let Some(if_) = parser.skip_keyword(Keyword::IF) {
423 Some(
424 parser
425 .consume_keywords(&[Keyword::NOT, Keyword::EXISTS])?
426 .join_span(&if_),
427 )
428 } else {
429 None
430 };
431
432 let name = parse_qualified_name(parser)?;
433 let as_span = parser.consume_keyword(Keyword::AS)?;
436
437 let select = parse_compound_query(parser)?;
438
439 Ok(Statement::CreateView(CreateView {
442 create_span,
443 create_options,
444 view_span,
445 if_not_exists,
446 name,
447 as_span,
448 select: Box::new(select),
449 }))
450}
451
452#[derive(Clone, Debug)]
454pub enum FunctionCharacteristic<'a> {
455 LanguageSql(Span),
456 LanguagePlpgsql(Span),
457 NotDeterministic(Span),
458 Deterministic(Span),
459 ContainsSql(Span),
460 NoSql(Span),
461 ReadsSqlData(Span),
462 ModifiesSqlData(Span),
463 SqlSecurityDefiner(Span),
464 SqlSecurityUser(Span),
465 Comment(SString<'a>),
466}
467
468impl<'a> Spanned for FunctionCharacteristic<'a> {
469 fn span(&self) -> Span {
470 match &self {
471 FunctionCharacteristic::LanguageSql(v) => v.span(),
472 FunctionCharacteristic::NotDeterministic(v) => v.span(),
473 FunctionCharacteristic::Deterministic(v) => v.span(),
474 FunctionCharacteristic::ContainsSql(v) => v.span(),
475 FunctionCharacteristic::NoSql(v) => v.span(),
476 FunctionCharacteristic::ReadsSqlData(v) => v.span(),
477 FunctionCharacteristic::ModifiesSqlData(v) => v.span(),
478 FunctionCharacteristic::SqlSecurityDefiner(v) => v.span(),
479 FunctionCharacteristic::SqlSecurityUser(v) => v.span(),
480 FunctionCharacteristic::Comment(v) => v.span(),
481 FunctionCharacteristic::LanguagePlpgsql(v) => v.span(),
482 }
483 }
484}
485
486#[derive(Clone, Debug)]
488pub enum FunctionParamDirection {
489 In(Span),
490 Out(Span),
491 InOut(Span),
492}
493
494impl Spanned for FunctionParamDirection {
495 fn span(&self) -> Span {
496 match &self {
497 FunctionParamDirection::In(v) => v.span(),
498 FunctionParamDirection::Out(v) => v.span(),
499 FunctionParamDirection::InOut(v) => v.span(),
500 }
501 }
502}
503
504#[derive(Clone, Debug)]
534pub struct CreateFunction<'a> {
535 pub create_span: Span,
537 pub create_options: Vec<CreateOption<'a>>,
539 pub function_span: Span,
541 pub if_not_exists: Option<Span>,
543 pub name: Identifier<'a>,
545 pub params: Vec<(Option<FunctionParamDirection>, Identifier<'a>, DataType<'a>)>,
547 pub returns_span: Span,
549 pub return_type: DataType<'a>,
551 pub characteristics: Vec<FunctionCharacteristic<'a>>,
553 pub return_: Option<Box<Statement<'a>>>,
555}
556
557impl<'a> Spanned for CreateFunction<'a> {
558 fn span(&self) -> Span {
559 self.create_span
560 .join_span(&self.create_options)
561 .join_span(&self.function_span)
562 .join_span(&self.if_not_exists)
563 .join_span(&self.name)
564 .join_span(&self.return_type)
565 .join_span(&self.characteristics)
566 .join_span(&self.return_)
567 }
568}
569
570fn parse_create_function<'a>(
571 parser: &mut Parser<'a, '_>,
572 create_span: Span,
573 create_options: Vec<CreateOption<'a>>,
574) -> Result<Statement<'a>, ParseError> {
575 let function_span = parser.consume_keyword(Keyword::FUNCTION)?;
576
577 let if_not_exists = if let Some(if_) = parser.skip_keyword(Keyword::IF) {
578 Some(
579 parser
580 .consume_keywords(&[Keyword::NOT, Keyword::EXISTS])?
581 .join_span(&if_),
582 )
583 } else {
584 None
585 };
586
587 let name = parser.consume_plain_identifier()?;
588 let mut params = Vec::new();
589 parser.consume_token(Token::LParen)?;
590 parser.recovered("')'", &|t| t == &Token::RParen, |parser| {
591 loop {
592 let direction = match &parser.token {
593 Token::Ident(_, Keyword::IN) => {
594 let in_ = parser.consume_keyword(Keyword::IN)?;
595 if let Some(out) = parser.skip_keyword(Keyword::OUT) {
596 Some(FunctionParamDirection::InOut(in_.join_span(&out)))
597 } else {
598 Some(FunctionParamDirection::In(in_))
599 }
600 }
601 Token::Ident(_, Keyword::OUT) => Some(FunctionParamDirection::Out(
602 parser.consume_keyword(Keyword::OUT)?,
603 )),
604 Token::Ident(_, Keyword::INOUT) => Some(FunctionParamDirection::InOut(
605 parser.consume_keyword(Keyword::INOUT)?,
606 )),
607 _ => None,
608 };
609
610 let name = parser.consume_plain_identifier()?;
611 let type_ = parse_data_type(parser, false)?;
612 params.push((direction, name, type_));
613 if parser.skip_token(Token::Comma).is_none() {
614 break;
615 }
616 }
617 Ok(())
618 })?;
619 parser.consume_token(Token::RParen)?;
620 let returns_span = parser.consume_keyword(Keyword::RETURNS)?;
621 let return_type = parse_data_type(parser, true)?;
622 if parser.options.dialect.is_postgresql() && parser.skip_keyword(Keyword::AS).is_some() {
623 parser.consume_token(Token::DoubleDollar)?;
624 loop {
625 match &parser.token {
626 Token::Eof | Token::DoubleDollar => {
627 parser.consume_token(Token::DoubleDollar)?;
628 break;
629 }
630 _ => {
631 parser.consume();
632 }
633 }
634 }
635 }
636
637 let mut characteristics = Vec::new();
638 loop {
639 let f = match &parser.token {
640 Token::Ident(_, Keyword::LANGUAGE) => {
641 let lg = parser.consume();
642 match &parser.token {
643 Token::Ident(_, Keyword::SQL) => {
644 FunctionCharacteristic::LanguageSql(lg.join_span(&parser.consume()))
645 }
646 Token::Ident(_, Keyword::PLPGSQL) => {
647 FunctionCharacteristic::LanguagePlpgsql(lg.join_span(&parser.consume()))
648 }
649 _ => parser.expected_failure("language name")?,
650 }
651 }
652 Token::Ident(_, Keyword::NOT) => FunctionCharacteristic::NotDeterministic(
653 parser.consume_keywords(&[Keyword::NOT, Keyword::DETERMINISTIC])?,
654 ),
655 Token::Ident(_, Keyword::DETERMINISTIC) => FunctionCharacteristic::Deterministic(
656 parser.consume_keyword(Keyword::DETERMINISTIC)?,
657 ),
658 Token::Ident(_, Keyword::CONTAINS) => FunctionCharacteristic::ContainsSql(
659 parser.consume_keywords(&[Keyword::CONTAINS, Keyword::SQL])?,
660 ),
661 Token::Ident(_, Keyword::NO) => FunctionCharacteristic::NoSql(
662 parser.consume_keywords(&[Keyword::NO, Keyword::SQL])?,
663 ),
664 Token::Ident(_, Keyword::READS) => {
665 FunctionCharacteristic::ReadsSqlData(parser.consume_keywords(&[
666 Keyword::READS,
667 Keyword::SQL,
668 Keyword::DATA,
669 ])?)
670 }
671 Token::Ident(_, Keyword::MODIFIES) => {
672 FunctionCharacteristic::ModifiesSqlData(parser.consume_keywords(&[
673 Keyword::MODIFIES,
674 Keyword::SQL,
675 Keyword::DATA,
676 ])?)
677 }
678 Token::Ident(_, Keyword::COMMENT) => {
679 parser.consume_keyword(Keyword::COMMENT)?;
680 FunctionCharacteristic::Comment(parser.consume_string()?)
681 }
682 Token::Ident(_, Keyword::SQL) => {
683 let span = parser.consume_keywords(&[Keyword::SQL, Keyword::SECURITY])?;
684 match &parser.token {
685 Token::Ident(_, Keyword::DEFINER) => {
686 FunctionCharacteristic::SqlSecurityDefiner(
687 parser.consume_keyword(Keyword::DEFINER)?.join_span(&span),
688 )
689 }
690 Token::Ident(_, Keyword::USER) => FunctionCharacteristic::SqlSecurityUser(
691 parser.consume_keyword(Keyword::USER)?.join_span(&span),
692 ),
693 _ => parser.expected_failure("'DEFINER' or 'USER'")?,
694 }
695 }
696 _ => break,
697 };
698 characteristics.push(f);
699 }
700
701 let return_ = if parser.options.dialect.is_maria() {
702 match parse_statement(parser)? {
703 Some(v) => Some(Box::new(v)),
704 None => parser.expected_failure("statement")?,
705 }
706 } else {
707 None
708 };
709
710 Ok(Statement::CreateFunction(CreateFunction {
711 create_span,
712 create_options,
713 function_span,
714 if_not_exists,
715 name,
716 params,
717 return_type,
718 characteristics,
719 return_,
720 returns_span,
721 }))
722}
723
724#[derive(Clone, Debug)]
726
727pub enum TriggerTime {
728 Before(Span),
729 After(Span),
730}
731
732impl Spanned for TriggerTime {
733 fn span(&self) -> Span {
734 match &self {
735 TriggerTime::Before(v) => v.span(),
736 TriggerTime::After(v) => v.span(),
737 }
738 }
739}
740
741#[derive(Clone, Debug)]
743pub enum TriggerEvent {
744 Update(Span),
745 Insert(Span),
746 Delete(Span),
747}
748
749impl Spanned for TriggerEvent {
750 fn span(&self) -> Span {
751 match &self {
752 TriggerEvent::Update(v) => v.span(),
753 TriggerEvent::Insert(v) => v.span(),
754 TriggerEvent::Delete(v) => v.span(),
755 }
756 }
757}
758
759#[derive(Clone, Debug)]
791pub struct CreateTrigger<'a> {
792 pub create_span: Span,
794 pub create_options: Vec<CreateOption<'a>>,
796 pub trigger_span: Span,
798 pub if_not_exists: Option<Span>,
800 pub name: Identifier<'a>,
802 pub trigger_time: TriggerTime,
804 pub trigger_event: TriggerEvent,
806 pub on_span: Span,
808 pub table: Identifier<'a>,
810 pub for_each_row_span: Span,
812 pub statement: Box<Statement<'a>>,
814}
815
816impl<'a> Spanned for CreateTrigger<'a> {
817 fn span(&self) -> Span {
818 self.create_span
819 .join_span(&self.create_options)
820 .join_span(&self.trigger_span)
821 .join_span(&self.if_not_exists)
822 .join_span(&self.name)
823 .join_span(&self.trigger_time)
824 .join_span(&self.trigger_event)
825 .join_span(&self.on_span)
826 .join_span(&self.table)
827 .join_span(&self.for_each_row_span)
828 .join_span(&self.statement)
829 }
830}
831
832fn parse_create_trigger<'a>(
833 parser: &mut Parser<'a, '_>,
834 create_span: Span,
835 create_options: Vec<CreateOption<'a>>,
836) -> Result<Statement<'a>, ParseError> {
837 let trigger_span = parser.consume_keyword(Keyword::TRIGGER)?;
838
839 let if_not_exists = if let Some(if_) = parser.skip_keyword(Keyword::IF) {
840 Some(
841 parser
842 .consume_keywords(&[Keyword::NOT, Keyword::EXISTS])?
843 .join_span(&if_),
844 )
845 } else {
846 None
847 };
848
849 let name = parser.consume_plain_identifier()?;
850
851 let trigger_time = match &parser.token {
852 Token::Ident(_, Keyword::AFTER) => {
853 TriggerTime::After(parser.consume_keyword(Keyword::AFTER)?)
854 }
855 Token::Ident(_, Keyword::BEFORE) => {
856 TriggerTime::Before(parser.consume_keyword(Keyword::BEFORE)?)
857 }
858 _ => parser.expected_failure("'BEFORE' or 'AFTER'")?,
859 };
860
861 let trigger_event = match &parser.token {
862 Token::Ident(_, Keyword::UPDATE) => {
863 TriggerEvent::Update(parser.consume_keyword(Keyword::UPDATE)?)
864 }
865 Token::Ident(_, Keyword::INSERT) => {
866 TriggerEvent::Insert(parser.consume_keyword(Keyword::INSERT)?)
867 }
868 Token::Ident(_, Keyword::DELETE) => {
869 TriggerEvent::Delete(parser.consume_keyword(Keyword::DELETE)?)
870 }
871 _ => parser.expected_failure("'UPDATE' or 'INSERT' or 'DELETE'")?,
872 };
873
874 let on_span = parser.consume_keyword(Keyword::ON)?;
875
876 let table = parser.consume_plain_identifier()?;
877
878 let for_each_row_span =
879 parser.consume_keywords(&[Keyword::FOR, Keyword::EACH, Keyword::ROW])?;
880
881 let old = core::mem::replace(&mut parser.permit_compound_statements, true);
884 let statement = match parse_statement(parser)? {
885 Some(v) => v,
886 None => parser.expected_failure("statement")?,
887 };
888 parser.permit_compound_statements = old;
889
890 Ok(Statement::CreateTrigger(CreateTrigger {
891 create_span,
892 create_options,
893 trigger_span,
894 if_not_exists,
895 name,
896 trigger_time,
897 trigger_event,
898 on_span,
899 table,
900 for_each_row_span,
901 statement: Box::new(statement),
902 }))
903}
904
905#[derive(Clone, Debug)]
906pub struct CreateTypeEnum<'a> {
907 pub create_span: Span,
909 pub create_options: Vec<CreateOption<'a>>,
911 pub type_span: Span,
913 pub name: Identifier<'a>,
915 pub as_enum_span: Span,
917 pub values: Vec<SString<'a>>,
919}
920
921impl<'a> Spanned for CreateTypeEnum<'a> {
922 fn span(&self) -> Span {
923 self.create_span
924 .join_span(&self.create_options)
925 .join_span(&self.type_span)
926 .join_span(&self.name)
927 .join_span(&self.as_enum_span)
928 .join_span(&self.values)
929 }
930}
931
932fn parse_create_type<'a>(
933 parser: &mut Parser<'a, '_>,
934 create_span: Span,
935 create_options: Vec<CreateOption<'a>>,
936) -> Result<Statement<'a>, ParseError> {
937 let type_span = parser.consume_keyword(Keyword::TYPE)?;
938 if !parser.options.dialect.is_postgresql() {
939 parser.err("CREATE TYPE only supported by postgresql", &type_span);
940 }
941 let name = parser.consume_plain_identifier()?;
942 let as_enum_span = parser.consume_keywords(&[Keyword::AS, Keyword::ENUM])?;
943 parser.consume_token(Token::LParen)?;
944 let mut values = Vec::new();
945 loop {
946 parser.recovered(
947 "')' or ','",
948 &|t| matches!(t, Token::RParen | Token::Comma),
949 |parser| {
950 values.push(parser.consume_string()?);
951 Ok(())
952 },
953 )?;
954 if matches!(parser.token, Token::RParen) {
955 break;
956 }
957 parser.consume_token(Token::Comma)?;
958 }
959 parser.consume_token(Token::RParen)?;
960 Ok(Statement::CreateTypeEnum(CreateTypeEnum {
961 create_span,
962 create_options,
963 type_span,
964 name,
965 as_enum_span,
966 values,
967 }))
968}
969
970#[derive(Clone, Debug)]
971pub enum CreateIndexOption {
972 UsingGist(Span),
973}
974
975impl Spanned for CreateIndexOption {
976 fn span(&self) -> Span {
977 match self {
978 CreateIndexOption::UsingGist(s) => s.clone(),
979 }
980 }
981}
982
983#[derive(Clone, Debug)]
984pub struct CreateIndex<'a> {
985 pub create_span: Span,
986 pub create_options: Vec<CreateOption<'a>>,
987 pub index_span: Span,
988 pub index_name: Identifier<'a>,
989 pub if_not_exists: Option<Span>,
990 pub on_span: Span,
991 pub table_name: QualifiedName<'a>,
992 pub index_options: Vec<CreateIndexOption>,
993 pub l_paren_span: Span,
994 pub column_names: Vec<Identifier<'a>>,
995 pub r_paren_span: Span,
996 pub where_: Option<(Span, Expression<'a>)>,
997}
998
999impl<'a> Spanned for CreateIndex<'a> {
1000 fn span(&self) -> Span {
1001 self.create_span
1002 .join_span(&self.create_options)
1003 .join_span(&self.index_span)
1004 .join_span(&self.index_name)
1005 .join_span(&self.on_span)
1006 .join_span(&self.table_name)
1007 .join_span(&self.index_options)
1008 .join_span(&self.l_paren_span)
1009 .join_span(&self.column_names)
1010 .join_span(&self.r_paren_span)
1011 .join_span(&self.where_)
1012 }
1013}
1014
1015fn parse_create_index<'a>(
1016 parser: &mut Parser<'a, '_>,
1017 create_span: Span,
1018 create_options: Vec<CreateOption<'a>>,
1019) -> Result<Statement<'a>, ParseError> {
1020 let index_span = parser.consume_keyword(Keyword::INDEX)?;
1021 let if_not_exists = if let Some(s) = parser.skip_keyword(Keyword::IF) {
1022 Some(s.join_span(&parser.consume_keywords(&[Keyword::NOT, Keyword::EXISTS])?))
1023 } else {
1024 None
1025 };
1026 let index_name = parser.consume_plain_identifier()?;
1027 let on_span = parser.consume_keyword(Keyword::ON)?;
1028 let table_name = parse_qualified_name(parser)?;
1029 let mut index_options = Vec::new();
1030 if let Some(using_span) = parser.skip_keyword(Keyword::USING) {
1031 let gist_span = parser.consume_keyword(Keyword::GIST)?;
1032 index_options.push(CreateIndexOption::UsingGist(
1033 gist_span.join_span(&using_span),
1034 ));
1035 }
1036 let l_paren_span = parser.consume_token(Token::LParen)?;
1037 let mut column_names = Vec::new();
1038 column_names.push(parser.consume_plain_identifier()?);
1039 while parser.skip_token(Token::Comma).is_some() {
1040 column_names.push(parser.consume_plain_identifier()?);
1041 }
1042 let r_paren_span = parser.consume_token(Token::RParen)?;
1043
1044 let mut where_ = None;
1045 if let Some(where_span) = parser.skip_keyword(Keyword::WHERE) {
1046 let where_expr = parse_expression(parser, false)?;
1047 if parser.options.dialect.is_maria() {
1048 parser.err(
1049 "Partial indexes not supported",
1050 &where_span.join_span(&where_expr),
1051 );
1052 }
1053 where_ = Some((where_span, where_expr));
1054 }
1055
1056 Ok(Statement::CreateIndex(CreateIndex {
1057 create_span,
1058 create_options,
1059 index_span,
1060 index_name,
1061 if_not_exists,
1062 on_span,
1063 table_name,
1064 index_options,
1065 l_paren_span,
1066 column_names,
1067 r_paren_span,
1068 where_,
1069 }))
1070}
1071
1072fn parse_create_table<'a>(
1073 parser: &mut Parser<'a, '_>,
1074 create_span: Span,
1075 create_options: Vec<CreateOption<'a>>,
1076) -> Result<Statement<'a>, ParseError> {
1077 let table_span = parser.consume_keyword(Keyword::TABLE)?;
1078
1079 let mut identifier = QualifiedName {
1080 identifier: Identifier::new("", 0..0),
1081 prefix: Default::default(),
1082 };
1083 let mut if_not_exists = None;
1084
1085 parser.recovered("'('", &|t| t == &Token::LParen, |parser| {
1086 if let Some(if_) = parser.skip_keyword(Keyword::IF) {
1087 if_not_exists = Some(
1088 if_.start
1089 ..parser
1090 .consume_keywords(&[Keyword::NOT, Keyword::EXISTS])?
1091 .end,
1092 );
1093 }
1094 identifier = parse_qualified_name(parser)?;
1095 Ok(())
1096 })?;
1097
1098 parser.consume_token(Token::LParen)?;
1099
1100 let mut create_definitions = Vec::new();
1101 if !matches!(parser.token, Token::RParen) {
1102 loop {
1103 parser.recovered(
1104 "')' or ','",
1105 &|t| matches!(t, Token::RParen | Token::Comma),
1106 |parser| {
1107 create_definitions.push(parse_create_definition(parser)?);
1108 Ok(())
1109 },
1110 )?;
1111 if matches!(parser.token, Token::RParen) {
1112 break;
1113 }
1114 parser.consume_token(Token::Comma)?;
1115 }
1116 }
1117 parser.consume_token(Token::RParen)?;
1118
1119 let mut options = Vec::new();
1120 let delimiter = parser.delimiter.clone();
1121 parser.recovered(
1122 delimiter.name(),
1123 &|t| t == &Token::Eof || t == &delimiter,
1124 |parser| {
1125 loop {
1126 let identifier = parser.span.clone();
1127 match &parser.token {
1128 Token::Ident(_, Keyword::ENGINE) => {
1129 parser.consume_keyword(Keyword::ENGINE)?;
1130 parser.skip_token(Token::Eq);
1131 options.push(TableOption::Engine {
1132 identifier,
1133 value: parser.consume_plain_identifier()?,
1134 });
1135 }
1136 Token::Ident(_, Keyword::DEFAULT) => {
1137 parser.consume_keyword(Keyword::DEFAULT)?;
1138 match &parser.token {
1139 Token::Ident(_, Keyword::CHARSET) => {
1140 parser.consume_keyword(Keyword::CHARSET)?;
1141 parser.skip_token(Token::Eq);
1142 options.push(TableOption::DefaultCharSet {
1143 identifier,
1144 value: parser.consume_plain_identifier()?,
1145 });
1146 }
1147 Token::Ident(_, Keyword::COLLATE) => {
1148 parser.consume_keyword(Keyword::COLLATE)?;
1149 parser.skip_token(Token::Eq);
1150 options.push(TableOption::DefaultCollate {
1151 identifier,
1152 value: parser.consume_plain_identifier()?,
1153 });
1154 }
1155 _ => parser.expected_failure("'CHARSET' or 'COLLATE'")?,
1156 }
1157 }
1158 Token::Ident(_, Keyword::CHARSET) => {
1159 parser.consume_keyword(Keyword::CHARSET)?;
1160 parser.skip_token(Token::Eq);
1161 options.push(TableOption::CharSet {
1162 identifier,
1163 value: parser.consume_plain_identifier()?,
1164 });
1165 }
1166 Token::Ident(_, Keyword::COLLATE) => {
1167 parser.consume_keyword(Keyword::COLLATE)?;
1168 parser.skip_token(Token::Eq);
1169 options.push(TableOption::Collate {
1170 identifier,
1171 value: parser.consume_plain_identifier()?,
1172 });
1173 }
1174 Token::Ident(_, Keyword::ROW_FORMAT) => {
1175 parser.consume_keyword(Keyword::ROW_FORMAT)?;
1176 parser.skip_token(Token::Eq);
1177 options.push(TableOption::RowFormat {
1178 identifier,
1179 value: parser.consume_plain_identifier()?,
1180 });
1181 }
1183 Token::Ident(_, Keyword::COMMENT) => {
1184 parser.consume_keyword(Keyword::COMMENT)?;
1185 parser.skip_token(Token::Eq);
1186 options.push(TableOption::Comment {
1187 identifier,
1188 value: parser.consume_string()?,
1189 });
1190 }
1191 Token::Ident(_, Keyword::STRICT) => {
1192 parser.consume_keyword(Keyword::STRICT)?;
1193 options.push(TableOption::Strict { identifier });
1194 }
1195 t if t == &parser.delimiter => break,
1196 Token::Eof => break,
1197 _ => {
1198 parser.expected_failure("table option or delimiter")?;
1199 }
1200 }
1201 }
1202 Ok(())
1203 },
1204 )?;
1205
1206 Ok(Statement::CreateTable(CreateTable {
1207 create_span,
1208 create_options,
1209 table_span,
1210 identifier,
1211 if_not_exists,
1212 options,
1213 create_definitions,
1214 }))
1215}
1216
1217pub(crate) fn parse_create<'a>(parser: &mut Parser<'a, '_>) -> Result<Statement<'a>, ParseError> {
1218 let create_span = parser.span.clone();
1219 parser.consume_keyword(Keyword::CREATE)?;
1220
1221 let mut create_options = Vec::new();
1222 const CREATABLE: &str = "'TABLE' | 'VIEW' | 'TRIGGER' | 'FUNCTION' | 'INDEX' | 'TYPE'";
1223
1224 parser.recovered(
1225 CREATABLE,
1226 &|t| {
1227 matches!(
1228 t,
1229 Token::Ident(
1230 _,
1231 Keyword::TABLE
1232 | Keyword::VIEW
1233 | Keyword::TRIGGER
1234 | Keyword::FUNCTION
1235 | Keyword::INDEX
1236 | Keyword::TYPE
1237 )
1238 )
1239 },
1240 |parser| {
1241 loop {
1242 let v = match &parser.token {
1243 Token::Ident(_, Keyword::OR) => CreateOption::OrReplace(
1244 parser.consume_keywords(&[Keyword::OR, Keyword::REPLACE])?,
1245 ),
1246 Token::Ident(_, Keyword::TEMPORARY) => {
1247 CreateOption::Temporary(parser.consume_keyword(Keyword::TEMPORARY)?)
1248 }
1249 Token::Ident(_, Keyword::UNIQUE) => {
1250 CreateOption::Unique(parser.consume_keyword(Keyword::UNIQUE)?)
1251 }
1252 Token::Ident(_, Keyword::ALGORITHM) => {
1253 let algorithm_span = parser.consume_keyword(Keyword::ALGORITHM)?;
1254 parser.consume_token(Token::Eq)?;
1255 let algorithm = match &parser.token {
1256 Token::Ident(_, Keyword::UNDEFINED) => CreateAlgorithm::Undefined(
1257 parser.consume_keyword(Keyword::UNDEFINED)?,
1258 ),
1259 Token::Ident(_, Keyword::MERGE) => {
1260 CreateAlgorithm::Merge(parser.consume_keyword(Keyword::MERGE)?)
1261 }
1262 Token::Ident(_, Keyword::TEMPTABLE) => CreateAlgorithm::TempTable(
1263 parser.consume_keyword(Keyword::TEMPTABLE)?,
1264 ),
1265 _ => parser.expected_failure("'UNDEFINED', 'MERGE' or 'TEMPTABLE'")?,
1266 };
1267 CreateOption::Algorithm(algorithm_span, algorithm)
1268 }
1269 Token::Ident(_, Keyword::DEFINER) => {
1270 let definer_span = parser.consume_keyword(Keyword::DEFINER)?;
1271 parser.consume_token(Token::Eq)?;
1272 let user = parser.consume_plain_identifier()?;
1274 parser.consume_token(Token::At)?;
1275 let host = parser.consume_plain_identifier()?;
1276 CreateOption::Definer {
1277 definer_span,
1278 user,
1279 host,
1280 }
1281 }
1282 Token::Ident(_, Keyword::SQL) => {
1283 let sql_security =
1284 parser.consume_keywords(&[Keyword::SQL, Keyword::SECURITY])?;
1285 match &parser.token {
1286 Token::Ident(_, Keyword::DEFINER) => CreateOption::SqlSecurityDefiner(
1287 sql_security,
1288 parser.consume_keyword(Keyword::DEFINER)?,
1289 ),
1290 Token::Ident(_, Keyword::USER) => CreateOption::SqlSecurityUser(
1291 sql_security,
1292 parser.consume_keyword(Keyword::USER)?,
1293 ),
1294 _ => parser.expected_failure("'DEFINER', 'USER'")?,
1295 }
1296 }
1297 _ => break,
1298 };
1299 create_options.push(v);
1300 }
1301 Ok(())
1302 },
1303 )?;
1304
1305 match &parser.token {
1306 Token::Ident(_, Keyword::INDEX) => parse_create_index(parser, create_span, create_options),
1307 Token::Ident(_, Keyword::TABLE) => parse_create_table(parser, create_span, create_options),
1308 Token::Ident(_, Keyword::VIEW) => parse_create_view(parser, create_span, create_options),
1309 Token::Ident(_, Keyword::FUNCTION) => {
1310 parse_create_function(parser, create_span, create_options)
1311 }
1312 Token::Ident(_, Keyword::TRIGGER) => {
1313 parse_create_trigger(parser, create_span, create_options)
1314 }
1315 Token::Ident(_, Keyword::TYPE) => parse_create_type(parser, create_span, create_options),
1316 _ => parser.expected_failure(CREATABLE),
1317 }
1318}