1use crate::{
13 DataType, Identifier, QualifiedName, SString, Span, Spanned, Statement,
14 create_constraint_trigger::parse_create_constraint_trigger,
15 create_function::{parse_create_function, parse_create_procedure},
16 create_index::parse_create_index,
17 create_option::{CreateAlgorithm, CreateOption},
18 create_role::parse_create_role,
19 create_table::parse_create_table_or_partition_of,
20 create_trigger::parse_create_trigger,
21 create_view::parse_create_view,
22 data_type::{DataTypeContext, parse_data_type},
23 expression::{Expression, PRIORITY_MAX, parse_expression_unreserved},
24 keywords::Keyword,
25 lexer::Token,
26 operator::{parse_create_operator, parse_create_operator_class, parse_create_operator_family},
27 parser::{ParseError, Parser},
28 qualified_name::parse_qualified_name_unreserved,
29};
30use alloc::{boxed::Box, vec::Vec};
31
32#[derive(Clone, Debug)]
33pub struct CreateTypeEnum<'a> {
34 pub create_span: Span,
36 pub create_options: Vec<CreateOption<'a>>,
38 pub type_span: Span,
40 pub name: QualifiedName<'a>,
42 pub as_enum_span: Span,
44 pub values: Vec<SString<'a>>,
46}
47
48impl<'a> Spanned for CreateTypeEnum<'a> {
49 fn span(&self) -> Span {
50 self.create_span
51 .join_span(&self.create_options)
52 .join_span(&self.type_span)
53 .join_span(&self.name)
54 .join_span(&self.as_enum_span)
55 .join_span(&self.values)
56 }
57}
58
59fn parse_create_type<'a>(
60 parser: &mut Parser<'a, '_>,
61 create_span: Span,
62 create_options: Vec<CreateOption<'a>>,
63) -> Result<CreateTypeEnum<'a>, ParseError> {
64 let type_span = parser.consume_keyword(Keyword::TYPE)?;
65 parser.postgres_only(&type_span);
66 let name = parse_qualified_name_unreserved(parser)?;
67 let as_enum_span = parser.consume_keywords(&[Keyword::AS, Keyword::ENUM])?;
68 parser.consume_token(Token::LParen)?;
69 let mut values = Vec::new();
70 loop {
71 parser.recovered(
72 "')' or ','",
73 &|t| matches!(t, Token::RParen | Token::Comma),
74 |parser| {
75 values.push(parser.consume_string()?);
76 Ok(())
77 },
78 )?;
79 if matches!(parser.token, Token::RParen) {
80 break;
81 }
82 parser.consume_token(Token::Comma)?;
83 }
84 parser.consume_token(Token::RParen)?;
85 Ok(CreateTypeEnum {
86 create_span,
87 create_options,
88 type_span,
89 name,
90 as_enum_span,
91 values,
92 })
93}
94
95#[derive(Clone, Debug)]
96pub enum CreateDatabaseOption<'a> {
97 CharSet {
98 identifier: Span,
99 default_span: Option<Span>,
100 value: Identifier<'a>,
101 },
102 Collate {
103 identifier: Span,
104 default_span: Option<Span>,
105 value: Identifier<'a>,
106 },
107 Encryption {
108 identifier: Span,
109 default_span: Option<Span>,
110 value: SString<'a>,
111 },
112}
113
114impl Spanned for CreateDatabaseOption<'_> {
115 fn span(&self) -> Span {
116 match self {
117 CreateDatabaseOption::CharSet {
118 identifier,
119 default_span,
120 value,
121 } => identifier.join_span(default_span).join_span(value),
122 CreateDatabaseOption::Collate {
123 identifier,
124 default_span,
125 value,
126 } => identifier.join_span(default_span).join_span(value),
127 CreateDatabaseOption::Encryption {
128 identifier,
129 default_span,
130 value,
131 } => identifier.join_span(default_span).join_span(value),
132 }
133 }
134}
135
136#[derive(Clone, Debug)]
137pub struct CreateDatabase<'a> {
138 pub create_span: Span,
140 pub database_span: Span,
142 pub if_not_exists: Option<Span>,
144 pub name: Identifier<'a>,
146 pub create_options: Vec<CreateDatabaseOption<'a>>,
148}
149
150impl Spanned for CreateDatabase<'_> {
151 fn span(&self) -> Span {
152 self.create_span
153 .join_span(&self.create_options)
154 .join_span(&self.database_span)
155 .join_span(&self.if_not_exists)
156 .join_span(&self.name)
157 }
158}
159
160#[derive(Clone, Debug)]
162pub struct CreateExtension<'a> {
163 pub create_span: Span,
165 pub extension_span: Span,
167 pub if_not_exists: Option<Span>,
169 pub name: Identifier<'a>,
171 pub schema: Option<(Span, Identifier<'a>)>,
173 pub version: Option<(Span, SString<'a>)>,
175 pub cascade: Option<Span>,
177}
178
179impl Spanned for CreateExtension<'_> {
180 fn span(&self) -> Span {
181 self.create_span
182 .join_span(&self.extension_span)
183 .join_span(&self.if_not_exists)
184 .join_span(&self.name)
185 .join_span(&self.schema)
186 .join_span(&self.version)
187 .join_span(&self.cascade)
188 }
189}
190
191fn parse_create_extension<'a>(
192 parser: &mut Parser<'a, '_>,
193 create_span: Span,
194 create_options: Vec<CreateOption<'a>>,
195) -> Result<CreateExtension<'a>, ParseError> {
196 let extension_span = parser.consume_keyword(Keyword::EXTENSION)?;
197 parser.postgres_only(&extension_span);
198
199 for option in create_options {
200 parser.err("Not supported for CREATE EXTENSION", &option.span());
201 }
202
203 let if_not_exists = if let Some(if_span) = parser.skip_keyword(Keyword::IF) {
204 Some(
205 parser
206 .consume_keywords(&[Keyword::NOT, Keyword::EXISTS])?
207 .join_span(&if_span),
208 )
209 } else {
210 None
211 };
212
213 let name = parser.consume_plain_identifier_unreserved()?;
214
215 parser.skip_keyword(Keyword::WITH);
217
218 let mut schema = None;
220 let mut version = None;
221 let mut cascade = None;
222 loop {
223 match &parser.token {
224 Token::Ident(_, Keyword::SCHEMA) => {
225 let schema_span = parser.consume_keyword(Keyword::SCHEMA)?;
226 let schema_name = parser.consume_plain_identifier_unreserved()?;
227 schema = Some((schema_span, schema_name));
228 }
229 Token::Ident(_, Keyword::VERSION) => {
230 let version_span = parser.consume_keyword(Keyword::VERSION)?;
231 let version_value = match &parser.token {
233 Token::String(v, _) => SString::new((*v).into(), parser.consume()),
234 _ => {
235 let ident = parser.consume_plain_identifier_unreserved()?;
236 SString::new(ident.value.into(), ident.span)
237 }
238 };
239 version = Some((version_span, version_value));
240 }
241 Token::Ident(_, Keyword::CASCADE) => {
242 cascade = Some(parser.consume_keyword(Keyword::CASCADE)?);
243 }
244 _ => break,
245 }
246 }
247
248 Ok(CreateExtension {
249 create_span,
250 extension_span,
251 if_not_exists,
252 name,
253 schema,
254 version,
255 cascade,
256 })
257}
258
259#[derive(Clone, Debug)]
261pub struct CreateDomain<'a> {
262 pub create_span: Span,
264 pub domain_span: Span,
266 pub if_not_exists: Option<Span>,
268 pub name: QualifiedName<'a>,
270 pub data_type: DataType<'a>,
272 pub collate: Option<(Span, Identifier<'a>)>,
274 pub default: Option<(Span, Expression<'a>)>,
276 pub constraints: Vec<DomainConstraint<'a>>,
278}
279
280impl<'a> Spanned for CreateDomain<'a> {
281 fn span(&self) -> Span {
282 self.create_span
283 .join_span(&self.domain_span)
284 .join_span(&self.if_not_exists)
285 .join_span(&self.name)
286 .join_span(&self.data_type)
287 .join_span(&self.collate)
288 .join_span(&self.default)
289 .join_span(&self.constraints)
290 }
291}
292
293#[derive(Clone, Debug)]
295pub enum DomainConstraint<'a> {
296 ConstraintName(Span, Identifier<'a>),
297 NotNull(Span),
298 Null(Span),
299 Check(Span, Expression<'a>),
300}
301
302impl<'a> Spanned for DomainConstraint<'a> {
303 fn span(&self) -> Span {
304 match self {
305 DomainConstraint::ConstraintName(span, name) => span.join_span(name),
306 DomainConstraint::NotNull(span) => span.clone(),
307 DomainConstraint::Null(span) => span.clone(),
308 DomainConstraint::Check(span, expr) => span.join_span(expr),
309 }
310 }
311}
312
313pub fn parse_create_domain<'a>(
315 parser: &mut Parser<'a, '_>,
316 create_span: Span,
317 create_options: Vec<CreateOption<'a>>,
318) -> Result<CreateDomain<'a>, ParseError> {
319 let domain_span = parser.consume_keyword(Keyword::DOMAIN)?;
320 parser.postgres_only(&domain_span);
321
322 for option in create_options {
323 parser.err("Not supported for CREATE DOMAIN", &option.span());
324 }
325
326 let if_not_exists = if let Some(if_span) = parser.skip_keyword(Keyword::IF) {
327 Some(
328 parser
329 .consume_keywords(&[Keyword::NOT, Keyword::EXISTS])?
330 .join_span(&if_span),
331 )
332 } else {
333 None
334 };
335
336 let name = parse_qualified_name_unreserved(parser)?;
337
338 parser.skip_keyword(Keyword::AS);
340
341 let data_type = parse_data_type(parser, DataTypeContext::Column)?;
342
343 let collate = if let Some(collate_span) = parser.skip_keyword(Keyword::COLLATE) {
345 let collate_name = parser.consume_plain_identifier_unreserved()?;
346 Some((collate_span, collate_name))
347 } else {
348 None
349 };
350
351 let default = if let Some(default_span) = parser.skip_keyword(Keyword::DEFAULT) {
353 let expr = parse_expression_unreserved(parser, PRIORITY_MAX)?;
354 Some((default_span, expr))
355 } else {
356 None
357 };
358
359 let mut constraints = Vec::new();
361 loop {
362 match &parser.token {
363 Token::Ident(_, Keyword::CONSTRAINT) => {
364 let constraint_span = parser.consume_keyword(Keyword::CONSTRAINT)?;
365 let name = parser.consume_plain_identifier_unreserved()?;
366 constraints.push(DomainConstraint::ConstraintName(constraint_span, name));
367 }
368 Token::Ident(_, Keyword::NOT) => {
369 let not_span = parser.consume_keyword(Keyword::NOT)?;
370 let null_span = parser.consume_keyword(Keyword::NULL)?;
371 constraints.push(DomainConstraint::NotNull(not_span.join_span(&null_span)));
372 }
373 Token::Ident(_, Keyword::NULL) => {
374 let null_span = parser.consume_keyword(Keyword::NULL)?;
375 constraints.push(DomainConstraint::Null(null_span));
376 }
377 Token::Ident(_, Keyword::CHECK) => {
378 let check_span = parser.consume_keyword(Keyword::CHECK)?;
379 parser.consume_token(Token::LParen)?;
380 let expr = parse_expression_unreserved(parser, PRIORITY_MAX)?;
381 parser.consume_token(Token::RParen)?;
382 constraints.push(DomainConstraint::Check(check_span, expr));
383 }
384 _ => break,
385 }
386 }
387
388 Ok(CreateDomain {
389 create_span,
390 domain_span,
391 if_not_exists,
392 name,
393 data_type,
394 collate,
395 default,
396 constraints,
397 })
398}
399
400#[derive(Clone, Debug)]
402pub struct CreateSchema<'a> {
403 pub create_span: Span,
405 pub schema_span: Span,
407 pub if_not_exists: Option<Span>,
409 pub name: Option<Identifier<'a>>,
411 pub authorization: Option<(Span, Identifier<'a>)>,
413}
414
415impl Spanned for CreateSchema<'_> {
416 fn span(&self) -> Span {
417 self.create_span
418 .join_span(&self.schema_span)
419 .join_span(&self.if_not_exists)
420 .join_span(&self.name)
421 .join_span(&self.authorization)
422 }
423}
424
425#[derive(Clone, Debug)]
427pub enum SequenceOption<'a> {
428 As {
430 as_span: Span,
431 data_type: DataType<'a>,
432 },
433 IncrementBy {
435 increment_span: Span,
436 by_span: Option<Span>,
437 value: i64,
438 value_span: Span,
439 },
440 MinValue {
442 minvalue_span: Span,
443 value: i64,
444 value_span: Span,
445 },
446 NoMinValue(Span),
448 MaxValue {
450 maxvalue_span: Span,
451 value: i64,
452 value_span: Span,
453 },
454 NoMaxValue(Span),
456 StartWith {
458 start_span: Span,
459 with_span: Option<Span>,
460 value: i64,
461 value_span: Span,
462 },
463 Restart {
465 restart_span: Span,
466 with_span: Option<Span>,
467 value: Option<i64>,
468 value_span: Option<Span>,
469 },
470 Cache {
472 cache_span: Span,
473 value: i64,
474 value_span: Span,
475 },
476 Cycle(Span),
478 NoCycle(Span),
480 OwnedBy {
482 owned_span: Span,
483 by_span: Span,
484 table_column: QualifiedName<'a>,
485 },
486 OwnedByNone {
488 owned_span: Span,
489 by_span: Span,
490 none_span: Span,
491 },
492}
493
494impl<'a> Spanned for SequenceOption<'a> {
495 fn span(&self) -> Span {
496 match self {
497 SequenceOption::As { as_span, data_type } => as_span.join_span(data_type),
498 SequenceOption::IncrementBy {
499 increment_span,
500 value_span,
501 ..
502 } => increment_span.join_span(value_span),
503 SequenceOption::MinValue {
504 minvalue_span,
505 value_span,
506 ..
507 } => minvalue_span.join_span(value_span),
508 SequenceOption::NoMinValue(s) => s.span(),
509 SequenceOption::MaxValue {
510 maxvalue_span,
511 value_span,
512 ..
513 } => maxvalue_span.join_span(value_span),
514 SequenceOption::NoMaxValue(s) => s.span(),
515 SequenceOption::StartWith {
516 start_span,
517 value_span,
518 ..
519 } => start_span.join_span(value_span),
520 SequenceOption::Restart {
521 restart_span,
522 value_span,
523 ..
524 } => restart_span.join_span(value_span),
525 SequenceOption::Cache {
526 cache_span,
527 value_span,
528 ..
529 } => cache_span.join_span(value_span),
530 SequenceOption::Cycle(s) => s.span(),
531 SequenceOption::NoCycle(s) => s.span(),
532 SequenceOption::OwnedBy {
533 owned_span,
534 table_column,
535 ..
536 } => owned_span.join_span(table_column),
537 SequenceOption::OwnedByNone {
538 owned_span,
539 none_span,
540 ..
541 } => owned_span.join_span(none_span),
542 }
543 }
544}
545
546pub(crate) fn parse_sequence_options<'a>(
548 parser: &mut Parser<'a, '_>,
549) -> Result<Vec<SequenceOption<'a>>, ParseError> {
550 let mut options = Vec::new();
551 loop {
552 match &parser.token {
553 Token::Ident(_, Keyword::AS) => {
554 let as_span = parser.consume_keyword(Keyword::AS)?;
555 let data_type = parse_data_type(parser, DataTypeContext::TypeRef)?;
556 options.push(SequenceOption::As { as_span, data_type });
557 }
558 Token::Ident(_, Keyword::INCREMENT) => {
559 let increment_span = parser.consume_keyword(Keyword::INCREMENT)?;
560 let by_span = parser.skip_keyword(Keyword::BY); let (value, value_span) = parser.consume_signed_int::<i64>()?;
562 options.push(SequenceOption::IncrementBy {
563 increment_span,
564 by_span,
565 value,
566 value_span,
567 });
568 }
569 Token::Ident(_, Keyword::MINVALUE) => {
570 let minvalue_span = parser.consume_keyword(Keyword::MINVALUE)?;
571 let (value, value_span) = parser.consume_signed_int::<i64>()?;
572 options.push(SequenceOption::MinValue {
573 minvalue_span,
574 value,
575 value_span,
576 });
577 }
578 Token::Ident(_, Keyword::MAXVALUE) => {
579 let maxvalue_span = parser.consume_keyword(Keyword::MAXVALUE)?;
580 let (value, value_span) = parser.consume_signed_int::<i64>()?;
581 options.push(SequenceOption::MaxValue {
582 maxvalue_span,
583 value,
584 value_span,
585 });
586 }
587 Token::Ident(_, Keyword::START) => {
588 let start_span = parser.consume_keyword(Keyword::START)?;
589 let with_span = parser.skip_keyword(Keyword::WITH); let (value, value_span) = parser.consume_signed_int::<i64>()?;
591 options.push(SequenceOption::StartWith {
592 start_span,
593 with_span,
594 value,
595 value_span,
596 });
597 }
598 Token::Ident(_, Keyword::RESTART) => {
599 let restart_span = parser.consume_keyword(Keyword::RESTART)?;
600 let with_span = parser.skip_keyword(Keyword::WITH); let has_value = match &parser.token {
604 Token::Integer(_) | Token::Minus | Token::Plus => true,
605 _ => with_span.is_some(),
606 };
607 if has_value {
608 let (value, value_span) = parser.consume_signed_int::<i64>()?;
610 options.push(SequenceOption::Restart {
611 restart_span,
612 with_span,
613 value: Some(value),
614 value_span: Some(value_span),
615 });
616 } else {
617 options.push(SequenceOption::Restart {
618 restart_span,
619 with_span,
620 value: None,
621 value_span: None,
622 });
623 }
624 }
625 Token::Ident(_, Keyword::CACHE) => {
626 let cache_span = parser.consume_keyword(Keyword::CACHE)?;
627 let (value, value_span) = parser.consume_signed_int::<i64>()?;
628 options.push(SequenceOption::Cache {
629 cache_span,
630 value,
631 value_span,
632 });
633 }
634 Token::Ident(_, Keyword::CYCLE) => {
635 let cycle_span = parser.consume_keyword(Keyword::CYCLE)?;
636 options.push(SequenceOption::Cycle(cycle_span));
637 }
638 Token::Ident(_, Keyword::NO) => {
639 let no_span = parser.consume_keyword(Keyword::NO)?;
641 match &parser.token {
642 Token::Ident(_, Keyword::MINVALUE) => {
643 let minvalue_span = parser.consume_keyword(Keyword::MINVALUE)?;
644 let span = no_span.join_span(&minvalue_span);
645 options.push(SequenceOption::NoMinValue(span));
646 }
647 Token::Ident(_, Keyword::MAXVALUE) => {
648 let maxvalue_span = parser.consume_keyword(Keyword::MAXVALUE)?;
649 let span = no_span.join_span(&maxvalue_span);
650 options.push(SequenceOption::NoMaxValue(span));
651 }
652 Token::Ident(_, Keyword::CYCLE) => {
653 let cycle_span = parser.consume_keyword(Keyword::CYCLE)?;
654 let span = no_span.join_span(&cycle_span);
655 options.push(SequenceOption::NoCycle(span));
656 }
657 _ => parser.expected_failure("'MINVALUE', 'MAXVALUE' or 'CYCLE' after 'NO'")?,
658 }
659 }
660 Token::Ident(_, Keyword::OWNED) => {
661 let owned_span = parser.consume_keyword(Keyword::OWNED)?;
662 let by_span = parser.consume_keyword(Keyword::BY)?;
663 if let Token::Ident(_, Keyword::NONE) = parser.token {
664 let none_span = parser.consume_keyword(Keyword::NONE)?;
665 options.push(SequenceOption::OwnedByNone {
666 owned_span,
667 by_span,
668 none_span,
669 });
670 } else {
671 let table_column = parse_qualified_name_unreserved(parser)?;
672 options.push(SequenceOption::OwnedBy {
673 owned_span,
674 by_span,
675 table_column,
676 });
677 }
678 }
679 _ => break,
680 }
681 }
682 Ok(options)
683}
684
685#[derive(Clone, Debug)]
687pub struct CreateSequence<'a> {
688 pub create_span: Span,
690 pub temporary: Option<Span>,
692 pub sequence_span: Span,
694 pub if_not_exists: Option<Span>,
696 pub name: QualifiedName<'a>,
698 pub options: Vec<SequenceOption<'a>>,
700}
701
702impl Spanned for CreateSequence<'_> {
703 fn span(&self) -> Span {
704 self.create_span
705 .join_span(&self.temporary)
706 .join_span(&self.sequence_span)
707 .join_span(&self.if_not_exists)
708 .join_span(&self.name)
709 .join_span(&self.options)
710 }
711}
712
713fn parse_create_database<'a>(
714 parser: &mut Parser<'a, '_>,
715 create_span: Span,
716 create_options: Vec<CreateOption<'a>>,
717) -> Result<CreateDatabase<'a>, ParseError> {
718 for option in create_options {
719 parser.err("Not supported fo CREATE DATABASE", &option.span());
720 }
721
722 let database_span = parser.consume();
723
724 let if_not_exists = if let Some(if_) = parser.skip_keyword(Keyword::IF) {
725 Some(
726 parser
727 .consume_keywords(&[Keyword::NOT, Keyword::EXISTS])?
728 .join_span(&if_),
729 )
730 } else {
731 None
732 };
733
734 let mut create_options = Vec::new();
735 let name = parser.consume_plain_identifier_unreserved()?;
736 loop {
737 let default_span = parser.skip_keyword(Keyword::DEFAULT);
738 match &parser.token {
739 Token::Ident(_, Keyword::CHARSET) => {
740 let identifier = parser.consume_keyword(Keyword::CHARSET)?;
741 parser.skip_token(Token::Eq);
742 create_options.push(CreateDatabaseOption::CharSet {
743 default_span,
744 identifier,
745 value: parser.consume_plain_identifier_unreserved()?,
746 });
747 }
748 Token::Ident(_, Keyword::CHARACTER) => {
749 let identifier = parser.consume_keywords(&[Keyword::CHARACTER, Keyword::SET])?;
750 parser.skip_token(Token::Eq);
751 create_options.push(CreateDatabaseOption::CharSet {
752 default_span,
753 identifier,
754 value: parser.consume_plain_identifier_unreserved()?,
755 });
756 }
757 Token::Ident(_, Keyword::COLLATE) => {
758 let identifier = parser.consume_keyword(Keyword::COLLATE)?;
759 parser.skip_token(Token::Eq);
760 create_options.push(CreateDatabaseOption::Collate {
761 default_span,
762 identifier,
763 value: parser.consume_plain_identifier_unreserved()?,
764 });
765 }
766 Token::Ident(_, Keyword::ENCRYPTION) => {
767 let identifier = parser.consume_keyword(Keyword::ENCRYPTION)?;
768 parser.skip_token(Token::Eq);
769 let value = parser.consume_string()?;
770
771 create_options.push(CreateDatabaseOption::Encryption {
772 default_span,
773 identifier,
774 value,
775 });
776 }
777 _ => {
778 if default_span.is_some() {
779 parser.expected_failure("'CHARSET', 'COLLATE' or 'ENCRYPTION'")?;
780 }
781 break;
782 }
783 }
784 }
785
786 Ok(CreateDatabase {
787 create_span,
788 create_options,
789 database_span,
790 if_not_exists,
791 name,
792 })
793}
794
795fn parse_create_schema<'a>(
796 parser: &mut Parser<'a, '_>,
797 create_span: Span,
798 create_options: Vec<CreateOption<'a>>,
799) -> Result<CreateSchema<'a>, ParseError> {
800 let schema_span = parser.consume_keyword(Keyword::SCHEMA)?;
801 parser.postgres_only(&schema_span);
802
803 for option in create_options {
804 parser.err("Not supported for CREATE SCHEMA", &option.span());
805 }
806
807 let if_not_exists = if let Some(if_span) = parser.skip_keyword(Keyword::IF) {
808 Some(
809 parser
810 .consume_keywords(&[Keyword::NOT, Keyword::EXISTS])?
811 .join_span(&if_span),
812 )
813 } else {
814 None
815 };
816
817 let name = if matches!(parser.token, Token::Ident(_, Keyword::AUTHORIZATION)) {
819 None
820 } else {
821 Some(parser.consume_plain_identifier_unreserved()?)
822 };
823
824 let authorization = if let Token::Ident(_, Keyword::AUTHORIZATION) = parser.token {
825 let auth_span = parser.consume_keyword(Keyword::AUTHORIZATION)?;
826 let role_name = parser.consume_plain_identifier_unreserved()?;
827 Some((auth_span, role_name))
828 } else {
829 None
830 };
831
832 Ok(CreateSchema {
835 create_span,
836 schema_span,
837 if_not_exists,
838 name,
839 authorization,
840 })
841}
842
843fn parse_create_sequence<'a>(
844 parser: &mut Parser<'a, '_>,
845 create_span: Span,
846 create_options: Vec<CreateOption<'a>>,
847) -> Result<CreateSequence<'a>, ParseError> {
848 let sequence_span = parser.consume_keyword(Keyword::SEQUENCE)?;
849 parser.postgres_only(&sequence_span);
850
851 let mut temporary = None;
853 for option in create_options {
854 match option {
855 CreateOption::Temporary {
856 local_span,
857 temporary_span,
858 } => {
859 temporary = Some(temporary_span.join_span(&local_span));
860 }
861 _ => {
862 parser.err("Not supported for CREATE SEQUENCE", &option.span());
863 }
864 }
865 }
866
867 let if_not_exists = if let Some(if_span) = parser.skip_keyword(Keyword::IF) {
868 Some(
869 parser
870 .consume_keywords(&[Keyword::NOT, Keyword::EXISTS])?
871 .join_span(&if_span),
872 )
873 } else {
874 None
875 };
876
877 let name = parse_qualified_name_unreserved(parser)?;
879
880 let options = parse_sequence_options(parser)?;
882
883 Ok(CreateSequence {
884 create_span,
885 temporary,
886 sequence_span,
887 if_not_exists,
888 name,
889 options,
890 })
891}
892
893#[derive(Clone, Debug)]
895pub struct CreateServer<'a> {
896 pub create_span: Span,
898 pub server_span: Span,
900 pub if_not_exists: Option<Span>,
902 pub server_name: Identifier<'a>,
904 pub type_: Option<(Span, SString<'a>)>,
906 pub version: Option<(Span, SString<'a>)>,
908 pub foreign_data_wrapper: (Span, Identifier<'a>),
910 pub options: Vec<(Identifier<'a>, SString<'a>)>,
912}
913
914impl Spanned for CreateServer<'_> {
915 fn span(&self) -> Span {
916 self.create_span
917 .join_span(&self.server_span)
918 .join_span(&self.if_not_exists)
919 .join_span(&self.server_name)
920 .join_span(&self.type_)
921 .join_span(&self.version)
922 .join_span(&self.foreign_data_wrapper)
923 .join_span(&self.options)
924 }
925}
926
927fn parse_create_server<'a>(
928 parser: &mut Parser<'a, '_>,
929 create_span: Span,
930 create_options: Vec<CreateOption<'a>>,
931) -> Result<CreateServer<'a>, ParseError> {
932 let server_span = parser.consume_keyword(Keyword::SERVER)?;
933 parser.postgres_only(&server_span);
934
935 for option in create_options {
936 parser.err("Not supported for CREATE SERVER", &option.span());
937 }
938
939 let if_not_exists = if let Some(if_span) = parser.skip_keyword(Keyword::IF) {
940 Some(
941 parser
942 .consume_keywords(&[Keyword::NOT, Keyword::EXISTS])?
943 .join_span(&if_span),
944 )
945 } else {
946 None
947 };
948
949 let server_name = parser.consume_plain_identifier_unreserved()?;
951
952 let type_ = if let Some(type_span) = parser.skip_keyword(Keyword::TYPE) {
954 let type_value = parser.consume_string()?;
955 Some((type_span, type_value))
956 } else {
957 None
958 };
959
960 let version = if let Some(version_span) = parser.skip_keyword(Keyword::VERSION) {
962 let version_value = parser.consume_string()?;
963 Some((version_span, version_value))
964 } else {
965 None
966 };
967
968 let fdw_span = parser.consume_keywords(&[Keyword::FOREIGN, Keyword::DATA, Keyword::WRAPPER])?;
970 let fdw_name = parser.consume_plain_identifier_unreserved()?;
971 let foreign_data_wrapper = (fdw_span, fdw_name);
972
973 let mut options = Vec::new();
975 if parser.skip_keyword(Keyword::OPTIONS).is_some() {
976 parser.consume_token(Token::LParen)?;
977 loop {
978 let option_name = parser.consume_plain_identifier_unreserved()?;
979 let option_value = parser.consume_string()?;
980 options.push((option_name, option_value));
981
982 if parser.skip_token(Token::Comma).is_none() {
983 break;
984 }
985 }
986 parser.consume_token(Token::RParen)?;
987 }
988
989 Ok(CreateServer {
990 create_span,
991 server_span,
992 if_not_exists,
993 server_name,
994 type_,
995 version,
996 foreign_data_wrapper,
997 options,
998 })
999}
1000
1001pub(crate) fn parse_create<'a>(parser: &mut Parser<'a, '_>) -> Result<Statement<'a>, ParseError> {
1002 let create_span = parser.span.clone();
1003 parser.consume_keyword(Keyword::CREATE)?;
1004
1005 let mut create_options = Vec::new();
1006 const CREATABLE: &str = "'TABLE' | 'VIEW' | 'TRIGGER' | 'FUNCTION' | 'PROCEDURE' | 'INDEX' | 'TYPE' | 'DATABASE' | 'DOMAIN' |'EXTENSION' | 'SCHEMA' | 'SEQUENCE' | 'ROLE' | 'SERVER' | 'OPERATOR' | 'CONSTRAINT'";
1007
1008 parser.recovered(
1009 CREATABLE,
1010 &|t| {
1011 matches!(
1012 t,
1013 Token::Ident(
1014 _,
1015 Keyword::TABLE
1016 | Keyword::MATERIALIZED
1017 | Keyword::VIEW
1018 | Keyword::TRIGGER
1019 | Keyword::FUNCTION
1020 | Keyword::PROCEDURE
1021 | Keyword::INDEX
1022 | Keyword::TYPE
1023 | Keyword::DATABASE
1024 | Keyword::SCHEMA
1025 | Keyword::SEQUENCE
1026 | Keyword::ROLE
1027 | Keyword::SERVER
1028 | Keyword::OPERATOR
1029 | Keyword::EXTENSION
1030 | Keyword::DOMAIN
1031 | Keyword::CONSTRAINT
1032 )
1033 )
1034 },
1035 |parser| {
1036 loop {
1037 let v = match &parser.token {
1038 Token::Ident(_, Keyword::OR) => CreateOption::OrReplace(
1039 parser.consume_keywords(&[Keyword::OR, Keyword::REPLACE])?,
1040 ),
1041 Token::Ident(_, Keyword::LOCAL) => {
1042 let local_span = parser.consume_keyword(Keyword::LOCAL)?;
1044 parser.postgres_only(&local_span);
1045 let temporary_span = parser.consume_keyword(Keyword::TEMPORARY)?;
1046 CreateOption::Temporary {
1047 local_span: Some(local_span),
1048 temporary_span,
1049 }
1050 }
1051 Token::Ident(_, Keyword::TEMPORARY) => {
1052 let temporary_span = parser.consume_keyword(Keyword::TEMPORARY)?;
1053 CreateOption::Temporary {
1054 local_span: None,
1055 temporary_span,
1056 }
1057 }
1058 Token::Ident(_, Keyword::UNIQUE) => {
1059 CreateOption::Unique(parser.consume_keyword(Keyword::UNIQUE)?)
1060 }
1061 Token::Ident(_, Keyword::ALGORITHM) => {
1062 let algorithm_span = parser.consume_keyword(Keyword::ALGORITHM)?;
1063 parser.consume_token(Token::Eq)?;
1064 let algorithm = match &parser.token {
1065 Token::Ident(_, Keyword::UNDEFINED) => CreateAlgorithm::Undefined(
1066 parser.consume_keyword(Keyword::UNDEFINED)?,
1067 ),
1068 Token::Ident(_, Keyword::MERGE) => {
1069 CreateAlgorithm::Merge(parser.consume_keyword(Keyword::MERGE)?)
1070 }
1071 Token::Ident(_, Keyword::TEMPTABLE) => CreateAlgorithm::TempTable(
1072 parser.consume_keyword(Keyword::TEMPTABLE)?,
1073 ),
1074 _ => parser.expected_failure("'UNDEFINED', 'MERGE' or 'TEMPTABLE'")?,
1075 };
1076 CreateOption::Algorithm(algorithm_span, algorithm)
1077 }
1078 Token::Ident(_, Keyword::DEFINER) => {
1079 let definer_span = parser.consume_keyword(Keyword::DEFINER)?;
1080 parser.consume_token(Token::Eq)?;
1081 let user = match &parser.token {
1084 Token::String(v, _) => {
1085 let v = *v;
1086 Identifier::new(v, parser.consume())
1087 }
1088 _ => parser.consume_plain_identifier_unreserved()?,
1089 };
1090 parser.consume_token(Token::At)?;
1091 let host = match &parser.token {
1092 Token::String(v, _) => {
1093 let v = *v;
1094 Identifier::new(v, parser.consume())
1095 }
1096 _ => parser.consume_plain_identifier_unreserved()?,
1097 };
1098 CreateOption::Definer {
1099 definer_span,
1100 user,
1101 host,
1102 }
1103 }
1104 Token::Ident(_, Keyword::SQL) => {
1105 let sql_security =
1106 parser.consume_keywords(&[Keyword::SQL, Keyword::SECURITY])?;
1107 match &parser.token {
1108 Token::Ident(_, Keyword::DEFINER) => CreateOption::SqlSecurityDefiner(
1109 sql_security,
1110 parser.consume_keyword(Keyword::DEFINER)?,
1111 ),
1112 Token::Ident(_, Keyword::INVOKER) => CreateOption::SqlSecurityInvoker(
1113 sql_security,
1114 parser.consume_keyword(Keyword::INVOKER)?,
1115 ),
1116 Token::Ident(_, Keyword::USER) => CreateOption::SqlSecurityUser(
1117 sql_security,
1118 parser.consume_keyword(Keyword::USER)?,
1119 ),
1120 _ => parser.expected_failure("'DEFINER', 'INVOKER', 'USER'")?,
1121 }
1122 }
1123 _ => break,
1124 };
1125 create_options.push(v);
1126 }
1127 Ok(())
1128 },
1129 )?;
1130
1131 let r =
1132 match &parser.token {
1133 Token::Ident(_, Keyword::INDEX) => Statement::CreateIndex(Box::new(
1134 parse_create_index(parser, create_span, create_options)?,
1135 )),
1136 Token::Ident(_, Keyword::TABLE) => {
1137 parse_create_table_or_partition_of(parser, create_span, create_options)?
1138 }
1139 Token::Ident(_, Keyword::MATERIALIZED) => {
1140 let materialized_span = parser.consume_keyword(Keyword::MATERIALIZED)?;
1142 parser.postgres_only(&materialized_span);
1143 create_options.push(CreateOption::Materialized(materialized_span));
1145 Statement::CreateView(Box::new(parse_create_view(
1146 parser,
1147 create_span,
1148 create_options,
1149 )?))
1150 }
1151 Token::Ident(_, Keyword::VIEW) => Statement::CreateView(Box::new(parse_create_view(
1152 parser,
1153 create_span,
1154 create_options,
1155 )?)),
1156 Token::Ident(_, Keyword::CONSTRAINT) => Statement::CreateConstraintTrigger(Box::new(
1157 parse_create_constraint_trigger(parser, create_span, create_options)?,
1158 )),
1159 Token::Ident(_, Keyword::DATABASE) => Statement::CreateDatabase(Box::new(
1160 parse_create_database(parser, create_span, create_options)?,
1161 )),
1162 Token::Ident(_, Keyword::DOMAIN) => Statement::CreateDomain(Box::new(
1163 parse_create_domain(parser, create_span, create_options)?,
1164 )),
1165 Token::Ident(_, Keyword::EXTENSION) => Statement::CreateExtension(Box::new(
1166 parse_create_extension(parser, create_span, create_options)?,
1167 )),
1168 Token::Ident(_, Keyword::SCHEMA) => Statement::CreateSchema(Box::new(
1169 parse_create_schema(parser, create_span, create_options)?,
1170 )),
1171 Token::Ident(_, Keyword::SEQUENCE) => Statement::CreateSequence(Box::new(
1172 parse_create_sequence(parser, create_span, create_options)?,
1173 )),
1174 Token::Ident(_, Keyword::FUNCTION) => Statement::CreateFunction(Box::new(
1175 parse_create_function(parser, create_span, create_options)?,
1176 )),
1177 Token::Ident(_, Keyword::PROCEDURE) => Statement::CreateProcedure(Box::new(
1178 parse_create_procedure(parser, create_span, create_options)?,
1179 )),
1180 Token::Ident(_, Keyword::TRIGGER) => Statement::CreateTrigger(Box::new(
1181 parse_create_trigger(parser, create_span, create_options)?,
1182 )),
1183 Token::Ident(_, Keyword::TYPE) => Statement::CreateTypeEnum(Box::new(
1184 parse_create_type(parser, create_span, create_options)?,
1185 )),
1186 Token::Ident(_, Keyword::ROLE) => Statement::CreateRole(Box::new(parse_create_role(
1187 parser,
1188 create_span,
1189 create_options,
1190 )?)),
1191 Token::Ident(_, Keyword::SERVER) => Statement::CreateServer(Box::new(
1192 parse_create_server(parser, create_span, create_options)?,
1193 )),
1194 Token::Ident(_, Keyword::OPERATOR) => {
1195 let operator_span = parser.consume_keyword(Keyword::OPERATOR)?;
1196 match parser.token {
1197 Token::Ident(_, Keyword::FAMILY) => {
1198 let family_span = parser.consume_keyword(Keyword::FAMILY)?;
1200 parser.postgres_only(&family_span);
1201 Statement::CreateOperatorFamily(Box::new(parse_create_operator_family(
1202 parser,
1203 create_span
1204 .join_span(&operator_span)
1205 .join_span(&family_span),
1206 create_options,
1207 )?))
1208 }
1209 Token::Ident(_, Keyword::CLASS) => {
1210 let class_span = parser.consume_keyword(Keyword::CLASS)?;
1212 Statement::CreateOperatorClass(Box::new(parse_create_operator_class(
1213 parser,
1214 create_span.join_span(&operator_span).join_span(&class_span),
1215 create_options,
1216 )?))
1217 }
1218 _ => {
1219 Statement::CreateOperator(Box::new(parse_create_operator(
1221 parser,
1222 create_span.join_span(&operator_span),
1223 create_options,
1224 )?))
1225 }
1226 }
1227 }
1228 _ => return parser.expected_failure(CREATABLE),
1229 };
1230 Ok(r)
1231}