1use crate::{
14 DataType, Expression, Identifier, QualifiedName, SString, Span, Spanned, Statement,
15 alter_table::{
16 ForeignKeyMatch, ForeignKeyOn, ForeignKeyOnAction, ForeignKeyOnType, IndexCol, IndexOption,
17 IndexType, parse_index_cols, parse_index_options, parse_index_type,
18 },
19 create_option::CreateOption,
20 data_type::{DataTypeContext, parse_data_type},
21 expression::{PRIORITY_MAX, parse_expression_unreserved},
22 keywords::{Keyword, Restrict},
23 lexer::{StringType, Token},
24 parser::{ParseError, Parser},
25 qualified_name::parse_qualified_name_unreserved,
26 statement::parse_compound_query,
27};
28use alloc::boxed::Box;
29use alloc::vec::Vec;
30
31#[derive(Clone, Debug)]
33pub enum OnCommitAction {
34 PreserveRows(Span),
35 DeleteRows(Span),
36 Drop(Span),
37}
38
39impl Spanned for OnCommitAction {
40 fn span(&self) -> Span {
41 match self {
42 OnCommitAction::PreserveRows(s) => s.span(),
43 OnCommitAction::DeleteRows(s) => s.span(),
44 OnCommitAction::Drop(s) => s.span(),
45 }
46 }
47}
48
49#[derive(Clone, Debug)]
51pub enum TableOption<'a> {
52 AutoExtendSize {
53 identifier: Span,
54 value: (usize, Span),
55 },
56 AutoIncrement {
57 identifier: Span,
58 value: (u64, Span),
59 },
60 AvgRowLength {
61 identifier: Span,
62 value: (usize, Span),
63 },
64 CharSet {
65 identifier: Span,
66 value: Identifier<'a>,
67 },
68 DefaultCharSet {
69 identifier: Span,
70 value: Identifier<'a>,
71 },
72 Checksum {
73 identifier: Span,
74 value: (bool, Span),
75 },
76 Collate {
77 identifier: Span,
78 value: Identifier<'a>,
79 },
80 DefaultCollate {
81 identifier: Span,
82 value: Identifier<'a>,
83 },
84 Comment {
85 identifier: Span,
86 value: SString<'a>,
87 },
88 Compression {
89 identifier: Span,
90 value: SString<'a>,
91 },
92 Connection {
93 identifier: Span,
94 value: SString<'a>,
95 },
96 DataDirectory {
97 identifier: Span,
98 value: SString<'a>,
99 },
100 IndexDirectory {
101 identifier: Span,
102 value: SString<'a>,
103 },
104 DelayKeyWrite {
105 identifier: Span,
106 value: (bool, Span),
107 },
108 Encryption {
109 identifier: Span,
110 value: (bool, Span),
111 },
112 Engine {
113 identifier: Span,
114 value: Identifier<'a>,
115 },
116 EngineAttribute {
117 identifier: Span,
118 value: SString<'a>,
119 },
120 InsertMethod {
121 identifier: Span,
122 value: Identifier<'a>,
123 },
124 KeyBlockSize {
125 identifier: Span,
126 value: (usize, Span),
127 },
128 MaxRows {
129 identifier: Span,
130 value: (usize, Span),
131 },
132 MinRows {
133 identifier: Span,
134 value: (usize, Span),
135 },
136 PackKeys {
137 identifier: Span,
138 value: (usize, Span),
139 },
140 Password {
141 identifier: Span,
142 value: SString<'a>,
143 },
144 RowFormat {
145 identifier: Span,
146 value: Identifier<'a>,
147 },
148 SecondaryEngineAttribute {
149 identifier: Span,
150 value: SString<'a>,
151 },
152 StartTransaction {
153 identifier: Span,
154 },
155 StatsAutoRecalc {
156 identifier: Span,
157 value: (usize, Span),
158 },
159 StatsPersistent {
160 identifier: Span,
161 value: (usize, Span),
162 },
163 StatsSamplePages {
164 identifier: Span,
165 value: (usize, Span),
166 },
167 Storage {
168 identifier: Span,
169 value: Identifier<'a>,
170 },
171 Strict {
172 identifier: Span,
173 },
174 Tablespace {
175 identifier: Span,
176 value: Identifier<'a>,
177 },
178 Union {
179 identifier: Span,
180 value: Vec<Identifier<'a>>,
181 },
182 Inherits {
183 identifier: Span,
184 value: Vec<QualifiedName<'a>>,
185 },
186 WithOptions {
188 identifier: Span,
189 options: Vec<(Identifier<'a>, Expression<'a>)>,
190 },
191 OnCommit {
193 identifier: Span,
194 action: OnCommitAction,
195 },
196}
197
198impl<'a> Spanned for TableOption<'a> {
199 fn span(&self) -> Span {
200 match &self {
201 TableOption::AutoExtendSize { identifier, value } => identifier.span().join_span(value),
202 TableOption::AutoIncrement { identifier, value } => identifier.span().join_span(value),
203 TableOption::AvgRowLength { identifier, value } => identifier.span().join_span(value),
204 TableOption::CharSet { identifier, value } => identifier.span().join_span(value),
205 TableOption::DefaultCharSet { identifier, value } => identifier.span().join_span(value),
206 TableOption::Checksum { identifier, value } => identifier.span().join_span(value),
207 TableOption::Collate { identifier, value } => identifier.span().join_span(value),
208 TableOption::DefaultCollate { identifier, value } => identifier.span().join_span(value),
209 TableOption::Comment { identifier, value } => identifier.span().join_span(value),
210 TableOption::Compression { identifier, value } => identifier.span().join_span(value),
211 TableOption::Connection { identifier, value } => identifier.span().join_span(value),
212 TableOption::DataDirectory { identifier, value } => identifier.span().join_span(value),
213 TableOption::IndexDirectory { identifier, value } => identifier.span().join_span(value),
214 TableOption::DelayKeyWrite { identifier, value } => identifier.span().join_span(value),
215 TableOption::Encryption { identifier, value } => identifier.span().join_span(value),
216 TableOption::Engine { identifier, value } => identifier.span().join_span(value),
217 TableOption::EngineAttribute { identifier, value } => {
218 identifier.span().join_span(value)
219 }
220 TableOption::InsertMethod { identifier, value } => identifier.span().join_span(value),
221 TableOption::KeyBlockSize { identifier, value } => identifier.span().join_span(value),
222 TableOption::MaxRows { identifier, value } => identifier.span().join_span(value),
223 TableOption::MinRows { identifier, value } => identifier.span().join_span(value),
224 TableOption::PackKeys { identifier, value } => identifier.span().join_span(value),
225 TableOption::Password { identifier, value } => identifier.span().join_span(value),
226 TableOption::RowFormat { identifier, value } => identifier.span().join_span(value),
227 TableOption::SecondaryEngineAttribute { identifier, value } => {
228 identifier.span().join_span(value)
229 }
230 TableOption::StartTransaction { identifier } => identifier.span(),
231 TableOption::StatsAutoRecalc { identifier, value } => {
232 identifier.span().join_span(value)
233 }
234 TableOption::StatsPersistent { identifier, value } => {
235 identifier.span().join_span(value)
236 }
237 TableOption::StatsSamplePages { identifier, value } => {
238 identifier.span().join_span(value)
239 }
240 TableOption::Storage { identifier, value } => identifier.span().join_span(value),
241 TableOption::Strict { identifier } => identifier.span(),
242 TableOption::Tablespace { identifier, value } => identifier.span().join_span(value),
243 TableOption::Union { identifier, value } => {
244 if let Some(last) = value.last() {
245 identifier.span().join_span(last)
246 } else {
247 identifier.span()
248 }
249 }
250 TableOption::Inherits { identifier, value } => {
251 if let Some(last) = value.last() {
252 identifier.span().join_span(last)
253 } else {
254 identifier.span()
255 }
256 }
257 TableOption::WithOptions {
258 identifier,
259 options,
260 } => {
261 if let Some((_, last)) = options.last() {
262 identifier.span().join_span(last)
263 } else {
264 identifier.span()
265 }
266 }
267 TableOption::OnCommit { identifier, action } => identifier.span().join_span(action),
268 }
269 }
270}
271
272#[derive(Clone, Debug)]
274pub enum CreateDefinition<'a> {
275 ColumnDefinition {
276 identifier: Identifier<'a>,
278 data_type: DataType<'a>,
280 },
281 IndexDefinition {
283 constraint_span: Option<Span>,
285 constraint_symbol: Option<Identifier<'a>>,
287 index_type: IndexType,
289 index_name: Option<Identifier<'a>>,
291 cols: Vec<IndexCol<'a>>,
293 index_options: Vec<IndexOption<'a>>,
295 },
296 ForeignKeyDefinition {
298 constraint_span: Option<Span>,
300 constraint_symbol: Option<Identifier<'a>>,
302 foreign_key_span: Span,
304 index_name: Option<Identifier<'a>>,
306 cols: Vec<IndexCol<'a>>,
308 references_span: Span,
310 references_table: Identifier<'a>,
312 references_cols: Vec<Identifier<'a>>,
314 match_type: Option<ForeignKeyMatch>,
316 ons: Vec<ForeignKeyOn>,
318 },
319 CheckConstraintDefinition {
321 constraint_span: Option<Span>,
323 constraint_symbol: Option<Identifier<'a>>,
325 check_span: Span,
327 expression: Expression<'a>,
329 enforced: Option<(bool, Span)>,
331 },
332}
333
334impl<'a> Spanned for CreateDefinition<'a> {
335 fn span(&self) -> Span {
336 match &self {
337 CreateDefinition::ColumnDefinition {
338 identifier,
339 data_type,
340 } => identifier.span().join_span(data_type),
341 CreateDefinition::IndexDefinition {
342 constraint_span,
343 constraint_symbol,
344 index_type,
345 index_name,
346 cols,
347 index_options,
348 } => index_type
349 .span()
350 .join_span(constraint_span)
351 .join_span(constraint_symbol)
352 .join_span(index_name)
353 .join_span(cols)
354 .join_span(index_options),
355 CreateDefinition::ForeignKeyDefinition {
356 constraint_span,
357 constraint_symbol,
358 foreign_key_span,
359 index_name,
360 cols,
361 references_span,
362 references_table,
363 references_cols,
364 match_type,
365 ons,
366 } => foreign_key_span
367 .span()
368 .join_span(constraint_span)
369 .join_span(constraint_symbol)
370 .join_span(index_name)
371 .join_span(cols)
372 .join_span(references_span)
373 .join_span(references_table)
374 .join_span(references_cols)
375 .join_span(match_type)
376 .join_span(ons),
377 CreateDefinition::CheckConstraintDefinition {
378 constraint_span,
379 constraint_symbol,
380 check_span,
381 expression,
382 enforced,
383 } => check_span
384 .span()
385 .join_span(constraint_span)
386 .join_span(constraint_symbol)
387 .join_span(expression)
388 .join_span(enforced),
389 }
390 }
391}
392
393#[derive(Clone, Debug)]
394pub struct CreateTableAs<'a> {
395 pub ignore_span: Option<Span>,
396 pub replace_span: Option<Span>,
397 pub as_span: Span,
398 pub query: Statement<'a>,
399}
400
401impl Spanned for CreateTableAs<'_> {
402 fn span(&self) -> Span {
403 self.as_span
404 .join_span(&self.replace_span)
405 .join_span(&self.ignore_span)
406 .join_span(&self.query)
407 }
408}
409
410#[derive(Clone, Debug)]
412pub enum PartitionMethod {
413 Range(Span),
414 List(Span),
415 Hash(Span),
416}
417
418impl Spanned for PartitionMethod {
419 fn span(&self) -> Span {
420 match self {
421 PartitionMethod::Range(s) => s.span(),
422 PartitionMethod::List(s) => s.span(),
423 PartitionMethod::Hash(s) => s.span(),
424 }
425 }
426}
427
428#[derive(Clone, Debug)]
430pub struct PartitionBy<'a> {
431 pub partition_by_span: Span,
433 pub method: PartitionMethod,
435 pub keys: Vec<Expression<'a>>,
437}
438
439impl<'a> Spanned for PartitionBy<'a> {
440 fn span(&self) -> Span {
441 self.partition_by_span
442 .join_span(&self.method)
443 .join_span(&self.keys)
444 }
445}
446
447#[derive(Clone, Debug)]
449pub enum PartitionBoundExpr<'a> {
450 Expr(Expression<'a>),
451 MinValue(Span),
452 MaxValue(Span),
453}
454
455impl<'a> Spanned for PartitionBoundExpr<'a> {
456 fn span(&self) -> Span {
457 match self {
458 PartitionBoundExpr::Expr(e) => e.span(),
459 PartitionBoundExpr::MinValue(s) => s.span(),
460 PartitionBoundExpr::MaxValue(s) => s.span(),
461 }
462 }
463}
464
465#[derive(Clone, Debug)]
467pub enum PartitionBoundSpec<'a> {
468 In {
470 in_span: Span,
471 values: Vec<PartitionBoundExpr<'a>>,
472 },
473 FromTo {
475 from_span: Span,
476 from_values: Vec<PartitionBoundExpr<'a>>,
477 to_span: Span,
478 to_values: Vec<PartitionBoundExpr<'a>>,
479 },
480 WithModulusRemainder {
482 with_span: Span,
483 modulus_span: Span,
484 modulus: (u64, Span),
485 remainder_span: Span,
486 remainder: (u64, Span),
487 },
488}
489
490impl<'a> Spanned for PartitionBoundSpec<'a> {
491 fn span(&self) -> Span {
492 match self {
493 PartitionBoundSpec::In { in_span, values } => in_span.join_span(values),
494 PartitionBoundSpec::FromTo {
495 from_span,
496 from_values: _,
497 to_span,
498 to_values,
499 } => from_span.join_span(to_span).join_span(to_values),
500 PartitionBoundSpec::WithModulusRemainder {
501 with_span,
502 modulus_span,
503 modulus,
504 remainder_span,
505 remainder,
506 } => with_span
507 .join_span(modulus_span)
508 .join_span(modulus)
509 .join_span(remainder_span)
510 .join_span(remainder),
511 }
512 }
513}
514
515#[derive(Clone, Debug)]
517pub enum PartitionOfBound<'a> {
518 ForValues {
520 for_values_span: Span,
521 spec: PartitionBoundSpec<'a>,
522 },
523 Default(Span),
525}
526
527impl<'a> Spanned for PartitionOfBound<'a> {
528 fn span(&self) -> Span {
529 match self {
530 PartitionOfBound::ForValues {
531 for_values_span,
532 spec,
533 } => for_values_span.join_span(spec),
534 PartitionOfBound::Default(s) => s.span(),
535 }
536 }
537}
538
539#[derive(Clone, Debug)]
541pub struct CreateTablePartitionOf<'a> {
542 pub create_span: Span,
544 pub create_options: Vec<CreateOption<'a>>,
546 pub table_span: Span,
548 pub if_not_exists: Option<Span>,
550 pub identifier: QualifiedName<'a>,
552 pub partition_of_span: Span,
554 pub parent_table: QualifiedName<'a>,
556 pub create_definitions: Vec<CreateDefinition<'a>>,
558 pub bound: PartitionOfBound<'a>,
560 pub partition_by: Option<PartitionBy<'a>>,
562}
563
564impl<'a> Spanned for CreateTablePartitionOf<'a> {
565 fn span(&self) -> Span {
566 self.create_span
567 .join_span(&self.create_options)
568 .join_span(&self.table_span)
569 .join_span(&self.if_not_exists)
570 .join_span(&self.identifier)
571 .join_span(&self.partition_of_span)
572 .join_span(&self.parent_table)
573 .join_span(&self.create_definitions)
574 .join_span(&self.bound)
575 .join_span(&self.partition_by)
576 }
577}
578
579#[derive(Clone, Debug)]
605pub struct CreateTable<'a> {
606 pub create_span: Span,
608 pub create_options: Vec<CreateOption<'a>>,
610 pub table_span: Span,
612 pub identifier: QualifiedName<'a>,
614 pub if_not_exists: Option<Span>,
616 pub create_definitions: Vec<CreateDefinition<'a>>,
618 pub options: Vec<TableOption<'a>>,
620 pub table_as: Option<CreateTableAs<'a>>,
622 pub partition_by: Option<PartitionBy<'a>>,
624}
625
626impl<'a> Spanned for CreateTable<'a> {
627 fn span(&self) -> Span {
628 self.create_span
629 .join_span(&self.create_options)
630 .join_span(&self.table_span)
631 .join_span(&self.identifier)
632 .join_span(&self.if_not_exists)
633 .join_span(&self.create_definitions)
634 .join_span(&self.options)
635 .join_span(&self.table_as)
636 .join_span(&self.partition_by)
637 }
638}
639
640fn parse_foreign_key_definition<'a>(
642 parser: &mut Parser<'a, '_>,
643 constraint_span: Option<Span>,
644 constraint_symbol: Option<Identifier<'a>>,
645) -> Result<CreateDefinition<'a>, ParseError> {
646 let foreign_span = parser.consume_keyword(Keyword::FOREIGN)?;
647 let key_span = parser.consume_keyword(Keyword::KEY)?;
648 let foreign_key_span = foreign_span.join_span(&key_span);
649
650 let index_name = if let Token::Ident(_, _) = parser.token {
652 if !matches!(parser.token, Token::LParen) {
653 Some(parser.consume_plain_identifier_unreserved()?)
654 } else {
655 None
656 }
657 } else {
658 None
659 };
660
661 let cols = parse_index_cols(parser)?;
663
664 let references_span = parser.consume_keyword(Keyword::REFERENCES)?;
666 let references_table = parser.consume_plain_identifier_unreserved()?;
667
668 parser.consume_token(Token::LParen)?;
670 let mut references_cols = Vec::new();
671 loop {
672 references_cols.push(parser.consume_plain_identifier_unreserved()?);
673 if parser.skip_token(Token::Comma).is_none() {
674 break;
675 }
676 }
677 parser.consume_token(Token::RParen)?;
678
679 let match_type = if parser.skip_keyword(Keyword::MATCH).is_some() {
680 match &parser.token {
681 Token::Ident(_, Keyword::FULL) => Some(ForeignKeyMatch::Full(parser.consume())),
682 Token::Ident(_, Keyword::SIMPLE) => Some(ForeignKeyMatch::Simple(parser.consume())),
683 Token::Ident(_, Keyword::PARTIAL) => Some(ForeignKeyMatch::Partial(parser.consume())),
684 _ => None,
685 }
686 } else {
687 None
688 };
689
690 let mut ons = Vec::new();
692 while parser.skip_keyword(Keyword::ON).is_some() {
693 let on_type = match &parser.token {
694 Token::Ident(_, Keyword::UPDATE) => {
695 ForeignKeyOnType::Update(parser.consume_keyword(Keyword::UPDATE)?)
696 }
697 Token::Ident(_, Keyword::DELETE) => {
698 ForeignKeyOnType::Delete(parser.consume_keyword(Keyword::DELETE)?)
699 }
700 _ => parser.expected_failure("UPDATE or DELETE")?,
701 };
702
703 let on_action = match &parser.token {
704 Token::Ident(_, Keyword::CASCADE) => {
705 ForeignKeyOnAction::Cascade(parser.consume_keyword(Keyword::CASCADE)?)
706 }
707 Token::Ident(_, Keyword::RESTRICT) => {
708 ForeignKeyOnAction::Restrict(parser.consume_keyword(Keyword::RESTRICT)?)
709 }
710 Token::Ident(_, Keyword::SET) => {
711 let set_span = parser.consume_keyword(Keyword::SET)?;
712 if parser.skip_keyword(Keyword::NULL).is_some() {
713 ForeignKeyOnAction::SetNull(set_span)
714 } else if parser.skip_keyword(Keyword::DEFAULT).is_some() {
715 ForeignKeyOnAction::SetDefault(set_span)
716 } else {
717 parser.expected_failure("NULL or DEFAULT after SET")?
718 }
719 }
720 Token::Ident(_, Keyword::NO) => {
721 let no_span = parser.consume_keyword(Keyword::NO)?;
722 parser.consume_keyword(Keyword::ACTION)?;
723 ForeignKeyOnAction::NoAction(no_span)
724 }
725 _ => {
726 parser.expected_failure("CASCADE, RESTRICT, SET NULL, SET DEFAULT, or NO ACTION")?
727 }
728 };
729
730 ons.push(ForeignKeyOn {
731 type_: on_type,
732 action: on_action,
733 });
734 }
735
736 Ok(CreateDefinition::ForeignKeyDefinition {
737 constraint_span,
738 constraint_symbol,
739 foreign_key_span,
740 index_name,
741 cols,
742 references_span,
743 references_table,
744 references_cols,
745 match_type,
746 ons,
747 })
748}
749
750fn parse_check_constraint_definition<'a>(
752 parser: &mut Parser<'a, '_>,
753 constraint_span: Option<Span>,
754 constraint_symbol: Option<Identifier<'a>>,
755) -> Result<CreateDefinition<'a>, ParseError> {
756 let check_span = parser.consume_keyword(Keyword::CHECK)?;
757
758 parser.consume_token(Token::LParen)?;
760 let expression = parse_expression_unreserved(parser, PRIORITY_MAX)?;
761 parser.consume_token(Token::RParen)?;
762
763 let enforced = None;
766
767 Ok(CreateDefinition::CheckConstraintDefinition {
768 constraint_span,
769 constraint_symbol,
770 check_span,
771 expression,
772 enforced,
773 })
774}
775
776pub(crate) fn parse_create_definition<'a>(
777 parser: &mut Parser<'a, '_>,
778) -> Result<CreateDefinition<'a>, ParseError> {
779 let constraint_span = parser.skip_keyword(Keyword::CONSTRAINT);
781
782 let constraint_symbol = if constraint_span.is_some() {
784 if let Token::Ident(_, keyword) = parser.token {
785 match keyword {
787 Keyword::PRIMARY
788 | Keyword::UNIQUE
789 | Keyword::FULLTEXT
790 | Keyword::SPATIAL
791 | Keyword::INDEX
792 | Keyword::KEY
793 | Keyword::FOREIGN
794 | Keyword::CHECK => None,
795 _ => Some(parser.consume_plain_identifier_unreserved()?),
796 }
797 } else {
798 None
799 }
800 } else {
801 None
802 };
803
804 let index_type = match &parser.token {
805 Token::Ident(_, Keyword::PRIMARY) => {
806 let span = parser.consume_keywords(&[Keyword::PRIMARY, Keyword::KEY])?;
807 IndexType::Primary(span)
808 }
809 Token::Ident(_, Keyword::UNIQUE) => {
810 let span = parser.consume_keyword(Keyword::UNIQUE)?;
811 let span = if let Some(s) = parser.skip_keyword(Keyword::INDEX) {
812 span.join_span(&s)
813 } else if let Some(s) = parser.skip_keyword(Keyword::KEY) {
814 span.join_span(&s)
815 } else {
816 span
817 };
818 IndexType::Unique(span)
819 }
820 Token::Ident(_, Keyword::FULLTEXT) => {
821 let span = parser.consume_keyword(Keyword::FULLTEXT)?;
822 let span = if let Some(s) = parser.skip_keyword(Keyword::INDEX) {
823 span.join_span(&s)
824 } else if let Some(s) = parser.skip_keyword(Keyword::KEY) {
825 span.join_span(&s)
826 } else {
827 span
828 };
829 IndexType::FullText(span)
830 }
831 Token::Ident(_, Keyword::SPATIAL) => {
832 let span = parser.consume_keyword(Keyword::SPATIAL)?;
833 let span = if let Some(s) = parser.skip_keyword(Keyword::INDEX) {
834 span.join_span(&s)
835 } else if let Some(s) = parser.skip_keyword(Keyword::KEY) {
836 span.join_span(&s)
837 } else {
838 span
839 };
840 IndexType::Spatial(span)
841 }
842 Token::Ident(_, Keyword::INDEX) => {
843 IndexType::Index(parser.consume_keyword(Keyword::INDEX)?)
844 }
845 Token::Ident(_, Keyword::KEY) => IndexType::Index(parser.consume_keyword(Keyword::KEY)?),
846 Token::Ident(_, Keyword::FOREIGN) => {
847 return parse_foreign_key_definition(parser, constraint_span, constraint_symbol);
848 }
849 Token::Ident(_, Keyword::CHECK) => {
850 return parse_check_constraint_definition(parser, constraint_span, constraint_symbol);
851 }
852 Token::String(_, StringType::DoubleQuoted) if parser.options.dialect.is_postgresql() => {
853 if constraint_span.is_some() {
856 parser.expected_failure(
857 "PRIMARY, UNIQUE, INDEX, KEY, FULLTEXT, SPATIAL, FOREIGN, or CHECK",
858 )?
859 }
860 return Ok(CreateDefinition::ColumnDefinition {
861 identifier: parser.consume_plain_identifier_unreserved()?,
862 data_type: parse_data_type(parser, DataTypeContext::Column)?,
863 });
864 }
865 Token::Ident(_, _) => {
866 if constraint_span.is_some() {
868 parser.expected_failure(
869 "PRIMARY, UNIQUE, INDEX, KEY, FULLTEXT, SPATIAL, FOREIGN, or CHECK",
870 )?
871 }
872 return Ok(CreateDefinition::ColumnDefinition {
873 identifier: parser.consume_plain_identifier_unreserved()?,
874 data_type: parse_data_type(parser, DataTypeContext::Column)?,
875 });
876 }
877 _ => return parser.expected_failure("identifier"),
878 };
879
880 let index_name = match &index_type {
882 IndexType::Primary(_) => {
883 match &parser.token {
885 Token::Ident(_, _) if !matches!(parser.token, Token::LParen) => {
886 Some(parser.consume_plain_identifier_unreserved()?)
887 }
888 Token::String(s, _) => {
889 let val = *s;
890 let span = parser.consume();
891 Some(Identifier { value: val, span })
892 }
893 _ => None,
894 }
895 }
896 _ => {
897 match &parser.token {
899 Token::Ident(_, _)
900 if !matches!(
901 parser.token,
902 Token::LParen | Token::Ident(_, Keyword::USING)
903 ) =>
904 {
905 Some(parser.consume_plain_identifier_restrict(Restrict::USING)?)
906 }
907 Token::String(s, _) => {
908 let val = *s;
909 let span = parser.consume();
910 Some(Identifier { value: val, span })
911 }
912 _ => None,
913 }
914 }
915 };
916
917 let mut index_options = Vec::new();
919 if matches!(parser.token, Token::Ident(_, Keyword::USING)) {
920 parse_index_type(parser, &mut index_options)?;
921 }
922
923 let cols = parse_index_cols(parser)?;
925
926 parse_index_options(parser, &mut index_options)?;
928
929 Ok(CreateDefinition::IndexDefinition {
930 constraint_span,
931 constraint_symbol,
932 index_type,
933 index_name,
934 cols,
935 index_options,
936 })
937}
938
939fn parse_partition_by<'a>(parser: &mut Parser<'a, '_>) -> Result<PartitionBy<'a>, ParseError> {
941 let partition_span = parser.consume_keyword(Keyword::PARTITION)?;
942 let by_span = parser.consume_keyword(Keyword::BY)?;
943 let partition_by_span = partition_span.join_span(&by_span);
944
945 let method = match &parser.token {
946 Token::Ident(_, Keyword::RANGE) => {
947 PartitionMethod::Range(parser.consume_keyword(Keyword::RANGE)?)
948 }
949 Token::Ident(_, Keyword::LIST) => {
950 PartitionMethod::List(parser.consume_keyword(Keyword::LIST)?)
951 }
952 Token::Ident(_, Keyword::HASH) => {
953 PartitionMethod::Hash(parser.consume_keyword(Keyword::HASH)?)
954 }
955 _ => parser.expected_failure("RANGE, LIST, or HASH")?,
956 };
957
958 parser.consume_token(Token::LParen)?;
959 let mut keys = Vec::new();
960 loop {
961 let key = if matches!(parser.token, Token::LParen) {
963 parser.consume_token(Token::LParen)?;
964 let expr = parse_expression_unreserved(parser, PRIORITY_MAX)?;
965 parser.consume_token(Token::RParen)?;
966 expr
967 } else {
968 parse_expression_unreserved(parser, PRIORITY_MAX)?
969 };
970 keys.push(key);
971 if parser.skip_token(Token::Comma).is_none() {
972 break;
973 }
974 }
975 parser.consume_token(Token::RParen)?;
976
977 Ok(PartitionBy {
978 partition_by_span,
979 method,
980 keys,
981 })
982}
983
984fn parse_partition_bound_expr<'a>(
986 parser: &mut Parser<'a, '_>,
987) -> Result<PartitionBoundExpr<'a>, ParseError> {
988 match &parser.token {
989 Token::Ident(_, Keyword::MINVALUE) => Ok(PartitionBoundExpr::MinValue(
990 parser.consume_keyword(Keyword::MINVALUE)?,
991 )),
992 Token::Ident(_, Keyword::MAXVALUE) => Ok(PartitionBoundExpr::MaxValue(
993 parser.consume_keyword(Keyword::MAXVALUE)?,
994 )),
995 _ => Ok(PartitionBoundExpr::Expr(parse_expression_unreserved(
996 parser,
997 PRIORITY_MAX,
998 )?)),
999 }
1000}
1001
1002fn parse_partition_bound_exprs<'a>(
1004 parser: &mut Parser<'a, '_>,
1005) -> Result<Vec<PartitionBoundExpr<'a>>, ParseError> {
1006 parser.consume_token(Token::LParen)?;
1007 let mut values = Vec::new();
1008 loop {
1009 values.push(parse_partition_bound_expr(parser)?);
1010 if parser.skip_token(Token::Comma).is_none() {
1011 break;
1012 }
1013 }
1014 parser.consume_token(Token::RParen)?;
1015 Ok(values)
1016}
1017
1018fn parse_partition_bound_spec<'a>(
1020 parser: &mut Parser<'a, '_>,
1021) -> Result<PartitionBoundSpec<'a>, ParseError> {
1022 match &parser.token {
1023 Token::Ident(_, Keyword::IN) => {
1024 let in_span = parser.consume_keyword(Keyword::IN)?;
1025 let values = parse_partition_bound_exprs(parser)?;
1026 Ok(PartitionBoundSpec::In { in_span, values })
1027 }
1028 Token::Ident(_, Keyword::FROM) => {
1029 let from_span = parser.consume_keyword(Keyword::FROM)?;
1030 let from_values = parse_partition_bound_exprs(parser)?;
1031 let to_span = parser.consume_keyword(Keyword::TO)?;
1032 let to_values = parse_partition_bound_exprs(parser)?;
1033 Ok(PartitionBoundSpec::FromTo {
1034 from_span,
1035 from_values,
1036 to_span,
1037 to_values,
1038 })
1039 }
1040 Token::Ident(_, Keyword::WITH) => {
1041 let with_span = parser.consume_keyword(Keyword::WITH)?;
1042 parser.consume_token(Token::LParen)?;
1043 let modulus_span = parser.consume_keyword(Keyword::MODULUS)?;
1044 let modulus = parser.consume_int::<u64>()?;
1045 parser.consume_token(Token::Comma)?;
1046 let remainder_span = parser.consume_keyword(Keyword::REMAINDER)?;
1047 let remainder = parser.consume_int::<u64>()?;
1048 parser.consume_token(Token::RParen)?;
1049 Ok(PartitionBoundSpec::WithModulusRemainder {
1050 with_span,
1051 modulus_span,
1052 modulus,
1053 remainder_span,
1054 remainder,
1055 })
1056 }
1057 _ => parser.expected_failure("IN, FROM, or WITH"),
1058 }
1059}
1060
1061pub(crate) fn parse_create_table<'a>(
1062 parser: &mut Parser<'a, '_>,
1063 create_span: Span,
1064 create_options: Vec<CreateOption<'a>>,
1065 table_span: Span,
1066 if_not_exists: Option<Span>,
1067 identifier: QualifiedName<'a>,
1068) -> Result<CreateTable<'a>, ParseError> {
1069 parser.consume_token(Token::LParen)?;
1070
1071 let mut create_definitions = Vec::new();
1072 if !matches!(parser.token, Token::RParen) {
1073 loop {
1074 parser.recovered(
1075 "')' or ','",
1076 &|t| matches!(t, Token::RParen | Token::Comma),
1077 |parser| {
1078 create_definitions.push(parse_create_definition(parser)?);
1079 Ok(())
1080 },
1081 )?;
1082 if matches!(parser.token, Token::RParen) {
1083 break;
1084 }
1085 parser.consume_token(Token::Comma)?;
1086 }
1087 }
1088 parser.consume_token(Token::RParen)?;
1089
1090 let mut options = Vec::new();
1091 let mut table_as: Option<CreateTableAs<'_>> = None;
1092 let mut partition_by: Option<PartitionBy<'_>> = None;
1093 let delimiter_name = parser.lexer.delimiter_name();
1094 parser.recovered(
1095 delimiter_name,
1096 &|t| t == &Token::Eof || t == &Token::Delimiter,
1097 |parser| {
1098 loop {
1099 match &parser.token {
1100 Token::Ident(_, Keyword::ENGINE) => {
1101 let identifier = parser.consume_keyword(Keyword::ENGINE)?;
1102 parser.skip_token(Token::Eq);
1103 options.push(TableOption::Engine {
1104 identifier,
1105 value: parser.consume_plain_identifier_unreserved()?,
1106 });
1107 }
1108 Token::Ident(_, Keyword::DEFAULT) => {
1109 let default_span = parser.consume_keyword(Keyword::DEFAULT)?;
1110 match &parser.token {
1111 Token::Ident(_, Keyword::CHARSET) => {
1112 let identifier = default_span
1113 .join_span(&parser.consume_keyword(Keyword::CHARSET)?);
1114 parser.skip_token(Token::Eq);
1115 options.push(TableOption::DefaultCharSet {
1116 identifier,
1117 value: parser.consume_plain_identifier_unreserved()?,
1118 });
1119 }
1120 Token::Ident(_, Keyword::COLLATE) => {
1121 let identifier = default_span
1122 .join_span(&parser.consume_keyword(Keyword::COLLATE)?);
1123 parser.skip_token(Token::Eq);
1124 options.push(TableOption::DefaultCollate {
1125 identifier,
1126 value: parser.consume_plain_identifier_unreserved()?,
1127 });
1128 }
1129 _ => parser.expected_failure("'CHARSET' or 'COLLATE'")?,
1130 }
1131 }
1132 Token::Ident(_, Keyword::CHARSET) => {
1133 let identifier = parser.consume_keyword(Keyword::CHARSET)?;
1134 parser.skip_token(Token::Eq);
1135 options.push(TableOption::CharSet {
1136 identifier,
1137 value: parser.consume_plain_identifier_unreserved()?,
1138 });
1139 }
1140 Token::Ident(_, Keyword::COLLATE) => {
1141 let identifier = parser.consume_keyword(Keyword::COLLATE)?;
1142 parser.skip_token(Token::Eq);
1143 options.push(TableOption::Collate {
1144 identifier,
1145 value: parser.consume_plain_identifier_unreserved()?,
1146 });
1147 }
1148 Token::Ident(_, Keyword::ROW_FORMAT) => {
1149 let identifier = parser.consume_keyword(Keyword::ROW_FORMAT)?;
1150 parser.skip_token(Token::Eq);
1151 options.push(TableOption::RowFormat {
1152 identifier,
1153 value: parser.consume_plain_identifier_unreserved()?,
1154 });
1155 }
1157 Token::Ident(_, Keyword::KEY_BLOCK_SIZE) => {
1158 let identifier = parser.consume_keywords(&[Keyword::KEY_BLOCK_SIZE])?;
1159 parser.skip_token(Token::Eq);
1160 options.push(TableOption::KeyBlockSize {
1161 identifier,
1162 value: parser.consume_int()?,
1163 });
1164 }
1165 Token::Ident(_, Keyword::COMMENT) => {
1166 let identifier = parser.consume_keyword(Keyword::COMMENT)?;
1167 parser.skip_token(Token::Eq);
1168 options.push(TableOption::Comment {
1169 identifier,
1170 value: parser.consume_string()?,
1171 });
1172 }
1173 Token::Ident(_, Keyword::STRICT) => {
1174 let identifier = parser.consume_keyword(Keyword::STRICT)?;
1175 options.push(TableOption::Strict { identifier });
1176 }
1177 Token::Ident(_, Keyword::AUTO_INCREMENT) => {
1178 let identifier = parser.consume_keyword(Keyword::AUTO_INCREMENT)?;
1179 parser.skip_token(Token::Eq);
1180 options.push(TableOption::AutoIncrement {
1181 identifier,
1182 value: parser.consume_int()?,
1183 });
1184 }
1185 Token::Ident(_, Keyword::DATA) => {
1186 let identifier =
1187 parser.consume_keywords(&[Keyword::DATA, Keyword::DIRECTORY])?;
1188 parser.skip_token(Token::Eq);
1189 options.push(TableOption::DataDirectory {
1190 identifier,
1191 value: parser.consume_string()?,
1192 });
1193 }
1194 Token::Ident(_, Keyword::INDEX) => {
1195 let identifier =
1196 parser.consume_keywords(&[Keyword::INDEX, Keyword::DIRECTORY])?;
1197 parser.skip_token(Token::Eq);
1198 options.push(TableOption::IndexDirectory {
1199 identifier,
1200 value: parser.consume_string()?,
1201 });
1202 }
1203 Token::Ident(_, Keyword::INSERT_METHOD) => {
1204 let identifier = parser.consume_keyword(Keyword::INSERT_METHOD)?;
1205 parser.skip_token(Token::Eq);
1206 options.push(TableOption::InsertMethod {
1207 identifier,
1208 value: parser.consume_plain_identifier_unreserved()?,
1209 });
1210 }
1211 Token::Ident(_, Keyword::PACK_KEYS) => {
1212 let identifier = parser.consume_keyword(Keyword::PACK_KEYS)?;
1213 parser.skip_token(Token::Eq);
1214 options.push(TableOption::PackKeys {
1215 identifier,
1216 value: parser.consume_int()?,
1217 });
1218 }
1219 Token::Ident(_, Keyword::STATS_AUTO_RECALC) => {
1220 let identifier = parser.consume_keyword(Keyword::STATS_AUTO_RECALC)?;
1221 parser.skip_token(Token::Eq);
1222 options.push(TableOption::StatsAutoRecalc {
1223 identifier,
1224 value: parser.consume_int()?,
1225 });
1226 }
1227 Token::Ident(_, Keyword::STATS_PERSISTENT) => {
1228 let identifier = parser.consume_keyword(Keyword::STATS_PERSISTENT)?;
1229 parser.skip_token(Token::Eq);
1230 options.push(TableOption::StatsPersistent {
1231 identifier,
1232 value: parser.consume_int()?,
1233 });
1234 }
1235 Token::Ident(_, Keyword::STATS_SAMPLE_PAGES) => {
1236 let identifier = parser.consume_keyword(Keyword::STATS_SAMPLE_PAGES)?;
1237 parser.skip_token(Token::Eq);
1238 options.push(TableOption::StatsSamplePages {
1239 identifier,
1240 value: parser.consume_int()?,
1241 });
1242 }
1243 Token::Ident(_, Keyword::DELAY_KEY_WRITE) => {
1244 let identifier = parser.consume_keyword(Keyword::DELAY_KEY_WRITE)?;
1245 parser.skip_token(Token::Eq);
1246 let (val, span) = parser.consume_int::<usize>()?;
1247 options.push(TableOption::DelayKeyWrite {
1248 identifier,
1249 value: (val != 0, span),
1250 });
1251 }
1252 Token::Ident(_, Keyword::COMPRESSION) => {
1253 let identifier = parser.consume_keyword(Keyword::COMPRESSION)?;
1254 parser.skip_token(Token::Eq);
1255 options.push(TableOption::Compression {
1256 identifier,
1257 value: parser.consume_string()?,
1258 });
1259 }
1260 Token::Ident(_, Keyword::ENCRYPTION) => {
1261 let identifier = parser.consume_keyword(Keyword::ENCRYPTION)?;
1262 parser.skip_token(Token::Eq);
1263 let value = match &parser.token {
1265 Token::String(..) => {
1266 let s = parser.consume_string()?;
1267 let is_yes = s.as_str().eq_ignore_ascii_case("y")
1268 || s.as_str().eq_ignore_ascii_case("yes");
1269 (is_yes, s.span())
1270 }
1271 _ => {
1272 let id = parser.consume_plain_identifier_unreserved()?;
1273 let is_yes = id.value.eq_ignore_ascii_case("yes");
1274 (is_yes, id.span())
1275 }
1276 };
1277 options.push(TableOption::Encryption { identifier, value });
1278 }
1279 Token::Ident(_, Keyword::MAX_ROWS) => {
1280 let identifier = parser.consume_keyword(Keyword::MAX_ROWS)?;
1281 parser.skip_token(Token::Eq);
1282 options.push(TableOption::MaxRows {
1283 identifier,
1284 value: parser.consume_int()?,
1285 });
1286 }
1287 Token::Ident(_, Keyword::MIN_ROWS) => {
1288 let identifier = parser.consume_keyword(Keyword::MIN_ROWS)?;
1289 parser.skip_token(Token::Eq);
1290 options.push(TableOption::MinRows {
1291 identifier,
1292 value: parser.consume_int()?,
1293 });
1294 }
1295 Token::Ident(_, Keyword::AUTOEXTEND_SIZE) => {
1296 let identifier = parser.consume_keyword(Keyword::AUTOEXTEND_SIZE)?;
1297 parser.skip_token(Token::Eq);
1298 options.push(TableOption::AutoExtendSize {
1299 identifier,
1300 value: parser.consume_int()?,
1301 });
1302 }
1303 Token::Ident(_, Keyword::AVG_ROW_LENGTH) => {
1304 let identifier = parser.consume_keyword(Keyword::AVG_ROW_LENGTH)?;
1305 parser.skip_token(Token::Eq);
1306 options.push(TableOption::AvgRowLength {
1307 identifier,
1308 value: parser.consume_int()?,
1309 });
1310 }
1311 Token::Ident(_, Keyword::CHECKSUM) => {
1312 let identifier = parser.consume_keyword(Keyword::CHECKSUM)?;
1313 parser.skip_token(Token::Eq);
1314 let (val, span) = parser.consume_int::<usize>()?;
1315 options.push(TableOption::Checksum {
1316 identifier,
1317 value: (val != 0, span),
1318 });
1319 }
1320 Token::Ident(_, Keyword::CONNECTION) => {
1321 let identifier = parser.consume_keyword(Keyword::CONNECTION)?;
1322 parser.skip_token(Token::Eq);
1323 options.push(TableOption::Connection {
1324 identifier,
1325 value: parser.consume_string()?,
1326 });
1327 }
1328 Token::Ident(_, Keyword::ENGINE_ATTRIBUTE) => {
1329 let identifier = parser.consume_keyword(Keyword::ENGINE_ATTRIBUTE)?;
1330 parser.skip_token(Token::Eq);
1331 options.push(TableOption::EngineAttribute {
1332 identifier,
1333 value: parser.consume_string()?,
1334 });
1335 }
1336 Token::Ident(_, Keyword::PASSWORD) => {
1337 let identifier = parser.consume_keyword(Keyword::PASSWORD)?;
1338 parser.skip_token(Token::Eq);
1339 options.push(TableOption::Password {
1340 identifier,
1341 value: parser.consume_string()?,
1342 });
1343 }
1344 Token::Ident(_, Keyword::SECONDARY_ENGINE_ATTRIBUTE) => {
1345 let identifier =
1346 parser.consume_keyword(Keyword::SECONDARY_ENGINE_ATTRIBUTE)?;
1347 parser.skip_token(Token::Eq);
1348 options.push(TableOption::SecondaryEngineAttribute {
1349 identifier,
1350 value: parser.consume_string()?,
1351 });
1352 }
1353 Token::Ident(_, Keyword::START) => {
1354 let identifier =
1355 parser.consume_keywords(&[Keyword::START, Keyword::TRANSACTION])?;
1356 options.push(TableOption::StartTransaction { identifier });
1357 }
1358 Token::Ident(_, Keyword::TABLESPACE) => {
1359 let identifier = parser.consume_keyword(Keyword::TABLESPACE)?;
1360 options.push(TableOption::Tablespace {
1361 identifier,
1362 value: parser.consume_plain_identifier_unreserved()?,
1363 });
1364 }
1365 Token::Ident(_, Keyword::STORAGE) => {
1366 let identifier = parser.consume_keyword(Keyword::STORAGE)?;
1367 options.push(TableOption::Storage {
1368 identifier,
1369 value: parser.consume_plain_identifier_unreserved()?,
1370 });
1371 }
1372 Token::Ident(_, Keyword::UNION) => {
1373 let identifier = parser.consume_keyword(Keyword::UNION)?;
1374 parser.skip_token(Token::Eq);
1375 parser.consume_token(Token::LParen)?;
1376 let mut tables = Vec::new();
1377 loop {
1378 tables.push(parser.consume_plain_identifier_unreserved()?);
1379 if parser.skip_token(Token::Comma).is_none() {
1380 break;
1381 }
1382 }
1383 parser.consume_token(Token::RParen)?;
1384 options.push(TableOption::Union {
1385 identifier,
1386 value: tables,
1387 });
1388 }
1389 Token::Ident(_, Keyword::INHERITS) => {
1390 let identifier = parser.consume_keyword(Keyword::INHERITS)?;
1391 parser.postgres_only(&identifier);
1392 parser.consume_token(Token::LParen)?;
1393 let mut tables = Vec::new();
1394 parser.recovered("')'", &|t| t == &Token::RParen, |parser| {
1395 loop {
1396 tables.push(parse_qualified_name_unreserved(parser)?);
1397 if parser.skip_token(Token::Comma).is_none() {
1398 break;
1399 }
1400 }
1401 Ok(())
1402 })?;
1403 parser.consume_token(Token::RParen)?;
1404 options.push(TableOption::Inherits {
1405 identifier,
1406 value: tables,
1407 });
1408 }
1409 Token::Ident(_, Keyword::WITH) => {
1410 let identifier = parser.consume_keyword(Keyword::WITH)?;
1411 parser.postgres_only(&identifier);
1412 parser.consume_token(Token::LParen)?;
1413 let mut params = Vec::new();
1414 parser.recovered("')'", &|t| t == &Token::RParen, |parser| {
1415 loop {
1416 let key = parser.consume_plain_identifier_unreserved()?;
1417 parser.consume_token(Token::Eq)?;
1418 let val = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1419 params.push((key, val));
1420 if parser.skip_token(Token::Comma).is_none() {
1421 break;
1422 }
1423 }
1424 Ok(())
1425 })?;
1426 parser.consume_token(Token::RParen)?;
1427 options.push(TableOption::WithOptions {
1428 identifier,
1429 options: params,
1430 });
1431 }
1432 Token::Ident(_, Keyword::ON) => {
1433 let identifier =
1434 parser.consume_keywords(&[Keyword::ON, Keyword::COMMIT])?;
1435 parser.postgres_only(&identifier);
1436 let action = match &parser.token {
1437 Token::Ident(_, Keyword::PRESERVE) => OnCommitAction::PreserveRows(
1438 parser.consume_keywords(&[Keyword::PRESERVE, Keyword::ROWS])?,
1439 ),
1440 Token::Ident(_, Keyword::DELETE) => OnCommitAction::DeleteRows(
1441 parser.consume_keywords(&[Keyword::DELETE, Keyword::ROWS])?,
1442 ),
1443 Token::Ident(_, Keyword::DROP) => {
1444 OnCommitAction::Drop(parser.consume_keyword(Keyword::DROP)?)
1445 }
1446 _ => parser.expected_failure("PRESERVE ROWS, DELETE ROWS, or DROP")?,
1447 };
1448 options.push(TableOption::OnCommit { identifier, action });
1449 }
1450 Token::Ident(_, Keyword::PARTITION) => {
1451 partition_by = Some(parse_partition_by(parser)?);
1452 }
1453 Token::Ident(_, Keyword::IGNORE)
1454 | Token::Ident(_, Keyword::REPLACE)
1455 | Token::Ident(_, Keyword::AS) => {
1456 let ignore_span = parser.skip_keyword(Keyword::IGNORE);
1457 let replace_span = parser.skip_keyword(Keyword::REPLACE);
1458 let as_span = parser.consume_keyword(Keyword::AS)?;
1459
1460 if let Some(table_as) = &table_as {
1461 parser.err("Multiple AS clauses not supported", table_as);
1462 }
1463
1464 let query = parse_compound_query(parser)?;
1465 table_as = Some(CreateTableAs {
1466 as_span,
1467 replace_span,
1468 ignore_span,
1469 query,
1470 });
1471 }
1472 Token::Comma => {
1473 parser.consume_token(Token::Comma)?;
1474 }
1475 Token::Delimiter => break,
1476 Token::Eof => break,
1477 _ => {
1478 parser.expected_failure("table option or delimiter")?;
1479 }
1480 }
1481 }
1482 Ok(())
1483 },
1484 )?;
1485
1486 Ok(CreateTable {
1487 create_span,
1488 create_options,
1489 table_span,
1490 identifier,
1491 if_not_exists,
1492 options,
1493 create_definitions,
1494 table_as,
1495 partition_by,
1496 })
1497}
1498
1499fn parse_create_table_partition_of<'a>(
1500 parser: &mut Parser<'a, '_>,
1501 create_span: Span,
1502 create_options: Vec<CreateOption<'a>>,
1503 table_span: Span,
1504 if_not_exists: Option<Span>,
1505 identifier: QualifiedName<'a>,
1506) -> Result<CreateTablePartitionOf<'a>, ParseError> {
1507 let partition_span = parser.consume_keyword(Keyword::PARTITION)?;
1508 let of_span = parser.consume_keyword(Keyword::OF)?;
1509 let partition_of_span = partition_span.join_span(&of_span);
1510
1511 let parent_table = parse_qualified_name_unreserved(parser)?;
1512
1513 let mut create_definitions = Vec::new();
1515 if matches!(parser.token, Token::LParen) {
1516 parser.consume_token(Token::LParen)?;
1517 if !matches!(parser.token, Token::RParen) {
1518 loop {
1519 parser.recovered(
1520 "')' or ','",
1521 &|t| matches!(t, Token::RParen | Token::Comma),
1522 |parser| {
1523 create_definitions.push(parse_create_definition(parser)?);
1524 Ok(())
1525 },
1526 )?;
1527 if matches!(parser.token, Token::RParen) {
1528 break;
1529 }
1530 parser.consume_token(Token::Comma)?;
1531 }
1532 }
1533 parser.consume_token(Token::RParen)?;
1534 }
1535
1536 let bound = match &parser.token {
1538 Token::Ident(_, Keyword::DEFAULT) => {
1539 PartitionOfBound::Default(parser.consume_keyword(Keyword::DEFAULT)?)
1540 }
1541 Token::Ident(_, Keyword::FOR) => {
1542 let for_values_span = parser.consume_keywords(&[Keyword::FOR, Keyword::VALUES])?;
1543 let spec = parse_partition_bound_spec(parser)?;
1544 PartitionOfBound::ForValues {
1545 for_values_span,
1546 spec,
1547 }
1548 }
1549 _ => parser.expected_failure("FOR VALUES or DEFAULT")?,
1550 };
1551
1552 let partition_by = if matches!(parser.token, Token::Ident(_, Keyword::PARTITION)) {
1554 Some(parse_partition_by(parser)?)
1555 } else {
1556 None
1557 };
1558
1559 Ok(CreateTablePartitionOf {
1560 create_span,
1561 create_options,
1562 table_span,
1563 if_not_exists,
1564 identifier,
1565 partition_of_span,
1566 parent_table,
1567 create_definitions,
1568 bound,
1569 partition_by,
1570 })
1571}
1572
1573pub(crate) fn parse_create_table_or_partition_of<'a>(
1578 parser: &mut Parser<'a, '_>,
1579 create_span: Span,
1580 create_options: Vec<CreateOption<'a>>,
1581) -> Result<Statement<'a>, ParseError> {
1582 let table_span = parser.consume_keyword(Keyword::TABLE)?;
1583
1584 let if_not_exists = if let Some(if_) = parser.skip_keyword(Keyword::IF) {
1585 Some(
1586 if_.start
1587 ..parser
1588 .consume_keywords(&[Keyword::NOT, Keyword::EXISTS])?
1589 .end,
1590 )
1591 } else {
1592 None
1593 };
1594 let identifier = parse_qualified_name_unreserved(parser)?;
1595
1596 if matches!(parser.token, Token::Ident(_, Keyword::PARTITION)) {
1597 Ok(Statement::CreateTablePartitionOf(Box::new(
1598 parse_create_table_partition_of(
1599 parser,
1600 create_span,
1601 create_options,
1602 table_span,
1603 if_not_exists,
1604 identifier,
1605 )?,
1606 )))
1607 } else if matches!(parser.token, Token::Ident(_, Keyword::AS))
1608 && !matches!(parser.peek(), Token::LParen)
1609 {
1610 let as_span = parser.consume_keyword(Keyword::AS)?;
1612 let query = parse_compound_query(parser)?;
1613 Ok(Statement::CreateTable(Box::new(CreateTable {
1614 create_span,
1615 create_options,
1616 table_span,
1617 identifier,
1618 if_not_exists,
1619 options: alloc::vec![],
1620 create_definitions: alloc::vec![],
1621 table_as: Some(CreateTableAs {
1622 as_span,
1623 replace_span: None,
1624 ignore_span: None,
1625 query,
1626 }),
1627 partition_by: None,
1628 })))
1629 } else {
1630 Ok(Statement::CreateTable(Box::new(parse_create_table(
1631 parser,
1632 create_span,
1633 create_options,
1634 table_span,
1635 if_not_exists,
1636 identifier,
1637 )?)))
1638 }
1639}