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