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 LikeTable {
334 like_span: Span,
336 source_table: QualifiedName<'a>,
338 },
339}
340
341impl<'a> Spanned for CreateDefinition<'a> {
342 fn span(&self) -> Span {
343 match &self {
344 CreateDefinition::ColumnDefinition {
345 identifier,
346 data_type,
347 } => identifier.span().join_span(data_type),
348 CreateDefinition::IndexDefinition {
349 constraint_span,
350 constraint_symbol,
351 index_type,
352 index_name,
353 cols,
354 index_options,
355 } => index_type
356 .span()
357 .join_span(constraint_span)
358 .join_span(constraint_symbol)
359 .join_span(index_name)
360 .join_span(cols)
361 .join_span(index_options),
362 CreateDefinition::ForeignKeyDefinition {
363 constraint_span,
364 constraint_symbol,
365 foreign_key_span,
366 index_name,
367 cols,
368 references_span,
369 references_table,
370 references_cols,
371 match_type,
372 ons,
373 } => foreign_key_span
374 .span()
375 .join_span(constraint_span)
376 .join_span(constraint_symbol)
377 .join_span(index_name)
378 .join_span(cols)
379 .join_span(references_span)
380 .join_span(references_table)
381 .join_span(references_cols)
382 .join_span(match_type)
383 .join_span(ons),
384 CreateDefinition::CheckConstraintDefinition {
385 constraint_span,
386 constraint_symbol,
387 check_span,
388 expression,
389 enforced,
390 } => check_span
391 .span()
392 .join_span(constraint_span)
393 .join_span(constraint_symbol)
394 .join_span(expression)
395 .join_span(enforced),
396 CreateDefinition::LikeTable {
397 like_span,
398 source_table,
399 } => like_span.join_span(source_table),
400 }
401 }
402}
403
404#[derive(Clone, Debug)]
405pub struct CreateTableAs<'a> {
406 pub ignore_span: Option<Span>,
407 pub replace_span: Option<Span>,
408 pub as_span: Span,
409 pub query: Statement<'a>,
410}
411
412impl Spanned for CreateTableAs<'_> {
413 fn span(&self) -> Span {
414 self.as_span
415 .join_span(&self.replace_span)
416 .join_span(&self.ignore_span)
417 .join_span(&self.query)
418 }
419}
420
421#[derive(Clone, Debug)]
423pub enum PartitionMethod {
424 Range(Span),
425 List(Span),
426 Hash(Span),
427}
428
429impl Spanned for PartitionMethod {
430 fn span(&self) -> Span {
431 match self {
432 PartitionMethod::Range(s) => s.span(),
433 PartitionMethod::List(s) => s.span(),
434 PartitionMethod::Hash(s) => s.span(),
435 }
436 }
437}
438
439#[derive(Clone, Debug)]
441pub struct PartitionBy<'a> {
442 pub partition_by_span: Span,
444 pub method: PartitionMethod,
446 pub keys: Vec<Expression<'a>>,
448}
449
450impl<'a> Spanned for PartitionBy<'a> {
451 fn span(&self) -> Span {
452 self.partition_by_span
453 .join_span(&self.method)
454 .join_span(&self.keys)
455 }
456}
457
458#[derive(Clone, Debug)]
460pub enum PartitionBoundExpr<'a> {
461 Expr(Expression<'a>),
462 MinValue(Span),
463 MaxValue(Span),
464}
465
466impl<'a> Spanned for PartitionBoundExpr<'a> {
467 fn span(&self) -> Span {
468 match self {
469 PartitionBoundExpr::Expr(e) => e.span(),
470 PartitionBoundExpr::MinValue(s) => s.span(),
471 PartitionBoundExpr::MaxValue(s) => s.span(),
472 }
473 }
474}
475
476#[derive(Clone, Debug)]
478pub enum PartitionBoundSpec<'a> {
479 In {
481 in_span: Span,
482 values: Vec<PartitionBoundExpr<'a>>,
483 },
484 FromTo {
486 from_span: Span,
487 from_values: Vec<PartitionBoundExpr<'a>>,
488 to_span: Span,
489 to_values: Vec<PartitionBoundExpr<'a>>,
490 },
491 WithModulusRemainder {
493 with_span: Span,
494 modulus_span: Span,
495 modulus: (u64, Span),
496 remainder_span: Span,
497 remainder: (u64, Span),
498 },
499}
500
501impl<'a> Spanned for PartitionBoundSpec<'a> {
502 fn span(&self) -> Span {
503 match self {
504 PartitionBoundSpec::In { in_span, values } => in_span.join_span(values),
505 PartitionBoundSpec::FromTo {
506 from_span,
507 from_values: _,
508 to_span,
509 to_values,
510 } => from_span.join_span(to_span).join_span(to_values),
511 PartitionBoundSpec::WithModulusRemainder {
512 with_span,
513 modulus_span,
514 modulus,
515 remainder_span,
516 remainder,
517 } => with_span
518 .join_span(modulus_span)
519 .join_span(modulus)
520 .join_span(remainder_span)
521 .join_span(remainder),
522 }
523 }
524}
525
526#[derive(Clone, Debug)]
528pub enum PartitionOfBound<'a> {
529 ForValues {
531 for_values_span: Span,
532 spec: PartitionBoundSpec<'a>,
533 },
534 Default(Span),
536}
537
538impl<'a> Spanned for PartitionOfBound<'a> {
539 fn span(&self) -> Span {
540 match self {
541 PartitionOfBound::ForValues {
542 for_values_span,
543 spec,
544 } => for_values_span.join_span(spec),
545 PartitionOfBound::Default(s) => s.span(),
546 }
547 }
548}
549
550#[derive(Clone, Debug)]
552pub struct CreateTablePartitionOf<'a> {
553 pub create_span: Span,
555 pub create_options: Vec<CreateOption<'a>>,
557 pub table_span: Span,
559 pub if_not_exists: Option<Span>,
561 pub identifier: QualifiedName<'a>,
563 pub partition_of_span: Span,
565 pub parent_table: QualifiedName<'a>,
567 pub create_definitions: Vec<CreateDefinition<'a>>,
569 pub bound: PartitionOfBound<'a>,
571 pub partition_by: Option<PartitionBy<'a>>,
573}
574
575impl<'a> Spanned for CreateTablePartitionOf<'a> {
576 fn span(&self) -> Span {
577 self.create_span
578 .join_span(&self.create_options)
579 .join_span(&self.table_span)
580 .join_span(&self.if_not_exists)
581 .join_span(&self.identifier)
582 .join_span(&self.partition_of_span)
583 .join_span(&self.parent_table)
584 .join_span(&self.create_definitions)
585 .join_span(&self.bound)
586 .join_span(&self.partition_by)
587 }
588}
589
590#[derive(Clone, Debug)]
616pub struct CreateTable<'a> {
617 pub create_span: Span,
619 pub create_options: Vec<CreateOption<'a>>,
621 pub table_span: Span,
623 pub identifier: QualifiedName<'a>,
625 pub if_not_exists: Option<Span>,
627 pub create_definitions: Vec<CreateDefinition<'a>>,
629 pub options: Vec<TableOption<'a>>,
631 pub table_as: Option<CreateTableAs<'a>>,
633 pub partition_by: Option<PartitionBy<'a>>,
635}
636
637impl<'a> Spanned for CreateTable<'a> {
638 fn span(&self) -> Span {
639 self.create_span
640 .join_span(&self.create_options)
641 .join_span(&self.table_span)
642 .join_span(&self.identifier)
643 .join_span(&self.if_not_exists)
644 .join_span(&self.create_definitions)
645 .join_span(&self.options)
646 .join_span(&self.table_as)
647 .join_span(&self.partition_by)
648 }
649}
650
651fn parse_foreign_key_definition<'a>(
653 parser: &mut Parser<'a, '_>,
654 constraint_span: Option<Span>,
655 constraint_symbol: Option<Identifier<'a>>,
656) -> Result<CreateDefinition<'a>, ParseError> {
657 let foreign_span = parser.consume_keyword(Keyword::FOREIGN)?;
658 let key_span = parser.consume_keyword(Keyword::KEY)?;
659 let foreign_key_span = foreign_span.join_span(&key_span);
660
661 let index_name = if let Token::Ident(_, _) = parser.token {
663 if !matches!(parser.token, Token::LParen) {
664 Some(parser.consume_plain_identifier_unreserved()?)
665 } else {
666 None
667 }
668 } else {
669 None
670 };
671
672 let cols = parse_index_cols(parser)?;
674
675 let references_span = parser.consume_keyword(Keyword::REFERENCES)?;
677 let references_table = parser.consume_plain_identifier_unreserved()?;
678
679 parser.consume_token(Token::LParen)?;
681 let mut references_cols = Vec::new();
682 loop {
683 references_cols.push(parser.consume_plain_identifier_unreserved()?);
684 if parser.skip_token(Token::Comma).is_none() {
685 break;
686 }
687 }
688 parser.consume_token(Token::RParen)?;
689
690 let match_type = if parser.skip_keyword(Keyword::MATCH).is_some() {
691 match &parser.token {
692 Token::Ident(_, Keyword::FULL) => Some(ForeignKeyMatch::Full(parser.consume())),
693 Token::Ident(_, Keyword::SIMPLE) => Some(ForeignKeyMatch::Simple(parser.consume())),
694 Token::Ident(_, Keyword::PARTIAL) => Some(ForeignKeyMatch::Partial(parser.consume())),
695 _ => None,
696 }
697 } else {
698 None
699 };
700
701 let mut ons = Vec::new();
703 while parser.skip_keyword(Keyword::ON).is_some() {
704 let on_type = match &parser.token {
705 Token::Ident(_, Keyword::UPDATE) => {
706 ForeignKeyOnType::Update(parser.consume_keyword(Keyword::UPDATE)?)
707 }
708 Token::Ident(_, Keyword::DELETE) => {
709 ForeignKeyOnType::Delete(parser.consume_keyword(Keyword::DELETE)?)
710 }
711 _ => parser.expected_failure("UPDATE or DELETE")?,
712 };
713
714 let on_action = match &parser.token {
715 Token::Ident(_, Keyword::CASCADE) => {
716 ForeignKeyOnAction::Cascade(parser.consume_keyword(Keyword::CASCADE)?)
717 }
718 Token::Ident(_, Keyword::RESTRICT) => {
719 ForeignKeyOnAction::Restrict(parser.consume_keyword(Keyword::RESTRICT)?)
720 }
721 Token::Ident(_, Keyword::SET) => {
722 let set_span = parser.consume_keyword(Keyword::SET)?;
723 if parser.skip_keyword(Keyword::NULL).is_some() {
724 ForeignKeyOnAction::SetNull(set_span)
725 } else if parser.skip_keyword(Keyword::DEFAULT).is_some() {
726 ForeignKeyOnAction::SetDefault(set_span)
727 } else {
728 parser.expected_failure("NULL or DEFAULT after SET")?
729 }
730 }
731 Token::Ident(_, Keyword::NO) => {
732 let no_span = parser.consume_keyword(Keyword::NO)?;
733 parser.consume_keyword(Keyword::ACTION)?;
734 ForeignKeyOnAction::NoAction(no_span)
735 }
736 _ => {
737 parser.expected_failure("CASCADE, RESTRICT, SET NULL, SET DEFAULT, or NO ACTION")?
738 }
739 };
740
741 ons.push(ForeignKeyOn {
742 type_: on_type,
743 action: on_action,
744 });
745 }
746
747 Ok(CreateDefinition::ForeignKeyDefinition {
748 constraint_span,
749 constraint_symbol,
750 foreign_key_span,
751 index_name,
752 cols,
753 references_span,
754 references_table,
755 references_cols,
756 match_type,
757 ons,
758 })
759}
760
761fn parse_check_constraint_definition<'a>(
763 parser: &mut Parser<'a, '_>,
764 constraint_span: Option<Span>,
765 constraint_symbol: Option<Identifier<'a>>,
766) -> Result<CreateDefinition<'a>, ParseError> {
767 let check_span = parser.consume_keyword(Keyword::CHECK)?;
768
769 parser.consume_token(Token::LParen)?;
771 let expression = parse_expression_unreserved(parser, PRIORITY_MAX)?;
772 parser.consume_token(Token::RParen)?;
773
774 let enforced = None;
777
778 Ok(CreateDefinition::CheckConstraintDefinition {
779 constraint_span,
780 constraint_symbol,
781 check_span,
782 expression,
783 enforced,
784 })
785}
786
787pub(crate) fn parse_create_definition<'a>(
788 parser: &mut Parser<'a, '_>,
789) -> Result<CreateDefinition<'a>, ParseError> {
790 let constraint_span = parser.skip_keyword(Keyword::CONSTRAINT);
792
793 let constraint_symbol = if constraint_span.is_some() {
795 if let Token::Ident(_, keyword) = parser.token {
796 match keyword {
798 Keyword::PRIMARY
799 | Keyword::UNIQUE
800 | Keyword::FULLTEXT
801 | Keyword::SPATIAL
802 | Keyword::INDEX
803 | Keyword::KEY
804 | Keyword::FOREIGN
805 | Keyword::CHECK => None,
806 _ => Some(parser.consume_plain_identifier_unreserved()?),
807 }
808 } else {
809 None
810 }
811 } else {
812 None
813 };
814
815 let index_type = match &parser.token {
816 Token::Ident(_, Keyword::PRIMARY) => {
817 let span = parser.consume_keywords(&[Keyword::PRIMARY, Keyword::KEY])?;
818 IndexType::Primary(span)
819 }
820 Token::Ident(_, Keyword::UNIQUE) => {
821 let span = parser.consume_keyword(Keyword::UNIQUE)?;
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::Unique(span)
830 }
831 Token::Ident(_, Keyword::FULLTEXT) => {
832 let span = parser.consume_keyword(Keyword::FULLTEXT)?;
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::FullText(span)
841 }
842 Token::Ident(_, Keyword::SPATIAL) => {
843 let span = parser.consume_keyword(Keyword::SPATIAL)?;
844 let span = if let Some(s) = parser.skip_keyword(Keyword::INDEX) {
845 span.join_span(&s)
846 } else if let Some(s) = parser.skip_keyword(Keyword::KEY) {
847 span.join_span(&s)
848 } else {
849 span
850 };
851 IndexType::Spatial(span)
852 }
853 Token::Ident(_, Keyword::INDEX) => {
854 IndexType::Index(parser.consume_keyword(Keyword::INDEX)?)
855 }
856 Token::Ident(_, Keyword::KEY) => IndexType::Index(parser.consume_keyword(Keyword::KEY)?),
857 Token::Ident(_, Keyword::FOREIGN) => {
858 return parse_foreign_key_definition(parser, constraint_span, constraint_symbol);
859 }
860 Token::Ident(_, Keyword::CHECK) => {
861 return parse_check_constraint_definition(parser, constraint_span, constraint_symbol);
862 }
863 Token::Ident(_, Keyword::LIKE) if parser.options.dialect.is_postgresql() => {
864 let like_span = parser.consume_keyword(Keyword::LIKE)?;
866 parser.postgres_only(&like_span);
867 let source_table = parse_qualified_name_unreserved(parser)?;
868 return Ok(CreateDefinition::LikeTable {
869 like_span,
870 source_table,
871 });
872 }
873 Token::String(_, StringType::DoubleQuoted) if parser.options.dialect.is_postgresql() => {
874 if constraint_span.is_some() {
877 parser.expected_failure(
878 "PRIMARY, UNIQUE, INDEX, KEY, FULLTEXT, SPATIAL, FOREIGN, or CHECK",
879 )?
880 }
881 return Ok(CreateDefinition::ColumnDefinition {
882 identifier: parser.consume_plain_identifier_unreserved()?,
883 data_type: parse_data_type(parser, DataTypeContext::Column)?,
884 });
885 }
886 Token::Ident(_, _) => {
887 if constraint_span.is_some() {
889 parser.expected_failure(
890 "PRIMARY, UNIQUE, INDEX, KEY, FULLTEXT, SPATIAL, FOREIGN, or CHECK",
891 )?
892 }
893 return Ok(CreateDefinition::ColumnDefinition {
894 identifier: parser.consume_plain_identifier_unreserved()?,
895 data_type: parse_data_type(parser, DataTypeContext::Column)?,
896 });
897 }
898 _ => return parser.expected_failure("identifier"),
899 };
900
901 let index_name = match &index_type {
903 IndexType::Primary(_) => {
904 match &parser.token {
906 Token::Ident(_, _) if !matches!(parser.token, Token::LParen) => {
907 Some(parser.consume_plain_identifier_unreserved()?)
908 }
909 Token::String(s, _) => {
910 let val = *s;
911 let span = parser.consume();
912 Some(Identifier { value: val, span })
913 }
914 _ => None,
915 }
916 }
917 _ => {
918 match &parser.token {
920 Token::Ident(_, _)
921 if !matches!(
922 parser.token,
923 Token::LParen | Token::Ident(_, Keyword::USING)
924 ) =>
925 {
926 Some(parser.consume_plain_identifier_restrict(Restrict::USING)?)
927 }
928 Token::String(s, _) => {
929 let val = *s;
930 let span = parser.consume();
931 Some(Identifier { value: val, span })
932 }
933 _ => None,
934 }
935 }
936 };
937
938 let mut index_options = Vec::new();
940 if matches!(parser.token, Token::Ident(_, Keyword::USING)) {
941 parse_index_type(parser, &mut index_options)?;
942 }
943
944 let cols = parse_index_cols(parser)?;
946
947 parse_index_options(parser, &mut index_options)?;
949
950 Ok(CreateDefinition::IndexDefinition {
951 constraint_span,
952 constraint_symbol,
953 index_type,
954 index_name,
955 cols,
956 index_options,
957 })
958}
959
960fn parse_partition_by<'a>(parser: &mut Parser<'a, '_>) -> Result<PartitionBy<'a>, ParseError> {
962 let partition_span = parser.consume_keyword(Keyword::PARTITION)?;
963 let by_span = parser.consume_keyword(Keyword::BY)?;
964 let partition_by_span = partition_span.join_span(&by_span);
965
966 let method = match &parser.token {
967 Token::Ident(_, Keyword::RANGE) => {
968 PartitionMethod::Range(parser.consume_keyword(Keyword::RANGE)?)
969 }
970 Token::Ident(_, Keyword::LIST) => {
971 PartitionMethod::List(parser.consume_keyword(Keyword::LIST)?)
972 }
973 Token::Ident(_, Keyword::HASH) => {
974 PartitionMethod::Hash(parser.consume_keyword(Keyword::HASH)?)
975 }
976 _ => parser.expected_failure("RANGE, LIST, or HASH")?,
977 };
978
979 parser.consume_token(Token::LParen)?;
980 let mut keys = Vec::new();
981 loop {
982 let key = if matches!(parser.token, Token::LParen) {
984 parser.consume_token(Token::LParen)?;
985 let expr = parse_expression_unreserved(parser, PRIORITY_MAX)?;
986 parser.consume_token(Token::RParen)?;
987 expr
988 } else {
989 parse_expression_unreserved(parser, PRIORITY_MAX)?
990 };
991 keys.push(key);
992 if parser.skip_token(Token::Comma).is_none() {
993 break;
994 }
995 }
996 parser.consume_token(Token::RParen)?;
997
998 Ok(PartitionBy {
999 partition_by_span,
1000 method,
1001 keys,
1002 })
1003}
1004
1005fn parse_partition_bound_expr<'a>(
1007 parser: &mut Parser<'a, '_>,
1008) -> Result<PartitionBoundExpr<'a>, ParseError> {
1009 match &parser.token {
1010 Token::Ident(_, Keyword::MINVALUE) => Ok(PartitionBoundExpr::MinValue(
1011 parser.consume_keyword(Keyword::MINVALUE)?,
1012 )),
1013 Token::Ident(_, Keyword::MAXVALUE) => Ok(PartitionBoundExpr::MaxValue(
1014 parser.consume_keyword(Keyword::MAXVALUE)?,
1015 )),
1016 _ => Ok(PartitionBoundExpr::Expr(parse_expression_unreserved(
1017 parser,
1018 PRIORITY_MAX,
1019 )?)),
1020 }
1021}
1022
1023fn parse_partition_bound_exprs<'a>(
1025 parser: &mut Parser<'a, '_>,
1026) -> Result<Vec<PartitionBoundExpr<'a>>, ParseError> {
1027 parser.consume_token(Token::LParen)?;
1028 let mut values = Vec::new();
1029 loop {
1030 values.push(parse_partition_bound_expr(parser)?);
1031 if parser.skip_token(Token::Comma).is_none() {
1032 break;
1033 }
1034 }
1035 parser.consume_token(Token::RParen)?;
1036 Ok(values)
1037}
1038
1039fn parse_partition_bound_spec<'a>(
1041 parser: &mut Parser<'a, '_>,
1042) -> Result<PartitionBoundSpec<'a>, ParseError> {
1043 match &parser.token {
1044 Token::Ident(_, Keyword::IN) => {
1045 let in_span = parser.consume_keyword(Keyword::IN)?;
1046 let values = parse_partition_bound_exprs(parser)?;
1047 Ok(PartitionBoundSpec::In { in_span, values })
1048 }
1049 Token::Ident(_, Keyword::FROM) => {
1050 let from_span = parser.consume_keyword(Keyword::FROM)?;
1051 let from_values = parse_partition_bound_exprs(parser)?;
1052 let to_span = parser.consume_keyword(Keyword::TO)?;
1053 let to_values = parse_partition_bound_exprs(parser)?;
1054 Ok(PartitionBoundSpec::FromTo {
1055 from_span,
1056 from_values,
1057 to_span,
1058 to_values,
1059 })
1060 }
1061 Token::Ident(_, Keyword::WITH) => {
1062 let with_span = parser.consume_keyword(Keyword::WITH)?;
1063 parser.consume_token(Token::LParen)?;
1064 let modulus_span = parser.consume_keyword(Keyword::MODULUS)?;
1065 let modulus = parser.consume_int::<u64>()?;
1066 parser.consume_token(Token::Comma)?;
1067 let remainder_span = parser.consume_keyword(Keyword::REMAINDER)?;
1068 let remainder = parser.consume_int::<u64>()?;
1069 parser.consume_token(Token::RParen)?;
1070 Ok(PartitionBoundSpec::WithModulusRemainder {
1071 with_span,
1072 modulus_span,
1073 modulus,
1074 remainder_span,
1075 remainder,
1076 })
1077 }
1078 _ => parser.expected_failure("IN, FROM, or WITH"),
1079 }
1080}
1081
1082pub(crate) fn parse_create_table<'a>(
1083 parser: &mut Parser<'a, '_>,
1084 create_span: Span,
1085 create_options: Vec<CreateOption<'a>>,
1086 table_span: Span,
1087 if_not_exists: Option<Span>,
1088 identifier: QualifiedName<'a>,
1089) -> Result<CreateTable<'a>, ParseError> {
1090 parser.consume_token(Token::LParen)?;
1091
1092 let mut create_definitions = Vec::new();
1093 if !matches!(parser.token, Token::RParen) {
1094 loop {
1095 parser.recovered(
1096 "')' or ','",
1097 &|t| matches!(t, Token::RParen | Token::Comma),
1098 |parser| {
1099 create_definitions.push(parse_create_definition(parser)?);
1100 Ok(())
1101 },
1102 )?;
1103 if matches!(parser.token, Token::RParen) {
1104 break;
1105 }
1106 parser.consume_token(Token::Comma)?;
1107 }
1108 }
1109 parser.consume_token(Token::RParen)?;
1110
1111 let mut options = Vec::new();
1112 let mut table_as: Option<CreateTableAs<'_>> = None;
1113 let mut partition_by: Option<PartitionBy<'_>> = None;
1114 let delimiter_name = parser.lexer.delimiter_name();
1115 parser.recovered(
1116 delimiter_name,
1117 &|t| t == &Token::Eof || t == &Token::Delimiter,
1118 |parser| {
1119 loop {
1120 match &parser.token {
1121 Token::Ident(_, Keyword::ENGINE) => {
1122 let identifier = parser.consume_keyword(Keyword::ENGINE)?;
1123 parser.skip_token(Token::Eq);
1124 options.push(TableOption::Engine {
1125 identifier,
1126 value: parser.consume_plain_identifier_unreserved()?,
1127 });
1128 }
1129 Token::Ident(_, Keyword::DEFAULT) => {
1130 let default_span = parser.consume_keyword(Keyword::DEFAULT)?;
1131 match &parser.token {
1132 Token::Ident(_, Keyword::CHARSET) => {
1133 let identifier = default_span
1134 .join_span(&parser.consume_keyword(Keyword::CHARSET)?);
1135 parser.skip_token(Token::Eq);
1136 options.push(TableOption::DefaultCharSet {
1137 identifier,
1138 value: parser.consume_plain_identifier_unreserved()?,
1139 });
1140 }
1141 Token::Ident(_, Keyword::COLLATE) => {
1142 let identifier = default_span
1143 .join_span(&parser.consume_keyword(Keyword::COLLATE)?);
1144 parser.skip_token(Token::Eq);
1145 options.push(TableOption::DefaultCollate {
1146 identifier,
1147 value: parser.consume_plain_identifier_unreserved()?,
1148 });
1149 }
1150 _ => parser.expected_failure("'CHARSET' or 'COLLATE'")?,
1151 }
1152 }
1153 Token::Ident(_, Keyword::CHARSET) => {
1154 let identifier = parser.consume_keyword(Keyword::CHARSET)?;
1155 parser.skip_token(Token::Eq);
1156 options.push(TableOption::CharSet {
1157 identifier,
1158 value: parser.consume_plain_identifier_unreserved()?,
1159 });
1160 }
1161 Token::Ident(_, Keyword::COLLATE) => {
1162 let identifier = parser.consume_keyword(Keyword::COLLATE)?;
1163 parser.skip_token(Token::Eq);
1164 options.push(TableOption::Collate {
1165 identifier,
1166 value: parser.consume_plain_identifier_unreserved()?,
1167 });
1168 }
1169 Token::Ident(_, Keyword::ROW_FORMAT) => {
1170 let identifier = parser.consume_keyword(Keyword::ROW_FORMAT)?;
1171 parser.skip_token(Token::Eq);
1172 options.push(TableOption::RowFormat {
1173 identifier,
1174 value: parser.consume_plain_identifier_unreserved()?,
1175 });
1176 }
1178 Token::Ident(_, Keyword::KEY_BLOCK_SIZE) => {
1179 let identifier = parser.consume_keywords(&[Keyword::KEY_BLOCK_SIZE])?;
1180 parser.skip_token(Token::Eq);
1181 options.push(TableOption::KeyBlockSize {
1182 identifier,
1183 value: parser.consume_int()?,
1184 });
1185 }
1186 Token::Ident(_, Keyword::COMMENT) => {
1187 let identifier = parser.consume_keyword(Keyword::COMMENT)?;
1188 parser.skip_token(Token::Eq);
1189 options.push(TableOption::Comment {
1190 identifier,
1191 value: parser.consume_string()?,
1192 });
1193 }
1194 Token::Ident(_, Keyword::STRICT) => {
1195 let identifier = parser.consume_keyword(Keyword::STRICT)?;
1196 options.push(TableOption::Strict { identifier });
1197 }
1198 Token::Ident(_, Keyword::AUTO_INCREMENT) => {
1199 let identifier = parser.consume_keyword(Keyword::AUTO_INCREMENT)?;
1200 parser.skip_token(Token::Eq);
1201 options.push(TableOption::AutoIncrement {
1202 identifier,
1203 value: parser.consume_int()?,
1204 });
1205 }
1206 Token::Ident(_, Keyword::DATA) => {
1207 let identifier =
1208 parser.consume_keywords(&[Keyword::DATA, Keyword::DIRECTORY])?;
1209 parser.skip_token(Token::Eq);
1210 options.push(TableOption::DataDirectory {
1211 identifier,
1212 value: parser.consume_string()?,
1213 });
1214 }
1215 Token::Ident(_, Keyword::INDEX) => {
1216 let identifier =
1217 parser.consume_keywords(&[Keyword::INDEX, Keyword::DIRECTORY])?;
1218 parser.skip_token(Token::Eq);
1219 options.push(TableOption::IndexDirectory {
1220 identifier,
1221 value: parser.consume_string()?,
1222 });
1223 }
1224 Token::Ident(_, Keyword::INSERT_METHOD) => {
1225 let identifier = parser.consume_keyword(Keyword::INSERT_METHOD)?;
1226 parser.skip_token(Token::Eq);
1227 options.push(TableOption::InsertMethod {
1228 identifier,
1229 value: parser.consume_plain_identifier_unreserved()?,
1230 });
1231 }
1232 Token::Ident(_, Keyword::PACK_KEYS) => {
1233 let identifier = parser.consume_keyword(Keyword::PACK_KEYS)?;
1234 parser.skip_token(Token::Eq);
1235 options.push(TableOption::PackKeys {
1236 identifier,
1237 value: parser.consume_int()?,
1238 });
1239 }
1240 Token::Ident(_, Keyword::STATS_AUTO_RECALC) => {
1241 let identifier = parser.consume_keyword(Keyword::STATS_AUTO_RECALC)?;
1242 parser.skip_token(Token::Eq);
1243 options.push(TableOption::StatsAutoRecalc {
1244 identifier,
1245 value: parser.consume_int()?,
1246 });
1247 }
1248 Token::Ident(_, Keyword::STATS_PERSISTENT) => {
1249 let identifier = parser.consume_keyword(Keyword::STATS_PERSISTENT)?;
1250 parser.skip_token(Token::Eq);
1251 options.push(TableOption::StatsPersistent {
1252 identifier,
1253 value: parser.consume_int()?,
1254 });
1255 }
1256 Token::Ident(_, Keyword::STATS_SAMPLE_PAGES) => {
1257 let identifier = parser.consume_keyword(Keyword::STATS_SAMPLE_PAGES)?;
1258 parser.skip_token(Token::Eq);
1259 options.push(TableOption::StatsSamplePages {
1260 identifier,
1261 value: parser.consume_int()?,
1262 });
1263 }
1264 Token::Ident(_, Keyword::DELAY_KEY_WRITE) => {
1265 let identifier = parser.consume_keyword(Keyword::DELAY_KEY_WRITE)?;
1266 parser.skip_token(Token::Eq);
1267 let (val, span) = parser.consume_int::<usize>()?;
1268 options.push(TableOption::DelayKeyWrite {
1269 identifier,
1270 value: (val != 0, span),
1271 });
1272 }
1273 Token::Ident(_, Keyword::COMPRESSION) => {
1274 let identifier = parser.consume_keyword(Keyword::COMPRESSION)?;
1275 parser.skip_token(Token::Eq);
1276 options.push(TableOption::Compression {
1277 identifier,
1278 value: parser.consume_string()?,
1279 });
1280 }
1281 Token::Ident(_, Keyword::ENCRYPTION) => {
1282 let identifier = parser.consume_keyword(Keyword::ENCRYPTION)?;
1283 parser.skip_token(Token::Eq);
1284 let value = match &parser.token {
1286 Token::String(..) => {
1287 let s = parser.consume_string()?;
1288 let is_yes = s.as_str().eq_ignore_ascii_case("y")
1289 || s.as_str().eq_ignore_ascii_case("yes");
1290 (is_yes, s.span())
1291 }
1292 _ => {
1293 let id = parser.consume_plain_identifier_unreserved()?;
1294 let is_yes = id.value.eq_ignore_ascii_case("yes");
1295 (is_yes, id.span())
1296 }
1297 };
1298 options.push(TableOption::Encryption { identifier, value });
1299 }
1300 Token::Ident(_, Keyword::MAX_ROWS) => {
1301 let identifier = parser.consume_keyword(Keyword::MAX_ROWS)?;
1302 parser.skip_token(Token::Eq);
1303 options.push(TableOption::MaxRows {
1304 identifier,
1305 value: parser.consume_int()?,
1306 });
1307 }
1308 Token::Ident(_, Keyword::MIN_ROWS) => {
1309 let identifier = parser.consume_keyword(Keyword::MIN_ROWS)?;
1310 parser.skip_token(Token::Eq);
1311 options.push(TableOption::MinRows {
1312 identifier,
1313 value: parser.consume_int()?,
1314 });
1315 }
1316 Token::Ident(_, Keyword::AUTOEXTEND_SIZE) => {
1317 let identifier = parser.consume_keyword(Keyword::AUTOEXTEND_SIZE)?;
1318 parser.skip_token(Token::Eq);
1319 options.push(TableOption::AutoExtendSize {
1320 identifier,
1321 value: parser.consume_int()?,
1322 });
1323 }
1324 Token::Ident(_, Keyword::AVG_ROW_LENGTH) => {
1325 let identifier = parser.consume_keyword(Keyword::AVG_ROW_LENGTH)?;
1326 parser.skip_token(Token::Eq);
1327 options.push(TableOption::AvgRowLength {
1328 identifier,
1329 value: parser.consume_int()?,
1330 });
1331 }
1332 Token::Ident(_, Keyword::CHECKSUM) => {
1333 let identifier = parser.consume_keyword(Keyword::CHECKSUM)?;
1334 parser.skip_token(Token::Eq);
1335 let (val, span) = parser.consume_int::<usize>()?;
1336 options.push(TableOption::Checksum {
1337 identifier,
1338 value: (val != 0, span),
1339 });
1340 }
1341 Token::Ident(_, Keyword::CONNECTION) => {
1342 let identifier = parser.consume_keyword(Keyword::CONNECTION)?;
1343 parser.skip_token(Token::Eq);
1344 options.push(TableOption::Connection {
1345 identifier,
1346 value: parser.consume_string()?,
1347 });
1348 }
1349 Token::Ident(_, Keyword::ENGINE_ATTRIBUTE) => {
1350 let identifier = parser.consume_keyword(Keyword::ENGINE_ATTRIBUTE)?;
1351 parser.skip_token(Token::Eq);
1352 options.push(TableOption::EngineAttribute {
1353 identifier,
1354 value: parser.consume_string()?,
1355 });
1356 }
1357 Token::Ident(_, Keyword::PASSWORD) => {
1358 let identifier = parser.consume_keyword(Keyword::PASSWORD)?;
1359 parser.skip_token(Token::Eq);
1360 options.push(TableOption::Password {
1361 identifier,
1362 value: parser.consume_string()?,
1363 });
1364 }
1365 Token::Ident(_, Keyword::SECONDARY_ENGINE_ATTRIBUTE) => {
1366 let identifier =
1367 parser.consume_keyword(Keyword::SECONDARY_ENGINE_ATTRIBUTE)?;
1368 parser.skip_token(Token::Eq);
1369 options.push(TableOption::SecondaryEngineAttribute {
1370 identifier,
1371 value: parser.consume_string()?,
1372 });
1373 }
1374 Token::Ident(_, Keyword::START) => {
1375 let identifier =
1376 parser.consume_keywords(&[Keyword::START, Keyword::TRANSACTION])?;
1377 options.push(TableOption::StartTransaction { identifier });
1378 }
1379 Token::Ident(_, Keyword::TABLESPACE) => {
1380 let identifier = parser.consume_keyword(Keyword::TABLESPACE)?;
1381 options.push(TableOption::Tablespace {
1382 identifier,
1383 value: parser.consume_plain_identifier_unreserved()?,
1384 });
1385 }
1386 Token::Ident(_, Keyword::STORAGE) => {
1387 let identifier = parser.consume_keyword(Keyword::STORAGE)?;
1388 options.push(TableOption::Storage {
1389 identifier,
1390 value: parser.consume_plain_identifier_unreserved()?,
1391 });
1392 }
1393 Token::Ident(_, Keyword::UNION) => {
1394 let identifier = parser.consume_keyword(Keyword::UNION)?;
1395 parser.skip_token(Token::Eq);
1396 parser.consume_token(Token::LParen)?;
1397 let mut tables = Vec::new();
1398 loop {
1399 tables.push(parser.consume_plain_identifier_unreserved()?);
1400 if parser.skip_token(Token::Comma).is_none() {
1401 break;
1402 }
1403 }
1404 parser.consume_token(Token::RParen)?;
1405 options.push(TableOption::Union {
1406 identifier,
1407 value: tables,
1408 });
1409 }
1410 Token::Ident(_, Keyword::INHERITS) => {
1411 let identifier = parser.consume_keyword(Keyword::INHERITS)?;
1412 parser.postgres_only(&identifier);
1413 parser.consume_token(Token::LParen)?;
1414 let mut tables = Vec::new();
1415 parser.recovered("')'", &|t| t == &Token::RParen, |parser| {
1416 loop {
1417 tables.push(parse_qualified_name_unreserved(parser)?);
1418 if parser.skip_token(Token::Comma).is_none() {
1419 break;
1420 }
1421 }
1422 Ok(())
1423 })?;
1424 parser.consume_token(Token::RParen)?;
1425 options.push(TableOption::Inherits {
1426 identifier,
1427 value: tables,
1428 });
1429 }
1430 Token::Ident(_, Keyword::WITH) => {
1431 let identifier = parser.consume_keyword(Keyword::WITH)?;
1432 parser.postgres_only(&identifier);
1433 parser.consume_token(Token::LParen)?;
1434 let mut params = Vec::new();
1435 parser.recovered("')'", &|t| t == &Token::RParen, |parser| {
1436 loop {
1437 let key = parser.consume_plain_identifier_unreserved()?;
1438 parser.consume_token(Token::Eq)?;
1439 let val = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1440 params.push((key, val));
1441 if parser.skip_token(Token::Comma).is_none() {
1442 break;
1443 }
1444 }
1445 Ok(())
1446 })?;
1447 parser.consume_token(Token::RParen)?;
1448 options.push(TableOption::WithOptions {
1449 identifier,
1450 options: params,
1451 });
1452 }
1453 Token::Ident(_, Keyword::ON) => {
1454 let identifier =
1455 parser.consume_keywords(&[Keyword::ON, Keyword::COMMIT])?;
1456 parser.postgres_only(&identifier);
1457 let action = match &parser.token {
1458 Token::Ident(_, Keyword::PRESERVE) => OnCommitAction::PreserveRows(
1459 parser.consume_keywords(&[Keyword::PRESERVE, Keyword::ROWS])?,
1460 ),
1461 Token::Ident(_, Keyword::DELETE) => OnCommitAction::DeleteRows(
1462 parser.consume_keywords(&[Keyword::DELETE, Keyword::ROWS])?,
1463 ),
1464 Token::Ident(_, Keyword::DROP) => {
1465 OnCommitAction::Drop(parser.consume_keyword(Keyword::DROP)?)
1466 }
1467 _ => parser.expected_failure("PRESERVE ROWS, DELETE ROWS, or DROP")?,
1468 };
1469 options.push(TableOption::OnCommit { identifier, action });
1470 }
1471 Token::Ident(_, Keyword::PARTITION) => {
1472 partition_by = Some(parse_partition_by(parser)?);
1473 }
1474 Token::Ident(_, Keyword::IGNORE)
1475 | Token::Ident(_, Keyword::REPLACE)
1476 | Token::Ident(_, Keyword::AS) => {
1477 let ignore_span = parser.skip_keyword(Keyword::IGNORE);
1478 let replace_span = parser.skip_keyword(Keyword::REPLACE);
1479 let as_span = parser.consume_keyword(Keyword::AS)?;
1480
1481 if let Some(table_as) = &table_as {
1482 parser.err("Multiple AS clauses not supported", table_as);
1483 }
1484
1485 let query = parse_compound_query(parser)?;
1486 table_as = Some(CreateTableAs {
1487 as_span,
1488 replace_span,
1489 ignore_span,
1490 query,
1491 });
1492 }
1493 Token::Comma => {
1494 parser.consume_token(Token::Comma)?;
1495 }
1496 Token::Delimiter => break,
1497 Token::Eof => break,
1498 _ => {
1499 parser.expected_failure("table option or delimiter")?;
1500 }
1501 }
1502 }
1503 Ok(())
1504 },
1505 )?;
1506
1507 Ok(CreateTable {
1508 create_span,
1509 create_options,
1510 table_span,
1511 identifier,
1512 if_not_exists,
1513 options,
1514 create_definitions,
1515 table_as,
1516 partition_by,
1517 })
1518}
1519
1520fn parse_create_table_partition_of<'a>(
1521 parser: &mut Parser<'a, '_>,
1522 create_span: Span,
1523 create_options: Vec<CreateOption<'a>>,
1524 table_span: Span,
1525 if_not_exists: Option<Span>,
1526 identifier: QualifiedName<'a>,
1527) -> Result<CreateTablePartitionOf<'a>, ParseError> {
1528 let partition_span = parser.consume_keyword(Keyword::PARTITION)?;
1529 let of_span = parser.consume_keyword(Keyword::OF)?;
1530 let partition_of_span = partition_span.join_span(&of_span);
1531
1532 let parent_table = parse_qualified_name_unreserved(parser)?;
1533
1534 let mut create_definitions = Vec::new();
1536 if matches!(parser.token, Token::LParen) {
1537 parser.consume_token(Token::LParen)?;
1538 if !matches!(parser.token, Token::RParen) {
1539 loop {
1540 parser.recovered(
1541 "')' or ','",
1542 &|t| matches!(t, Token::RParen | Token::Comma),
1543 |parser| {
1544 create_definitions.push(parse_create_definition(parser)?);
1545 Ok(())
1546 },
1547 )?;
1548 if matches!(parser.token, Token::RParen) {
1549 break;
1550 }
1551 parser.consume_token(Token::Comma)?;
1552 }
1553 }
1554 parser.consume_token(Token::RParen)?;
1555 }
1556
1557 let bound = match &parser.token {
1559 Token::Ident(_, Keyword::DEFAULT) => {
1560 PartitionOfBound::Default(parser.consume_keyword(Keyword::DEFAULT)?)
1561 }
1562 Token::Ident(_, Keyword::FOR) => {
1563 let for_values_span = parser.consume_keywords(&[Keyword::FOR, Keyword::VALUES])?;
1564 let spec = parse_partition_bound_spec(parser)?;
1565 PartitionOfBound::ForValues {
1566 for_values_span,
1567 spec,
1568 }
1569 }
1570 _ => parser.expected_failure("FOR VALUES or DEFAULT")?,
1571 };
1572
1573 let partition_by = if matches!(parser.token, Token::Ident(_, Keyword::PARTITION)) {
1575 Some(parse_partition_by(parser)?)
1576 } else {
1577 None
1578 };
1579
1580 Ok(CreateTablePartitionOf {
1581 create_span,
1582 create_options,
1583 table_span,
1584 if_not_exists,
1585 identifier,
1586 partition_of_span,
1587 parent_table,
1588 create_definitions,
1589 bound,
1590 partition_by,
1591 })
1592}
1593
1594pub(crate) fn parse_create_table_or_partition_of<'a>(
1599 parser: &mut Parser<'a, '_>,
1600 create_span: Span,
1601 create_options: Vec<CreateOption<'a>>,
1602) -> Result<Statement<'a>, ParseError> {
1603 let table_span = parser.consume_keyword(Keyword::TABLE)?;
1604
1605 let if_not_exists = if let Some(if_) = parser.skip_keyword(Keyword::IF) {
1606 Some(
1607 if_.start
1608 ..parser
1609 .consume_keywords(&[Keyword::NOT, Keyword::EXISTS])?
1610 .end,
1611 )
1612 } else {
1613 None
1614 };
1615 let identifier = parse_qualified_name_unreserved(parser)?;
1616
1617 if matches!(parser.token, Token::Ident(_, Keyword::PARTITION)) {
1618 Ok(Statement::CreateTablePartitionOf(Box::new(
1619 parse_create_table_partition_of(
1620 parser,
1621 create_span,
1622 create_options,
1623 table_span,
1624 if_not_exists,
1625 identifier,
1626 )?,
1627 )))
1628 } else if matches!(parser.token, Token::Ident(_, Keyword::AS))
1629 && !matches!(parser.peek(), Token::LParen)
1630 {
1631 let as_span = parser.consume_keyword(Keyword::AS)?;
1633 let query = parse_compound_query(parser)?;
1634 Ok(Statement::CreateTable(Box::new(CreateTable {
1635 create_span,
1636 create_options,
1637 table_span,
1638 identifier,
1639 if_not_exists,
1640 options: alloc::vec![],
1641 create_definitions: alloc::vec![],
1642 table_as: Some(CreateTableAs {
1643 as_span,
1644 replace_span: None,
1645 ignore_span: None,
1646 query,
1647 }),
1648 partition_by: None,
1649 })))
1650 } else {
1651 Ok(Statement::CreateTable(Box::new(parse_create_table(
1652 parser,
1653 create_span,
1654 create_options,
1655 table_span,
1656 if_not_exists,
1657 identifier,
1658 )?)))
1659 }
1660}