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: Identifier<'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 = parser.consume_plain_identifier_unreserved()?;
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 { value: val, span })
930 }
931 _ => None,
932 }
933 }
934 _ => {
935 match &parser.token {
937 Token::Ident(_, _)
938 if !matches!(
939 parser.token,
940 Token::LParen | Token::Ident(_, Keyword::USING)
941 ) =>
942 {
943 Some(parser.consume_plain_identifier_restrict(Restrict::USING)?)
944 }
945 Token::String(s, _) => {
946 let val = *s;
947 let span = parser.consume();
948 Some(Identifier { value: val, span })
949 }
950 _ => None,
951 }
952 }
953 };
954
955 let mut index_options = Vec::new();
957 if matches!(parser.token, Token::Ident(_, Keyword::USING)) {
958 parse_index_type(parser, &mut index_options)?;
959 }
960
961 let (cols, cols_r_paren) = parse_index_cols(parser)?;
963
964 parse_index_options(parser, &mut index_options)?;
966
967 Ok(CreateDefinition::IndexDefinition {
968 constraint_span,
969 constraint_symbol,
970 index_type,
971 index_name,
972 cols,
973 cols_r_paren,
974 index_options,
975 })
976}
977
978fn parse_partition_by<'a>(parser: &mut Parser<'a, '_>) -> Result<PartitionBy<'a>, ParseError> {
980 let partition_span = parser.consume_keyword(Keyword::PARTITION)?;
981 let by_span = parser.consume_keyword(Keyword::BY)?;
982 let partition_by_span = partition_span.join_span(&by_span);
983
984 let method = match &parser.token {
985 Token::Ident(_, Keyword::RANGE) => {
986 PartitionMethod::Range(parser.consume_keyword(Keyword::RANGE)?)
987 }
988 Token::Ident(_, Keyword::LIST) => {
989 PartitionMethod::List(parser.consume_keyword(Keyword::LIST)?)
990 }
991 Token::Ident(_, Keyword::HASH) => {
992 PartitionMethod::Hash(parser.consume_keyword(Keyword::HASH)?)
993 }
994 _ => parser.expected_failure("RANGE, LIST, or HASH")?,
995 };
996
997 parser.consume_token(Token::LParen)?;
998 let mut keys = Vec::new();
999 loop {
1000 let key = if matches!(parser.token, Token::LParen) {
1002 parser.consume_token(Token::LParen)?;
1003 let expr = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1004 parser.consume_token(Token::RParen)?;
1005 expr
1006 } else {
1007 parse_expression_unreserved(parser, PRIORITY_MAX)?
1008 };
1009 keys.push(key);
1010 if parser.skip_token(Token::Comma).is_none() {
1011 break;
1012 }
1013 }
1014 parser.consume_token(Token::RParen)?;
1015
1016 Ok(PartitionBy {
1017 partition_by_span,
1018 method,
1019 keys,
1020 })
1021}
1022
1023fn parse_partition_bound_expr<'a>(
1025 parser: &mut Parser<'a, '_>,
1026) -> Result<PartitionBoundExpr<'a>, ParseError> {
1027 match &parser.token {
1028 Token::Ident(_, Keyword::MINVALUE) => Ok(PartitionBoundExpr::MinValue(
1029 parser.consume_keyword(Keyword::MINVALUE)?,
1030 )),
1031 Token::Ident(_, Keyword::MAXVALUE) => Ok(PartitionBoundExpr::MaxValue(
1032 parser.consume_keyword(Keyword::MAXVALUE)?,
1033 )),
1034 _ => Ok(PartitionBoundExpr::Expr(parse_expression_unreserved(
1035 parser,
1036 PRIORITY_MAX,
1037 )?)),
1038 }
1039}
1040
1041fn parse_partition_bound_exprs<'a>(
1043 parser: &mut Parser<'a, '_>,
1044) -> Result<Vec<PartitionBoundExpr<'a>>, ParseError> {
1045 parser.consume_token(Token::LParen)?;
1046 let mut values = Vec::new();
1047 loop {
1048 values.push(parse_partition_bound_expr(parser)?);
1049 if parser.skip_token(Token::Comma).is_none() {
1050 break;
1051 }
1052 }
1053 parser.consume_token(Token::RParen)?;
1054 Ok(values)
1055}
1056
1057fn parse_partition_bound_spec<'a>(
1059 parser: &mut Parser<'a, '_>,
1060) -> Result<PartitionBoundSpec<'a>, ParseError> {
1061 match &parser.token {
1062 Token::Ident(_, Keyword::IN) => {
1063 let in_span = parser.consume_keyword(Keyword::IN)?;
1064 let values = parse_partition_bound_exprs(parser)?;
1065 Ok(PartitionBoundSpec::In { in_span, values })
1066 }
1067 Token::Ident(_, Keyword::FROM) => {
1068 let from_span = parser.consume_keyword(Keyword::FROM)?;
1069 let from_values = parse_partition_bound_exprs(parser)?;
1070 let to_span = parser.consume_keyword(Keyword::TO)?;
1071 let to_values = parse_partition_bound_exprs(parser)?;
1072 Ok(PartitionBoundSpec::FromTo {
1073 from_span,
1074 from_values,
1075 to_span,
1076 to_values,
1077 })
1078 }
1079 Token::Ident(_, Keyword::WITH) => {
1080 let with_span = parser.consume_keyword(Keyword::WITH)?;
1081 parser.consume_token(Token::LParen)?;
1082 let modulus_span = parser.consume_keyword(Keyword::MODULUS)?;
1083 let modulus = parser.consume_int::<u64>()?;
1084 parser.consume_token(Token::Comma)?;
1085 let remainder_span = parser.consume_keyword(Keyword::REMAINDER)?;
1086 let remainder = parser.consume_int::<u64>()?;
1087 parser.consume_token(Token::RParen)?;
1088 Ok(PartitionBoundSpec::WithModulusRemainder {
1089 with_span,
1090 modulus_span,
1091 modulus,
1092 remainder_span,
1093 remainder,
1094 })
1095 }
1096 _ => parser.expected_failure("IN, FROM, or WITH"),
1097 }
1098}
1099
1100pub(crate) fn parse_create_table<'a>(
1101 parser: &mut Parser<'a, '_>,
1102 create_span: Span,
1103 create_options: Vec<CreateOption<'a>>,
1104 table_span: Span,
1105 if_not_exists: Option<Span>,
1106 identifier: QualifiedName<'a>,
1107) -> Result<CreateTable<'a>, ParseError> {
1108 parser.consume_token(Token::LParen)?;
1109
1110 let mut create_definitions = Vec::new();
1111 if !matches!(parser.token, Token::RParen) {
1112 loop {
1113 parser.recovered(
1114 "')' or ','",
1115 &|t| matches!(t, Token::RParen | Token::Comma),
1116 |parser| {
1117 create_definitions.push(parse_create_definition(parser)?);
1118 Ok(())
1119 },
1120 )?;
1121 if matches!(parser.token, Token::RParen) {
1122 break;
1123 }
1124 parser.consume_token(Token::Comma)?;
1125 }
1126 }
1127 let r_paren_span = parser.consume_token(Token::RParen)?;
1128
1129 let mut options = Vec::new();
1130 let mut table_as: Option<CreateTableAs<'_>> = None;
1131 let mut partition_by: Option<PartitionBy<'_>> = None;
1132 let delimiter_name = parser.lexer.delimiter_name();
1133 parser.recovered(
1134 delimiter_name,
1135 &|t| t == &Token::Eof || t == &Token::Delimiter,
1136 |parser| {
1137 loop {
1138 match &parser.token {
1139 Token::Ident(_, Keyword::ENGINE) => {
1140 let identifier = parser.consume_keyword(Keyword::ENGINE)?;
1141 parser.skip_token(Token::Eq);
1142 options.push(TableOption::Engine {
1143 identifier,
1144 value: parser.consume_plain_identifier_unreserved()?,
1145 });
1146 }
1147 Token::Ident(_, Keyword::DEFAULT) => {
1148 let default_span = parser.consume_keyword(Keyword::DEFAULT)?;
1149 match &parser.token {
1150 Token::Ident(_, Keyword::CHARSET) => {
1151 let identifier = default_span
1152 .join_span(&parser.consume_keyword(Keyword::CHARSET)?);
1153 parser.skip_token(Token::Eq);
1154 options.push(TableOption::DefaultCharSet {
1155 identifier,
1156 value: parser.consume_plain_identifier_unreserved()?,
1157 });
1158 }
1159 Token::Ident(_, Keyword::COLLATE) => {
1160 let identifier = default_span
1161 .join_span(&parser.consume_keyword(Keyword::COLLATE)?);
1162 parser.skip_token(Token::Eq);
1163 options.push(TableOption::DefaultCollate {
1164 identifier,
1165 value: parser.consume_plain_identifier_unreserved()?,
1166 });
1167 }
1168 _ => parser.expected_failure("'CHARSET' or 'COLLATE'")?,
1169 }
1170 }
1171 Token::Ident(_, Keyword::CHARSET) => {
1172 let identifier = parser.consume_keyword(Keyword::CHARSET)?;
1173 parser.skip_token(Token::Eq);
1174 options.push(TableOption::CharSet {
1175 identifier,
1176 value: parser.consume_plain_identifier_unreserved()?,
1177 });
1178 }
1179 Token::Ident(_, Keyword::COLLATE) => {
1180 let identifier = parser.consume_keyword(Keyword::COLLATE)?;
1181 parser.skip_token(Token::Eq);
1182 options.push(TableOption::Collate {
1183 identifier,
1184 value: parser.consume_plain_identifier_unreserved()?,
1185 });
1186 }
1187 Token::Ident(_, Keyword::ROW_FORMAT) => {
1188 let identifier = parser.consume_keyword(Keyword::ROW_FORMAT)?;
1189 parser.skip_token(Token::Eq);
1190 options.push(TableOption::RowFormat {
1191 identifier,
1192 value: parser.consume_plain_identifier_unreserved()?,
1193 });
1194 }
1196 Token::Ident(_, Keyword::KEY_BLOCK_SIZE) => {
1197 let identifier = parser.consume_keywords(&[Keyword::KEY_BLOCK_SIZE])?;
1198 parser.skip_token(Token::Eq);
1199 options.push(TableOption::KeyBlockSize {
1200 identifier,
1201 value: parser.consume_int()?,
1202 });
1203 }
1204 Token::Ident(_, Keyword::COMMENT) => {
1205 let identifier = parser.consume_keyword(Keyword::COMMENT)?;
1206 parser.skip_token(Token::Eq);
1207 options.push(TableOption::Comment {
1208 identifier,
1209 value: parser.consume_string()?,
1210 });
1211 }
1212 Token::Ident(_, Keyword::STRICT) => {
1213 let identifier = parser.consume_keyword(Keyword::STRICT)?;
1214 options.push(TableOption::Strict { identifier });
1215 }
1216 Token::Ident(_, Keyword::AUTO_INCREMENT) => {
1217 let identifier = parser.consume_keyword(Keyword::AUTO_INCREMENT)?;
1218 parser.skip_token(Token::Eq);
1219 options.push(TableOption::AutoIncrement {
1220 identifier,
1221 value: parser.consume_int()?,
1222 });
1223 }
1224 Token::Ident(_, Keyword::DATA) => {
1225 let identifier =
1226 parser.consume_keywords(&[Keyword::DATA, Keyword::DIRECTORY])?;
1227 parser.skip_token(Token::Eq);
1228 options.push(TableOption::DataDirectory {
1229 identifier,
1230 value: parser.consume_string()?,
1231 });
1232 }
1233 Token::Ident(_, Keyword::INDEX) => {
1234 let identifier =
1235 parser.consume_keywords(&[Keyword::INDEX, Keyword::DIRECTORY])?;
1236 parser.skip_token(Token::Eq);
1237 options.push(TableOption::IndexDirectory {
1238 identifier,
1239 value: parser.consume_string()?,
1240 });
1241 }
1242 Token::Ident(_, Keyword::INSERT_METHOD) => {
1243 let identifier = parser.consume_keyword(Keyword::INSERT_METHOD)?;
1244 parser.skip_token(Token::Eq);
1245 options.push(TableOption::InsertMethod {
1246 identifier,
1247 value: parser.consume_plain_identifier_unreserved()?,
1248 });
1249 }
1250 Token::Ident(_, Keyword::PACK_KEYS) => {
1251 let identifier = parser.consume_keyword(Keyword::PACK_KEYS)?;
1252 parser.skip_token(Token::Eq);
1253 options.push(TableOption::PackKeys {
1254 identifier,
1255 value: parser.consume_int()?,
1256 });
1257 }
1258 Token::Ident(_, Keyword::STATS_AUTO_RECALC) => {
1259 let identifier = parser.consume_keyword(Keyword::STATS_AUTO_RECALC)?;
1260 parser.skip_token(Token::Eq);
1261 options.push(TableOption::StatsAutoRecalc {
1262 identifier,
1263 value: parser.consume_int()?,
1264 });
1265 }
1266 Token::Ident(_, Keyword::STATS_PERSISTENT) => {
1267 let identifier = parser.consume_keyword(Keyword::STATS_PERSISTENT)?;
1268 parser.skip_token(Token::Eq);
1269 options.push(TableOption::StatsPersistent {
1270 identifier,
1271 value: parser.consume_int()?,
1272 });
1273 }
1274 Token::Ident(_, Keyword::STATS_SAMPLE_PAGES) => {
1275 let identifier = parser.consume_keyword(Keyword::STATS_SAMPLE_PAGES)?;
1276 parser.skip_token(Token::Eq);
1277 options.push(TableOption::StatsSamplePages {
1278 identifier,
1279 value: parser.consume_int()?,
1280 });
1281 }
1282 Token::Ident(_, Keyword::DELAY_KEY_WRITE) => {
1283 let identifier = parser.consume_keyword(Keyword::DELAY_KEY_WRITE)?;
1284 parser.skip_token(Token::Eq);
1285 let (val, span) = parser.consume_int::<usize>()?;
1286 options.push(TableOption::DelayKeyWrite {
1287 identifier,
1288 value: (val != 0, span),
1289 });
1290 }
1291 Token::Ident(_, Keyword::COMPRESSION) => {
1292 let identifier = parser.consume_keyword(Keyword::COMPRESSION)?;
1293 parser.skip_token(Token::Eq);
1294 options.push(TableOption::Compression {
1295 identifier,
1296 value: parser.consume_string()?,
1297 });
1298 }
1299 Token::Ident(_, Keyword::ENCRYPTION) => {
1300 let identifier = parser.consume_keyword(Keyword::ENCRYPTION)?;
1301 parser.skip_token(Token::Eq);
1302 let value = match &parser.token {
1304 Token::String(..) => {
1305 let s = parser.consume_string()?;
1306 let is_yes = s.as_str().eq_ignore_ascii_case("y")
1307 || s.as_str().eq_ignore_ascii_case("yes");
1308 (is_yes, s.span())
1309 }
1310 _ => {
1311 let id = parser.consume_plain_identifier_unreserved()?;
1312 let is_yes = id.value.eq_ignore_ascii_case("yes");
1313 (is_yes, id.span())
1314 }
1315 };
1316 options.push(TableOption::Encryption { identifier, value });
1317 }
1318 Token::Ident(_, Keyword::MAX_ROWS) => {
1319 let identifier = parser.consume_keyword(Keyword::MAX_ROWS)?;
1320 parser.skip_token(Token::Eq);
1321 options.push(TableOption::MaxRows {
1322 identifier,
1323 value: parser.consume_int()?,
1324 });
1325 }
1326 Token::Ident(_, Keyword::MIN_ROWS) => {
1327 let identifier = parser.consume_keyword(Keyword::MIN_ROWS)?;
1328 parser.skip_token(Token::Eq);
1329 options.push(TableOption::MinRows {
1330 identifier,
1331 value: parser.consume_int()?,
1332 });
1333 }
1334 Token::Ident(_, Keyword::AUTOEXTEND_SIZE) => {
1335 let identifier = parser.consume_keyword(Keyword::AUTOEXTEND_SIZE)?;
1336 parser.skip_token(Token::Eq);
1337 options.push(TableOption::AutoExtendSize {
1338 identifier,
1339 value: parser.consume_int()?,
1340 });
1341 }
1342 Token::Ident(_, Keyword::AVG_ROW_LENGTH) => {
1343 let identifier = parser.consume_keyword(Keyword::AVG_ROW_LENGTH)?;
1344 parser.skip_token(Token::Eq);
1345 options.push(TableOption::AvgRowLength {
1346 identifier,
1347 value: parser.consume_int()?,
1348 });
1349 }
1350 Token::Ident(_, Keyword::CHECKSUM) => {
1351 let identifier = parser.consume_keyword(Keyword::CHECKSUM)?;
1352 parser.skip_token(Token::Eq);
1353 let (val, span) = parser.consume_int::<usize>()?;
1354 options.push(TableOption::Checksum {
1355 identifier,
1356 value: (val != 0, span),
1357 });
1358 }
1359 Token::Ident(_, Keyword::CONNECTION) => {
1360 let identifier = parser.consume_keyword(Keyword::CONNECTION)?;
1361 parser.skip_token(Token::Eq);
1362 options.push(TableOption::Connection {
1363 identifier,
1364 value: parser.consume_string()?,
1365 });
1366 }
1367 Token::Ident(_, Keyword::ENGINE_ATTRIBUTE) => {
1368 let identifier = parser.consume_keyword(Keyword::ENGINE_ATTRIBUTE)?;
1369 parser.skip_token(Token::Eq);
1370 options.push(TableOption::EngineAttribute {
1371 identifier,
1372 value: parser.consume_string()?,
1373 });
1374 }
1375 Token::Ident(_, Keyword::PASSWORD) => {
1376 let identifier = parser.consume_keyword(Keyword::PASSWORD)?;
1377 parser.skip_token(Token::Eq);
1378 options.push(TableOption::Password {
1379 identifier,
1380 value: parser.consume_string()?,
1381 });
1382 }
1383 Token::Ident(_, Keyword::SECONDARY_ENGINE_ATTRIBUTE) => {
1384 let identifier =
1385 parser.consume_keyword(Keyword::SECONDARY_ENGINE_ATTRIBUTE)?;
1386 parser.skip_token(Token::Eq);
1387 options.push(TableOption::SecondaryEngineAttribute {
1388 identifier,
1389 value: parser.consume_string()?,
1390 });
1391 }
1392 Token::Ident(_, Keyword::START) => {
1393 let identifier =
1394 parser.consume_keywords(&[Keyword::START, Keyword::TRANSACTION])?;
1395 options.push(TableOption::StartTransaction { identifier });
1396 }
1397 Token::Ident(_, Keyword::TABLESPACE) => {
1398 let identifier = parser.consume_keyword(Keyword::TABLESPACE)?;
1399 options.push(TableOption::Tablespace {
1400 identifier,
1401 value: parser.consume_plain_identifier_unreserved()?,
1402 });
1403 }
1404 Token::Ident(_, Keyword::STORAGE) => {
1405 let identifier = parser.consume_keyword(Keyword::STORAGE)?;
1406 options.push(TableOption::Storage {
1407 identifier,
1408 value: parser.consume_plain_identifier_unreserved()?,
1409 });
1410 }
1411 Token::Ident(_, Keyword::UNION) => {
1412 let identifier = parser.consume_keyword(Keyword::UNION)?;
1413 parser.skip_token(Token::Eq);
1414 parser.consume_token(Token::LParen)?;
1415 let mut tables = Vec::new();
1416 loop {
1417 tables.push(parser.consume_plain_identifier_unreserved()?);
1418 if parser.skip_token(Token::Comma).is_none() {
1419 break;
1420 }
1421 }
1422 parser.consume_token(Token::RParen)?;
1423 options.push(TableOption::Union {
1424 identifier,
1425 value: tables,
1426 });
1427 }
1428 Token::Ident(_, Keyword::INHERITS) => {
1429 let identifier = parser.consume_keyword(Keyword::INHERITS)?;
1430 parser.postgres_only(&identifier);
1431 parser.consume_token(Token::LParen)?;
1432 let mut tables = Vec::new();
1433 parser.recovered("')'", &|t| t == &Token::RParen, |parser| {
1434 loop {
1435 tables.push(parse_qualified_name_unreserved(parser)?);
1436 if parser.skip_token(Token::Comma).is_none() {
1437 break;
1438 }
1439 }
1440 Ok(())
1441 })?;
1442 parser.consume_token(Token::RParen)?;
1443 options.push(TableOption::Inherits {
1444 identifier,
1445 value: tables,
1446 });
1447 }
1448 Token::Ident(_, Keyword::WITH) => {
1449 let identifier = parser.consume_keyword(Keyword::WITH)?;
1450 parser.postgres_only(&identifier);
1451 parser.consume_token(Token::LParen)?;
1452 let mut params = Vec::new();
1453 parser.recovered("')'", &|t| t == &Token::RParen, |parser| {
1454 loop {
1455 let key = parser.consume_plain_identifier_unreserved()?;
1456 parser.consume_token(Token::Eq)?;
1457 let val = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1458 params.push((key, val));
1459 if parser.skip_token(Token::Comma).is_none() {
1460 break;
1461 }
1462 }
1463 Ok(())
1464 })?;
1465 parser.consume_token(Token::RParen)?;
1466 options.push(TableOption::WithOptions {
1467 identifier,
1468 options: params,
1469 });
1470 }
1471 Token::Ident(_, Keyword::ON) => {
1472 let identifier =
1473 parser.consume_keywords(&[Keyword::ON, Keyword::COMMIT])?;
1474 parser.postgres_only(&identifier);
1475 let action = match &parser.token {
1476 Token::Ident(_, Keyword::PRESERVE) => OnCommitAction::PreserveRows(
1477 parser.consume_keywords(&[Keyword::PRESERVE, Keyword::ROWS])?,
1478 ),
1479 Token::Ident(_, Keyword::DELETE) => OnCommitAction::DeleteRows(
1480 parser.consume_keywords(&[Keyword::DELETE, Keyword::ROWS])?,
1481 ),
1482 Token::Ident(_, Keyword::DROP) => {
1483 OnCommitAction::Drop(parser.consume_keyword(Keyword::DROP)?)
1484 }
1485 _ => parser.expected_failure("PRESERVE ROWS, DELETE ROWS, or DROP")?,
1486 };
1487 options.push(TableOption::OnCommit { identifier, action });
1488 }
1489 Token::Ident(_, Keyword::PARTITION) => {
1490 partition_by = Some(parse_partition_by(parser)?);
1491 }
1492 Token::Ident(_, Keyword::IGNORE)
1493 | Token::Ident(_, Keyword::REPLACE)
1494 | Token::Ident(_, Keyword::AS) => {
1495 let ignore_span = parser.skip_keyword(Keyword::IGNORE);
1496 let replace_span = parser.skip_keyword(Keyword::REPLACE);
1497 let as_span = parser.consume_keyword(Keyword::AS)?;
1498
1499 if let Some(table_as) = &table_as {
1500 parser.err("Multiple AS clauses not supported", table_as);
1501 }
1502
1503 let query = parse_compound_query(parser)?;
1504 table_as = Some(CreateTableAs {
1505 as_span,
1506 replace_span,
1507 ignore_span,
1508 query,
1509 });
1510 }
1511 Token::Comma => {
1512 parser.consume_token(Token::Comma)?;
1513 }
1514 Token::Delimiter => break,
1515 Token::Eof => break,
1516 _ => {
1517 parser.expected_failure("table option or delimiter")?;
1518 }
1519 }
1520 }
1521 Ok(())
1522 },
1523 )?;
1524
1525 Ok(CreateTable {
1526 create_span,
1527 create_options,
1528 table_span,
1529 identifier,
1530 if_not_exists,
1531 create_definitions,
1532 r_paren_span,
1533 options,
1534 table_as,
1535 partition_by,
1536 })
1537}
1538
1539fn parse_create_table_partition_of<'a>(
1540 parser: &mut Parser<'a, '_>,
1541 create_span: Span,
1542 create_options: Vec<CreateOption<'a>>,
1543 table_span: Span,
1544 if_not_exists: Option<Span>,
1545 identifier: QualifiedName<'a>,
1546) -> Result<CreateTablePartitionOf<'a>, ParseError> {
1547 let partition_span = parser.consume_keyword(Keyword::PARTITION)?;
1548 let of_span = parser.consume_keyword(Keyword::OF)?;
1549 let partition_of_span = partition_span.join_span(&of_span);
1550
1551 let parent_table = parse_qualified_name_unreserved(parser)?;
1552
1553 let mut create_definitions = Vec::new();
1555 if matches!(parser.token, Token::LParen) {
1556 parser.consume_token(Token::LParen)?;
1557 if !matches!(parser.token, Token::RParen) {
1558 loop {
1559 parser.recovered(
1560 "')' or ','",
1561 &|t| matches!(t, Token::RParen | Token::Comma),
1562 |parser| {
1563 create_definitions.push(parse_create_definition(parser)?);
1564 Ok(())
1565 },
1566 )?;
1567 if matches!(parser.token, Token::RParen) {
1568 break;
1569 }
1570 parser.consume_token(Token::Comma)?;
1571 }
1572 }
1573 parser.consume_token(Token::RParen)?;
1574 }
1575
1576 let bound = match &parser.token {
1578 Token::Ident(_, Keyword::DEFAULT) => {
1579 PartitionOfBound::Default(parser.consume_keyword(Keyword::DEFAULT)?)
1580 }
1581 Token::Ident(_, Keyword::FOR) => {
1582 let for_values_span = parser.consume_keywords(&[Keyword::FOR, Keyword::VALUES])?;
1583 let spec = parse_partition_bound_spec(parser)?;
1584 PartitionOfBound::ForValues {
1585 for_values_span,
1586 spec,
1587 }
1588 }
1589 _ => parser.expected_failure("FOR VALUES or DEFAULT")?,
1590 };
1591
1592 let partition_by = if matches!(parser.token, Token::Ident(_, Keyword::PARTITION)) {
1594 Some(parse_partition_by(parser)?)
1595 } else {
1596 None
1597 };
1598
1599 Ok(CreateTablePartitionOf {
1600 create_span,
1601 create_options,
1602 table_span,
1603 if_not_exists,
1604 identifier,
1605 partition_of_span,
1606 parent_table,
1607 create_definitions,
1608 bound,
1609 partition_by,
1610 })
1611}
1612
1613pub(crate) fn parse_create_table_or_partition_of<'a>(
1618 parser: &mut Parser<'a, '_>,
1619 create_span: Span,
1620 create_options: Vec<CreateOption<'a>>,
1621) -> Result<Statement<'a>, ParseError> {
1622 let table_span = parser.consume_keyword(Keyword::TABLE)?;
1623
1624 let if_not_exists = if let Some(if_) = parser.skip_keyword(Keyword::IF) {
1625 Some(
1626 if_.start
1627 ..parser
1628 .consume_keywords(&[Keyword::NOT, Keyword::EXISTS])?
1629 .end,
1630 )
1631 } else {
1632 None
1633 };
1634 let identifier = parse_qualified_name_unreserved(parser)?;
1635
1636 if matches!(parser.token, Token::Ident(_, Keyword::PARTITION)) {
1637 Ok(Statement::CreateTablePartitionOf(Box::new(
1638 parse_create_table_partition_of(
1639 parser,
1640 create_span,
1641 create_options,
1642 table_span,
1643 if_not_exists,
1644 identifier,
1645 )?,
1646 )))
1647 } else if matches!(parser.token, Token::Ident(_, Keyword::AS))
1648 && !matches!(parser.peek(), Token::LParen)
1649 {
1650 let as_span = parser.consume_keyword(Keyword::AS)?;
1652 let query = parse_compound_query(parser)?;
1653 Ok(Statement::CreateTable(Box::new(CreateTable {
1654 create_span: create_span.clone(),
1655 create_options,
1656 table_span,
1657 identifier,
1658 if_not_exists,
1659 create_definitions: alloc::vec![],
1660 r_paren_span: create_span.clone(),
1661 options: alloc::vec![],
1662 table_as: Some(CreateTableAs {
1663 as_span,
1664 replace_span: None,
1665 ignore_span: None,
1666 query,
1667 }),
1668 partition_by: None,
1669 })))
1670 } else {
1671 Ok(Statement::CreateTable(Box::new(parse_create_table(
1672 parser,
1673 create_span,
1674 create_options,
1675 table_span,
1676 if_not_exists,
1677 identifier,
1678 )?)))
1679 }
1680}