1use alloc::{borrow::Cow, boxed::Box, vec::Vec};
13
14use crate::QualifiedName;
15use crate::qualified_name::parse_qualified_name_unreserved;
16use crate::{
17 DataType, Identifier, SString, Span, Spanned, Statement,
18 data_type::{DataTypeContext, parse_data_type},
19 expression::{Expression, PRIORITY_MAX, parse_expression_unreserved},
20 keywords::{Keyword, Restrict},
21 lexer::{StringType, Token},
22 parser::{ParseError, Parser},
23 span::OptSpanned,
24 statement::parse_compound_query,
25};
26
27#[derive(Debug, Clone)]
29pub struct SelectExpr<'a> {
30 pub expr: Expression<'a>,
32 pub as_: Option<Identifier<'a>>,
34}
35
36impl<'a> Spanned for SelectExpr<'a> {
37 fn span(&self) -> Span {
38 self.expr.join_span(&self.as_)
39 }
40}
41
42pub(crate) fn parse_select_expr<'a>(
43 parser: &mut Parser<'a, '_>,
44) -> Result<SelectExpr<'a>, ParseError> {
45 let expr = parse_expression_unreserved(parser, PRIORITY_MAX)?;
46 let reserved = parser.reserved();
47 let as_ = if parser.skip_keyword(Keyword::AS).is_some() {
48 Some(parser.consume_plain_identifier_unreserved()?)
49 } else {
50 let is_implicit_alias = match &parser.token {
51 Token::Ident(_, kw) => !kw.restricted(reserved),
52 Token::String(_, StringType::DoubleQuoted) => parser.options.dialect.is_postgresql(),
53 _ => false,
54 };
55 if is_implicit_alias {
56 Some(parser.consume_plain_identifier_unreserved()?)
57 } else {
58 None
59 }
60 };
61 Ok(SelectExpr { expr, as_ })
62}
63
64#[derive(Debug, Clone)]
66pub enum JoinSpecification<'a> {
67 On(Expression<'a>, Span),
69 Using(Vec<Identifier<'a>>, Span),
71}
72
73impl<'a> Spanned for JoinSpecification<'a> {
74 fn span(&self) -> Span {
75 match &self {
76 JoinSpecification::On(v, s) => s.join_span(v),
77 JoinSpecification::Using(v, s) => s.join_span(v),
78 }
79 }
80}
81
82#[derive(Debug, Clone)]
84pub enum JoinType {
85 Inner(Span),
86 Cross(Span),
87 Normal(Span),
88 Straight(Span),
89 Left(Span),
90 Right(Span),
91 FullOuter(Span),
92 Natural(Span),
93 NaturalInner(Span),
94 NaturalLeft(Span),
95 NaturalRight(Span),
96}
97impl Spanned for JoinType {
98 fn span(&self) -> Span {
99 match &self {
100 JoinType::Inner(v) => v.span(),
101 JoinType::Cross(v) => v.span(),
102 JoinType::Normal(v) => v.span(),
103 JoinType::Straight(v) => v.span(),
104 JoinType::Left(v) => v.span(),
105 JoinType::Right(v) => v.span(),
106 JoinType::FullOuter(v) => v.span(),
107 JoinType::Natural(v) => v.span(),
108 JoinType::NaturalInner(v) => v.span(),
109 JoinType::NaturalLeft(v) => v.span(),
110 JoinType::NaturalRight(v) => v.span(),
111 }
112 }
113}
114
115#[derive(Debug, Clone)]
116pub enum IndexHintUse {
117 Use(Span),
118 Ignore(Span),
119 Force(Span),
120}
121impl Spanned for IndexHintUse {
122 fn span(&self) -> Span {
123 match &self {
124 IndexHintUse::Use(v) => v.span(),
125 IndexHintUse::Ignore(v) => v.span(),
126 IndexHintUse::Force(v) => v.span(),
127 }
128 }
129}
130
131#[derive(Debug, Clone)]
132pub enum IndexHintType {
133 Index(Span),
134 Key(Span),
135}
136impl Spanned for IndexHintType {
137 fn span(&self) -> Span {
138 match &self {
139 IndexHintType::Index(v) => v.span(),
140 IndexHintType::Key(v) => v.span(),
141 }
142 }
143}
144
145#[derive(Debug, Clone)]
146pub enum IndexHintFor {
147 Join(Span),
148 OrderBy(Span),
149 GroupBy(Span),
150}
151impl Spanned for IndexHintFor {
152 fn span(&self) -> Span {
153 match &self {
154 IndexHintFor::Join(v) => v.span(),
155 IndexHintFor::OrderBy(v) => v.span(),
156 IndexHintFor::GroupBy(v) => v.span(),
157 }
158 }
159}
160
161#[derive(Debug, Clone)]
162pub struct IndexHint<'a> {
163 pub use_: IndexHintUse,
164 pub type_: IndexHintType,
165 pub for_: Option<(Span, IndexHintFor)>,
166 pub lparen: Span,
167 pub index_list: Vec<Identifier<'a>>,
168 pub rparen: Span,
169}
170
171impl<'a> Spanned for IndexHint<'a> {
172 fn span(&self) -> Span {
173 self.use_
174 .span()
175 .join_span(&self.type_)
176 .join_span(&self.for_)
177 .join_span(&self.lparen)
178 .join_span(&self.index_list)
179 .join_span(&self.rparen)
180 }
181}
182
183#[derive(Debug, Clone)]
185pub enum JsonTableOnErrorEmpty<'a> {
186 Default(Expression<'a>),
188 Error(Span),
190 Null(Span),
192}
193
194impl<'a> Spanned for JsonTableOnErrorEmpty<'a> {
195 fn span(&self) -> Span {
196 match self {
197 JsonTableOnErrorEmpty::Default(expr) => expr.span(),
198 JsonTableOnErrorEmpty::Error(s) => s.clone(),
199 JsonTableOnErrorEmpty::Null(s) => s.clone(),
200 }
201 }
202}
203
204#[derive(Debug, Clone)]
206pub enum JsonTableColumn<'a> {
207 Column {
209 name: Identifier<'a>,
210 data_type: DataType<'a>,
211 path_span: Span,
212 path: Expression<'a>,
213 on_empty: Option<(JsonTableOnErrorEmpty<'a>, Span)>,
215 on_error: Option<(JsonTableOnErrorEmpty<'a>, Span)>,
217 },
218 Ordinality {
220 name: Identifier<'a>,
221 for_ordinality_span: Span,
222 },
223 Nested {
225 nested_span: Span,
226 path_span: Span,
227 path: Expression<'a>,
228 columns_span: Span,
229 columns: Vec<JsonTableColumn<'a>>,
230 },
231}
232
233impl<'a> Spanned for JsonTableColumn<'a> {
234 fn span(&self) -> Span {
235 match self {
236 JsonTableColumn::Column {
237 name,
238 data_type,
239 path_span,
240 path,
241 on_empty,
242 on_error,
243 } => name
244 .span()
245 .join_span(data_type)
246 .join_span(path_span)
247 .join_span(path)
248 .join_span(on_empty)
249 .join_span(on_error),
250 JsonTableColumn::Ordinality {
251 name,
252 for_ordinality_span,
253 } => name.span().join_span(for_ordinality_span),
254 JsonTableColumn::Nested {
255 nested_span,
256 path_span,
257 path,
258 columns_span,
259 columns,
260 } => nested_span
261 .join_span(path_span)
262 .join_span(path)
263 .join_span(columns_span)
264 .join_span(columns),
265 }
266 }
267}
268
269#[derive(Debug, Clone)]
275pub enum TableFunctionName<'a> {
276 Unnest(Span),
278 GenerateSeries(Span),
280 StringToTable(Span),
282 Other(QualifiedName<'a>),
284}
285
286impl<'a> Spanned for TableFunctionName<'a> {
287 fn span(&self) -> Span {
288 match self {
289 TableFunctionName::Unnest(s)
290 | TableFunctionName::GenerateSeries(s)
291 | TableFunctionName::StringToTable(s) => s.clone(),
292 TableFunctionName::Other(n) => n.span(),
293 }
294 }
295}
296
297#[derive(Debug, Clone)]
299pub enum TableReference<'a> {
300 Table {
302 identifier: QualifiedName<'a>,
304 as_span: Option<Span>,
306 as_: Option<Identifier<'a>>,
308 index_hints: Vec<IndexHint<'a>>,
310 },
311 Query {
313 query: Box<Statement<'a>>,
315 as_span: Option<Span>,
317 as_: Option<Identifier<'a>>,
319 col_list: Vec<Identifier<'a>>,
321 },
322 JsonTable {
324 json_table_span: Span,
326 json_expr: Expression<'a>,
328 path: Expression<'a>,
330 columns_keyword_span: Span,
332 columns: Vec<JsonTableColumn<'a>>,
334 as_span: Option<Span>,
336 as_: Option<Identifier<'a>>,
338 },
339 Function {
341 name: TableFunctionName<'a>,
343 args: Vec<Expression<'a>>,
345 with_ordinality: Option<Span>,
347 as_span: Option<Span>,
349 as_: Option<Identifier<'a>>,
351 col_list: Vec<Identifier<'a>>,
353 },
354 Join {
356 join: JoinType,
358 left: Box<TableReference<'a>>,
360 right: Box<TableReference<'a>>,
362 specification: Option<JoinSpecification<'a>>,
364 },
365}
366
367impl<'a> Spanned for TableReference<'a> {
368 fn span(&self) -> Span {
369 match &self {
370 TableReference::Table {
371 identifier,
372 as_span,
373 as_,
374 index_hints,
375 } => identifier
376 .opt_join_span(as_span)
377 .opt_join_span(as_)
378 .opt_join_span(index_hints)
379 .expect("span of table"),
380 TableReference::Query {
381 query,
382 as_span,
383 as_,
384 col_list,
385 } => query.join_span(as_span).join_span(as_).join_span(col_list),
386 TableReference::JsonTable {
387 json_table_span,
388 json_expr,
389 path,
390 columns_keyword_span,
391 columns,
392 as_span,
393 as_,
394 } => json_table_span
395 .join_span(json_expr)
396 .join_span(path)
397 .join_span(columns_keyword_span)
398 .join_span(columns)
399 .join_span(as_span)
400 .join_span(as_),
401 TableReference::Function {
402 name,
403 args,
404 with_ordinality,
405 as_span,
406 as_,
407 col_list,
408 } => name
409 .span()
410 .join_span(args)
411 .join_span(with_ordinality)
412 .join_span(as_span)
413 .join_span(as_)
414 .join_span(col_list),
415 TableReference::Join {
416 join,
417 left,
418 right,
419 specification,
420 } => join
421 .join_span(left)
422 .join_span(right)
423 .join_span(specification),
424 }
425 }
426}
427
428pub(crate) fn parse_table_reference_inner<'a>(
429 parser: &mut Parser<'a, '_>,
430 additional_restrict: crate::keywords::Restrict,
431) -> Result<TableReference<'a>, ParseError> {
432 match &parser.token {
440 Token::Ident(_, Keyword::LATERAL) => {
441 let lateral_span = parser.consume_keyword(Keyword::LATERAL)?;
443 parser.postgres_only(&lateral_span);
444 let query = parse_compound_query(parser)?;
445 let as_span = parser.skip_keyword(Keyword::AS);
446 let as_ = if as_span.is_some()
447 || (matches!(&parser.token, Token::Ident(_, k) if !k.restricted(parser.reserved() | additional_restrict)))
448 {
449 Some(
450 parser.consume_plain_identifier_restrict(
451 parser.reserved() | additional_restrict,
452 )?,
453 )
454 } else {
455 None
456 };
457 Ok(TableReference::Query {
458 query: Box::new(query),
459 as_span: as_span
460 .map(|s| lateral_span.join_span(&s))
461 .or(Some(lateral_span)),
462 as_,
463 col_list: Vec::new(),
464 })
465 }
466 Token::Ident(_, Keyword::SELECT) | Token::LParen => {
467 let is_join_group = matches!(parser.token, Token::LParen)
471 && !matches!(
472 parser.peek(),
473 Token::Ident(_, Keyword::SELECT | Keyword::VALUES | Keyword::WITH)
474 | Token::LParen
475 );
476 if is_join_group {
477 parser.consume_token(Token::LParen)?;
478 let inner = parse_table_reference(parser, additional_restrict)?;
479 parser.consume_token(Token::RParen)?;
480 return Ok(inner);
481 }
482 let query = parse_compound_query(parser)?;
483 let as_span = parser.skip_keyword(Keyword::AS);
484 let as_ = if as_span.is_some()
485 || (matches!(&parser.token, Token::Ident(_, k) if !k.restricted(parser.reserved() | additional_restrict)))
486 {
487 Some(
488 parser.consume_plain_identifier_restrict(
489 parser.reserved() | additional_restrict,
490 )?,
491 )
492 } else {
493 None
494 };
495 let mut col_list = Vec::new();
497 if as_.is_some() && matches!(parser.token, Token::LParen) {
498 parser.consume_token(Token::LParen)?;
499 loop {
500 parser.recovered(
501 "')' or ','",
502 &|t| matches!(t, Token::RParen | Token::Comma),
503 |parser| {
504 col_list
505 .push(parser.consume_plain_identifier_restrict(Restrict::EMPTY)?);
506 Ok(())
507 },
508 )?;
509 if parser.skip_token(Token::Comma).is_none() {
510 break;
511 }
512 }
513 parser.consume_token(Token::RParen)?;
514 };
515 Ok(TableReference::Query {
516 query: Box::new(query),
517 as_span,
518 as_,
519 col_list,
520 })
521 }
522 Token::Ident(_, _) => parse_table_reference_named(parser, additional_restrict),
523 Token::String(_, StringType::DoubleQuoted) if parser.options.dialect.is_postgresql() => {
524 parse_table_reference_named(parser, additional_restrict)
525 }
526 _ => parser.expected_failure("subquery or identifier"),
527 }
528}
529
530fn parse_table_reference_named<'a>(
531 parser: &mut Parser<'a, '_>,
532 additional_restrict: Restrict,
533) -> Result<TableReference<'a>, ParseError> {
534 if matches!(parser.token, Token::Ident(_, Keyword::JSON_TABLE))
535 && matches!(parser.peek(), Token::LParen)
536 {
537 let json_table_span = parser.consume_keyword(Keyword::JSON_TABLE)?;
538
539 parser.consume_token(Token::LParen)?;
540
541 let json_expr = parse_expression_unreserved(parser, PRIORITY_MAX)?;
543
544 parser.consume_token(Token::Comma)?;
546
547 let path = match &parser.token {
549 Token::String(s, _) => {
550 let val = *s;
551 let span = parser.consume();
552 Expression::String(Box::new(SString::new(Cow::Borrowed(val), span)))
553 }
554 _ => {
555 parse_expression_unreserved(parser, PRIORITY_MAX)?
557 }
558 };
559
560 let columns_keyword_span = parser.consume_keyword(Keyword::COLUMNS)?;
562 parser.consume_token(Token::LParen)?;
563
564 let columns = parser.recovered(")", &|t| t == &Token::RParen, |parser| {
565 parse_json_table_columns(parser)
567 })?;
568
569 parser.consume_token(Token::RParen)?;
570
571 parser.consume_token(Token::RParen)?;
573
574 let as_span = parser.skip_keyword(Keyword::AS);
576 let as_ = if as_span.is_some()
577 || (matches!(&parser.token, Token::Ident(_, k) if !k.restricted(parser.reserved() | additional_restrict)))
578 {
579 Some(parser.consume_plain_identifier_unreserved()?)
580 } else {
581 None
582 };
583
584 return Ok(TableReference::JsonTable {
585 json_table_span,
586 json_expr,
587 path,
588 columns_keyword_span,
589 columns,
590 as_span,
591 as_,
592 });
593 }
594
595 let first_kw = match &parser.token {
599 Token::Ident(_, kw) => Some(*kw),
600 _ => None,
601 };
602 let identifier = parse_qualified_name_unreserved(parser)?;
603
604 if matches!(parser.token, Token::LParen) {
605 let func_name = if identifier.prefix.is_empty() {
607 match first_kw {
608 Some(Keyword::UNNEST) => TableFunctionName::Unnest(identifier.identifier.span),
609 Some(Keyword::GENERATE_SERIES) => {
610 TableFunctionName::GenerateSeries(identifier.identifier.span)
611 }
612 Some(Keyword::STRING_TO_TABLE) => {
613 TableFunctionName::StringToTable(identifier.identifier.span)
614 }
615 _ => TableFunctionName::Other(identifier),
616 }
617 } else {
618 TableFunctionName::Other(identifier)
619 };
620 parser.consume_token(Token::LParen)?;
621 let mut args = Vec::new();
622 if !matches!(parser.token, Token::RParen) {
623 loop {
624 parser.recovered(
625 "')' or ','",
626 &|t| matches!(t, Token::RParen | Token::Comma),
627 |parser| {
628 args.push(parse_expression_unreserved(parser, PRIORITY_MAX)?);
629 Ok(())
630 },
631 )?;
632 if parser.skip_token(Token::Comma).is_none() {
633 break;
634 }
635 }
636 }
637 parser.consume_token(Token::RParen)?;
638 let with_ordinality = if let Some(with_span) = parser.skip_keyword(Keyword::WITH) {
640 let ord_span = parser.consume_keyword(Keyword::ORDINALITY)?;
641 Some(with_span.join_span(&ord_span))
642 } else {
643 None
644 };
645 let as_span = parser.skip_keyword(Keyword::AS);
646 let as_ = if as_span.is_some()
647 || (matches!(&parser.token, Token::Ident(_, k) if !k.restricted(parser.reserved() | additional_restrict)))
648 {
649 Some(parser.consume_plain_identifier_unreserved()?)
650 } else {
651 None
652 };
653 let col_list = if as_.is_some() && matches!(parser.token, Token::LParen) {
655 parser.consume_token(Token::LParen)?;
656 let mut cols = Vec::new();
657 loop {
658 parser.recovered(
659 "')' or ','",
660 &|t| matches!(t, Token::RParen | Token::Comma),
661 |parser| {
662 cols.push(parser.consume_plain_identifier_unreserved()?);
663 Ok(())
664 },
665 )?;
666 if parser.skip_token(Token::Comma).is_none() {
667 break;
668 }
669 }
670 parser.consume_token(Token::RParen)?;
671 cols
672 } else {
673 Vec::new()
674 };
675 return Ok(TableReference::Function {
676 name: func_name,
677 args,
678 with_ordinality,
679 as_span,
680 as_,
681 col_list,
682 });
683 }
684
685 let as_span = parser.skip_keyword(Keyword::AS);
687 let as_ = if as_span.is_some()
688 || (matches!(&parser.token, Token::Ident(_, k) if !k.restricted(parser.reserved() | additional_restrict)))
689 {
690 Some(parser.consume_plain_identifier_restrict(parser.reserved() | additional_restrict)?)
691 } else {
692 None
693 };
694
695 let mut index_hints = Vec::new();
696 loop {
697 let use_ = match parser.token {
698 Token::Ident(_, Keyword::USE) => IndexHintUse::Use(parser.consume()),
699 Token::Ident(_, Keyword::IGNORE) => IndexHintUse::Ignore(parser.consume()),
700 Token::Ident(_, Keyword::FORCE) => IndexHintUse::Force(parser.consume()),
701 _ => break,
702 };
703 let type_ = match parser.token {
704 Token::Ident(_, Keyword::INDEX) => IndexHintType::Index(parser.consume()),
705 Token::Ident(_, Keyword::KEY) => IndexHintType::Key(parser.consume()),
706 _ => parser.expected_failure("'INDEX' or 'KEY'")?,
707 };
708 let for_ = if let Some(for_span) = parser.skip_keyword(Keyword::FOR) {
709 let v = match parser.token {
710 Token::Ident(_, Keyword::JOIN) => IndexHintFor::Join(parser.consume()),
711 Token::Ident(_, Keyword::GROUP) => {
712 IndexHintFor::GroupBy(parser.consume_keywords(&[Keyword::GROUP, Keyword::BY])?)
713 }
714 Token::Ident(_, Keyword::ORDER) => {
715 IndexHintFor::OrderBy(parser.consume_keywords(&[Keyword::ORDER, Keyword::BY])?)
716 }
717 _ => parser.expected_failure("'JOIN', 'GROUP BY' or 'ORDER BY'")?,
718 };
719 Some((for_span, v))
720 } else {
721 None
722 };
723 let lparen = parser.consume_token(Token::LParen)?;
724 let mut index_list = Vec::new();
725 loop {
726 parser.recovered(
727 "')' or ','",
728 &|t| matches!(t, Token::RParen | Token::Comma),
729 |parser| {
730 index_list.push(parser.consume_plain_identifier_unreserved()?);
731 Ok(())
732 },
733 )?;
734 if matches!(parser.token, Token::RParen) {
735 break;
736 }
737 parser.consume_token(Token::Comma)?;
738 }
739 let rparen = parser.consume_token(Token::RParen)?;
740 index_hints.push(IndexHint {
741 use_,
742 type_,
743 for_,
744 lparen,
745 index_list,
746 rparen,
747 })
748 }
749
750 if !index_hints.is_empty() && !parser.options.dialect.is_maria() {
751 parser.err(
752 "Index hints only supported by MariaDb",
753 &index_hints.opt_span().unwrap(),
754 );
755 }
756
757 Ok(TableReference::Table {
758 identifier,
759 as_span,
760 as_,
761 index_hints,
762 })
763}
764
765fn parse_json_table_columns<'a>(
766 parser: &mut Parser<'a, '_>,
767) -> Result<Vec<JsonTableColumn<'a>>, ParseError> {
768 let mut columns = Vec::new();
769
770 loop {
771 if let Some(nested_span) = parser.skip_keyword(Keyword::NESTED) {
773 let path_span = parser.consume_keyword(Keyword::PATH)?;
774 let path = match &parser.token {
775 Token::String(s, _) => {
776 let val = *s;
777 let span = parser.consume();
778 Expression::String(Box::new(SString::new(Cow::Borrowed(val), span)))
779 }
780 _ => parse_expression_unreserved(parser, PRIORITY_MAX)?,
781 };
782 let columns_span = parser.consume_keyword(Keyword::COLUMNS)?;
783 parser.consume_token(Token::LParen)?;
784 let nested_columns = parser.recovered(")", &|t| t == &Token::RParen, |parser| {
785 parse_json_table_columns(parser)
786 })?;
787 parser.consume_token(Token::RParen)?;
788
789 columns.push(JsonTableColumn::Nested {
790 nested_span,
791 path_span,
792 path,
793 columns_span,
794 columns: nested_columns,
795 });
796 } else {
797 let name = parser.consume_plain_identifier_unreserved()?;
799
800 if let Some(for_span) = parser.skip_keyword(Keyword::FOR) {
802 let ordinality_span = parser.consume_keyword(Keyword::ORDINALITY)?;
803 let for_ordinality_span = for_span.join_span(&ordinality_span);
804
805 columns.push(JsonTableColumn::Ordinality {
806 name,
807 for_ordinality_span,
808 });
809 } else {
810 let data_type = parse_data_type(parser, DataTypeContext::FunctionReturn)?;
812
813 let _ = parser.skip_keyword(Keyword::EXISTS);
815
816 let path_span = parser.consume_keyword(Keyword::PATH)?;
818 let path = match &parser.token {
819 Token::String(s, _) => {
820 let val = *s;
821 let span = parser.consume();
822 Expression::String(Box::new(SString::new(Cow::Borrowed(val), span)))
823 }
824 _ => parse_expression_unreserved(parser, PRIORITY_MAX)?,
825 };
826
827 let mut on_empty = None;
830 let mut on_error = None;
831
832 loop {
833 let behavior_start = parser.span.span().start;
834 let behavior = match &parser.token {
835 Token::Ident(_, Keyword::DEFAULT) => {
836 parser.consume();
837 let default_val = parse_expression_unreserved(parser, PRIORITY_MAX)?;
839 Some(JsonTableOnErrorEmpty::Default(default_val))
840 }
841 Token::Ident(_, Keyword::ERROR) => {
842 let error_span = parser.consume();
843 Some(JsonTableOnErrorEmpty::Error(error_span))
844 }
845 Token::Ident(_, Keyword::NULL) => {
846 let null_span = parser.consume();
847 Some(JsonTableOnErrorEmpty::Null(null_span))
848 }
849 _ => None,
850 };
851
852 if let Some(behavior) = behavior {
853 parser.consume_keyword(Keyword::ON)?;
854 let clause_end = parser.span.span().end;
855 match &parser.token {
856 Token::Ident(_, Keyword::EMPTY) => {
857 parser.consume();
858 let span = behavior_start..clause_end;
859 on_empty = Some((behavior, span));
860 }
861 Token::Ident(_, Keyword::ERROR) => {
862 parser.consume();
863 let span = behavior_start..clause_end;
864 on_error = Some((behavior, span));
865 }
866 _ => {
867 parser.expected_failure("EMPTY or ERROR")?;
869 }
870 }
871 } else {
872 break;
874 }
875 }
876
877 columns.push(JsonTableColumn::Column {
878 name,
879 data_type,
880 path_span,
881 path,
882 on_empty,
883 on_error,
884 });
885 }
886 }
887
888 if parser.skip_token(Token::Comma).is_none() {
890 break;
891 }
892
893 if matches!(parser.token, Token::RParen) {
895 break;
896 }
897 }
898
899 Ok(columns)
900}
901
902pub(crate) fn parse_table_reference<'a>(
903 parser: &mut Parser<'a, '_>,
904 additional_restrict: crate::keywords::Restrict,
905) -> Result<TableReference<'a>, ParseError> {
906 let mut ans = parse_table_reference_inner(parser, additional_restrict)?;
907 loop {
908 let join = match parser.token {
909 Token::Ident(_, Keyword::FULL) => {
910 let full = parser.consume_keyword(Keyword::FULL)?;
911 parser.postgres_only(&full);
912 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
913 JoinType::FullOuter(
914 full.join_span(&outer)
915 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
916 )
917 } else {
918 JoinType::FullOuter(full.join_span(&parser.consume_keyword(Keyword::JOIN)?))
919 }
920 }
921 Token::Ident(_, Keyword::INNER) => JoinType::Inner(
922 parser
923 .consume_keyword(Keyword::INNER)?
924 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
925 ),
926 Token::Ident(_, Keyword::CROSS) => JoinType::Cross(
927 parser
928 .consume_keyword(Keyword::CROSS)?
929 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
930 ),
931 Token::Ident(_, Keyword::JOIN) => {
932 JoinType::Normal(parser.consume_keyword(Keyword::JOIN)?)
933 }
934 Token::Ident(_, Keyword::STRAIGHT_JOIN) => {
935 JoinType::Straight(parser.consume_keyword(Keyword::STRAIGHT_JOIN)?)
936 }
937 Token::Ident(_, Keyword::LEFT) => {
938 let left = parser.consume_keyword(Keyword::LEFT)?;
939 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
940 JoinType::Left(
941 left.join_span(&outer)
942 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
943 )
944 } else {
945 JoinType::Left(left.join_span(&parser.consume_keyword(Keyword::JOIN)?))
946 }
947 }
948 Token::Ident(_, Keyword::RIGHT) => {
949 let right = parser.consume_keyword(Keyword::RIGHT)?;
950 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
951 JoinType::Right(
952 right
953 .join_span(&outer)
954 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
955 )
956 } else {
957 JoinType::Right(right.join_span(&parser.consume_keyword(Keyword::JOIN)?))
958 }
959 }
960 Token::Ident(_, Keyword::NATURAL) => {
961 let natural = parser.consume_keyword(Keyword::NATURAL)?;
962 match &parser.token {
963 Token::Ident(_, Keyword::INNER) => JoinType::NaturalInner(
964 natural
965 .join_span(&parser.consume_keywords(&[Keyword::INNER, Keyword::JOIN])?),
966 ),
967 Token::Ident(_, Keyword::LEFT) => {
968 let left = parser.consume_keyword(Keyword::LEFT)?;
969 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
970 JoinType::NaturalLeft(
971 left.join_span(&outer)
972 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
973 )
974 } else {
975 JoinType::NaturalLeft(
976 left.join_span(&parser.consume_keyword(Keyword::JOIN)?),
977 )
978 }
979 }
980 Token::Ident(_, Keyword::RIGHT) => {
981 let right = parser.consume_keyword(Keyword::RIGHT)?;
982 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
983 JoinType::NaturalRight(
984 right
985 .join_span(&outer)
986 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
987 )
988 } else {
989 JoinType::NaturalRight(
990 right.join_span(&parser.consume_keyword(Keyword::JOIN)?),
991 )
992 }
993 }
994 Token::Ident(_, Keyword::JOIN) => JoinType::Natural(
995 natural.join_span(&parser.consume_keyword(Keyword::JOIN)?),
996 ),
997 _ => parser.expected_failure("'INNER', 'LEFT', 'RIGHT' or 'JOIN'")?,
998 }
999 }
1000 _ => break,
1001 };
1002
1003 let right = parse_table_reference_inner(parser, additional_restrict)?;
1004
1005 let specification = match &parser.token {
1006 Token::Ident(_, Keyword::ON) => {
1007 let on = parser.consume_keyword(Keyword::ON)?;
1008 let expr = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1009 Some(JoinSpecification::On(expr, on))
1010 }
1011 Token::Ident(_, Keyword::USING) => {
1012 let using = parser.consume_keyword(Keyword::USING)?;
1013 let mut join_column_list = Vec::new();
1014 loop {
1015 join_column_list.push(parser.consume_plain_identifier_unreserved()?);
1016 if parser.skip_token(Token::Comma).is_none() {
1017 break;
1018 }
1019 }
1020 Some(JoinSpecification::Using(join_column_list, using))
1021 }
1022 _ => None,
1023 };
1024
1025 ans = TableReference::Join {
1026 join,
1027 left: Box::new(ans),
1028 right: Box::new(right),
1029 specification,
1030 };
1031 }
1032 Ok(ans)
1033}
1034
1035#[derive(Debug, Clone)]
1037pub enum SelectFlag {
1038 All(Span),
1039 Distinct(Span),
1040 DistinctOn(Span),
1041 DistinctRow(Span),
1042 HighPriority(Span),
1043 StraightJoin(Span),
1044 SqlSmallResult(Span),
1045 SqlBigResult(Span),
1046 SqlBufferResult(Span),
1047 SqlNoCache(Span),
1048 SqlCalcFoundRows(Span),
1049}
1050
1051impl Spanned for SelectFlag {
1052 fn span(&self) -> Span {
1053 match &self {
1054 SelectFlag::All(v) => v.span(),
1055 SelectFlag::Distinct(v) => v.span(),
1056 SelectFlag::DistinctOn(v) => v.span(),
1057 SelectFlag::DistinctRow(v) => v.span(),
1058 SelectFlag::HighPriority(v) => v.span(),
1059 SelectFlag::StraightJoin(v) => v.span(),
1060 SelectFlag::SqlSmallResult(v) => v.span(),
1061 SelectFlag::SqlBigResult(v) => v.span(),
1062 SelectFlag::SqlBufferResult(v) => v.span(),
1063 SelectFlag::SqlNoCache(v) => v.span(),
1064 SelectFlag::SqlCalcFoundRows(v) => v.span(),
1065 }
1066 }
1067}
1068
1069#[derive(Debug, Clone)]
1071pub enum OrderFlag {
1072 Asc(Span),
1073 Desc(Span),
1074 AscNullsFirst(Span),
1075 AscNullsLast(Span),
1076 DescNullsFirst(Span),
1077 DescNullsLast(Span),
1078 NullsFirst(Span),
1079 NullsLast(Span),
1080 None,
1081}
1082impl OptSpanned for OrderFlag {
1083 fn opt_span(&self) -> Option<Span> {
1084 match &self {
1085 OrderFlag::Asc(v) => v.opt_span(),
1086 OrderFlag::Desc(v) => v.opt_span(),
1087 OrderFlag::AscNullsFirst(v) => v.opt_span(),
1088 OrderFlag::AscNullsLast(v) => v.opt_span(),
1089 OrderFlag::DescNullsFirst(v) => v.opt_span(),
1090 OrderFlag::DescNullsLast(v) => v.opt_span(),
1091 OrderFlag::NullsFirst(v) => v.opt_span(),
1092 OrderFlag::NullsLast(v) => v.opt_span(),
1093 OrderFlag::None => None,
1094 }
1095 }
1096}
1097
1098#[derive(Debug, Clone)]
1100pub enum LockStrength {
1101 Update(Span),
1102 Share(Span),
1103 NoKeyUpdate(Span),
1104 KeyShare(Span),
1105}
1106impl Spanned for LockStrength {
1107 fn span(&self) -> Span {
1108 match &self {
1109 LockStrength::Update(v) => v.span(),
1110 LockStrength::Share(v) => v.span(),
1111 LockStrength::NoKeyUpdate(v) => v.span(),
1112 LockStrength::KeyShare(v) => v.span(),
1113 }
1114 }
1115}
1116
1117#[derive(Debug, Clone)]
1118pub enum LockWait {
1119 NoWait(Span),
1120 SkipLocket(Span),
1121 Default,
1122}
1123impl OptSpanned for LockWait {
1124 fn opt_span(&self) -> Option<Span> {
1125 match &self {
1126 LockWait::NoWait(v) => v.opt_span(),
1127 LockWait::SkipLocket(v) => v.opt_span(),
1128 LockWait::Default => None,
1129 }
1130 }
1131}
1132
1133#[derive(Debug, Clone)]
1134pub struct Locking<'a> {
1135 pub for_span: Span,
1137 pub strength: LockStrength,
1138 pub of: Option<(Span, Vec<Identifier<'a>>)>,
1139 pub wait: LockWait,
1140}
1141impl<'a> Spanned for Locking<'a> {
1142 fn span(&self) -> Span {
1143 self.for_span
1144 .join_span(&self.strength)
1145 .join_span(&self.of)
1146 .join_span(&self.wait)
1147 }
1148}
1149
1150#[derive(Debug, Clone)]
1192pub struct Select<'a> {
1193 pub select_span: Span,
1195 pub flags: Vec<SelectFlag>,
1197 pub select_exprs: Vec<SelectExpr<'a>>,
1199 pub from_span: Option<Span>,
1201 pub table_references: Option<Vec<TableReference<'a>>>,
1203 pub where_: Option<(Expression<'a>, Span)>,
1205 pub group_by: Option<(Span, Vec<Expression<'a>>)>,
1207 pub having: Option<(Expression<'a>, Span)>,
1209 pub window_span: Option<Span>,
1211 pub order_by: Option<(Span, Vec<(Expression<'a>, OrderFlag)>)>,
1213 pub limit: Option<(Span, Option<Expression<'a>>, Expression<'a>)>,
1215 pub distinct_on: Option<(Span, Vec<Expression<'a>>)>,
1217 pub offset: Option<(Span, Expression<'a>)>,
1219 pub fetch: Option<(Span, Expression<'a>)>,
1221 pub locking: Option<Locking<'a>>,
1223}
1224
1225impl<'a> Spanned for Select<'a> {
1226 fn span(&self) -> Span {
1227 self.select_span
1228 .join_span(&self.flags)
1229 .join_span(&self.select_exprs)
1230 .join_span(&self.from_span)
1231 .join_span(&self.table_references)
1232 .join_span(&self.where_)
1233 .join_span(&self.group_by)
1234 .join_span(&self.having)
1235 .join_span(&self.window_span)
1236 .join_span(&self.order_by)
1237 .join_span(&self.limit)
1238 .join_span(&self.distinct_on)
1239 .join_span(&self.offset)
1240 .join_span(&self.fetch)
1241 }
1242}
1243
1244pub(crate) fn parse_select<'a>(parser: &mut Parser<'a, '_>) -> Result<Select<'a>, ParseError> {
1245 let select_span = parser.consume_keyword(Keyword::SELECT)?;
1246 let mut flags = Vec::new();
1247 let mut select_exprs = Vec::new();
1248
1249 loop {
1250 match &parser.token {
1251 Token::Ident(_, Keyword::ALL) => {
1252 flags.push(SelectFlag::All(parser.consume_keyword(Keyword::ALL)?))
1253 }
1254 Token::Ident(_, Keyword::DISTINCT) => {
1255 let distinct_span = parser.consume_keyword(Keyword::DISTINCT)?;
1256 if matches!(parser.token, Token::Ident(_, Keyword::ON)) {
1258 flags.push(SelectFlag::DistinctOn(distinct_span));
1259 } else {
1260 flags.push(SelectFlag::Distinct(distinct_span));
1261 }
1262 }
1263 Token::Ident(_, Keyword::DISTINCTROW) => flags.push(SelectFlag::DistinctRow(
1264 parser.consume_keyword(Keyword::DISTINCTROW)?,
1265 )),
1266 Token::Ident(_, Keyword::HIGH_PRIORITY) => flags.push(SelectFlag::HighPriority(
1267 parser.consume_keyword(Keyword::HIGH_PRIORITY)?,
1268 )),
1269 Token::Ident(_, Keyword::STRAIGHT_JOIN) => flags.push(SelectFlag::StraightJoin(
1270 parser.consume_keyword(Keyword::STRAIGHT_JOIN)?,
1271 )),
1272 Token::Ident(_, Keyword::SQL_SMALL_RESULT) => flags.push(SelectFlag::SqlSmallResult(
1273 parser.consume_keyword(Keyword::SQL_SMALL_RESULT)?,
1274 )),
1275 Token::Ident(_, Keyword::SQL_BIG_RESULT) => flags.push(SelectFlag::SqlBigResult(
1276 parser.consume_keyword(Keyword::SQL_BIG_RESULT)?,
1277 )),
1278 Token::Ident(_, Keyword::SQL_BUFFER_RESULT) => flags.push(SelectFlag::SqlBufferResult(
1279 parser.consume_keyword(Keyword::SQL_BUFFER_RESULT)?,
1280 )),
1281 Token::Ident(_, Keyword::SQL_NO_CACHE) => flags.push(SelectFlag::SqlNoCache(
1282 parser.consume_keyword(Keyword::SQL_NO_CACHE)?,
1283 )),
1284 Token::Ident(_, Keyword::SQL_CALC_FOUND_ROWS) => flags.push(
1285 SelectFlag::SqlCalcFoundRows(parser.consume_keyword(Keyword::SQL_CALC_FOUND_ROWS)?),
1286 ),
1287 _ => break,
1288 }
1289 }
1290
1291 let distinct_on = if flags
1293 .last()
1294 .is_some_and(|f| matches!(f, SelectFlag::DistinctOn(_)))
1295 {
1296 let on_span = parser.consume_keyword(Keyword::ON)?;
1297 parser.postgres_only(&on_span);
1298 parser.consume_token(Token::LParen)?;
1299 let mut exprs = Vec::new();
1300 loop {
1301 parser.recovered(
1302 "')' or ','",
1303 &|t| matches!(t, Token::RParen | Token::Comma),
1304 |parser| {
1305 exprs.push(parse_expression_unreserved(parser, PRIORITY_MAX)?);
1306 Ok(())
1307 },
1308 )?;
1309 if parser.skip_token(Token::Comma).is_none() {
1310 break;
1311 }
1312 }
1313 parser.consume_token(Token::RParen)?;
1314 Some((on_span, exprs))
1315 } else {
1316 None
1317 };
1318
1319 loop {
1320 select_exprs.push(parse_select_expr(parser)?);
1321 if parser.skip_token(Token::Comma).is_none() {
1322 break;
1323 }
1324 }
1325
1326 let from_span = parser.skip_keyword(Keyword::FROM);
1329
1330 let table_references = if from_span.is_some() {
1331 let mut table_references = Vec::new();
1332 loop {
1333 table_references.push(parse_table_reference(parser, Restrict::EMPTY)?);
1334 if parser.skip_token(Token::Comma).is_none() {
1335 break;
1336 }
1337 }
1338 Some(table_references)
1339 } else {
1340 None
1341 };
1342
1343 let where_ = if let Some(span) = parser.skip_keyword(Keyword::WHERE) {
1345 Some((parse_expression_unreserved(parser, PRIORITY_MAX)?, span))
1346 } else {
1347 None
1348 };
1349
1350 let group_by = if let Some(group_span) = parser.skip_keyword(Keyword::GROUP) {
1351 let span = parser.consume_keyword(Keyword::BY)?.join_span(&group_span);
1352 let mut groups = Vec::new();
1353 loop {
1354 groups.push(parse_expression_unreserved(parser, PRIORITY_MAX)?);
1355 if parser.skip_token(Token::Comma).is_none() {
1356 break;
1357 }
1358 }
1359 Some((span, groups))
1361 } else {
1362 None
1363 };
1364
1365 let having = if let Some(span) = parser.skip_keyword(Keyword::HAVING) {
1366 Some((parse_expression_unreserved(parser, PRIORITY_MAX)?, span))
1367 } else {
1368 None
1369 };
1370
1371 let window_span = parser.skip_keyword(Keyword::WINDOW);
1372 if window_span.is_some() {
1373 }
1375
1376 let order_by = if let Some(span) = parser.skip_keyword(Keyword::ORDER) {
1377 let span = parser.consume_keyword(Keyword::BY)?.join_span(&span);
1378 let mut order = Vec::new();
1379 loop {
1380 let e = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1381 let dir_span_opt = match &parser.token {
1382 Token::Ident(_, Keyword::ASC) => Some((true, parser.consume())),
1383 Token::Ident(_, Keyword::DESC) => Some((false, parser.consume())),
1384 _ => None,
1385 };
1386 let f = if let Some(nulls_span) = parser.skip_keyword(Keyword::NULLS) {
1387 match &parser.token {
1388 Token::Ident(_, Keyword::FIRST) => {
1389 let s = parser.consume().join_span(&nulls_span);
1390 parser.postgres_only(&s);
1391 match dir_span_opt {
1392 Some((true, _)) => OrderFlag::AscNullsFirst(s),
1393 Some((false, _)) => OrderFlag::DescNullsFirst(s),
1394 None => OrderFlag::NullsFirst(s),
1395 }
1396 }
1397 Token::Ident(_, Keyword::LAST) => {
1398 let s = parser.consume().join_span(&nulls_span);
1399 parser.postgres_only(&s);
1400 match dir_span_opt {
1401 Some((true, _)) => OrderFlag::AscNullsLast(s),
1402 Some((false, _)) => OrderFlag::DescNullsLast(s),
1403 None => OrderFlag::NullsLast(s),
1404 }
1405 }
1406 _ => parser.expected_failure("FIRST or LAST")?,
1407 }
1408 } else {
1409 match dir_span_opt {
1410 Some((true, s)) => OrderFlag::Asc(s),
1411 Some((false, s)) => OrderFlag::Desc(s),
1412 None => OrderFlag::None,
1413 }
1414 };
1415 order.push((e, f));
1416 if parser.skip_token(Token::Comma).is_none() {
1417 break;
1418 }
1419 }
1420 Some((span, order))
1421 } else {
1422 None
1423 };
1424
1425 let limit = if let Some(span) = parser.skip_keyword(Keyword::LIMIT) {
1426 let n = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1427 match parser.token {
1428 Token::Comma => {
1429 parser.consume();
1430 Some((
1431 span,
1432 Some(n),
1433 parse_expression_unreserved(parser, PRIORITY_MAX)?,
1434 ))
1435 }
1436 Token::Ident(_, Keyword::OFFSET) => {
1437 parser.consume();
1438 Some((
1439 span,
1440 Some(parse_expression_unreserved(parser, PRIORITY_MAX)?),
1441 n,
1442 ))
1443 }
1444 _ => Some((span, None, n)),
1445 }
1446 } else {
1447 None
1448 };
1449
1450 let offset = if limit.is_none() {
1452 if let Some(offset_span) = parser.skip_keyword(Keyword::OFFSET) {
1453 parser.postgres_only(&offset_span);
1454 let n = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1455 if matches!(parser.token, Token::Ident(_, Keyword::ROWS | Keyword::ROW)) {
1457 parser.consume();
1458 }
1459 Some((offset_span, n))
1460 } else {
1461 None
1462 }
1463 } else {
1464 None
1465 };
1466
1467 let fetch = if let Some(fetch_span) = parser.skip_keyword(Keyword::FETCH) {
1469 parser.postgres_only(&fetch_span);
1470 match &parser.token {
1471 Token::Ident(_, Keyword::FIRST | Keyword::NEXT) => {
1472 parser.consume();
1473 }
1474 _ => parser.expected_failure("FIRST or NEXT")?,
1475 }
1476 let n = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1477 if matches!(parser.token, Token::Ident(_, Keyword::ROWS | Keyword::ROW)) {
1478 parser.consume();
1479 }
1480 parser.consume_keyword(Keyword::ONLY)?;
1481 Some((fetch_span, n))
1482 } else {
1483 None
1484 };
1485
1486 let locking = if let Some(for_span) = parser.skip_keyword(Keyword::FOR) {
1487 let strength = match &parser.token {
1488 Token::Ident(_, Keyword::UPDATE) => {
1489 LockStrength::Update(parser.consume_keyword(Keyword::UPDATE)?)
1490 }
1491 Token::Ident(_, Keyword::SHARE) => {
1492 LockStrength::Share(parser.consume_keyword(Keyword::SHARE)?)
1493 }
1494 Token::Ident(_, Keyword::NO) => {
1495 LockStrength::NoKeyUpdate(parser.consume_keywords(&[
1496 Keyword::NO,
1497 Keyword::KEY,
1498 Keyword::UPDATE,
1499 ])?)
1500 }
1501 Token::Ident(_, Keyword::KEY) => {
1502 LockStrength::KeyShare(parser.consume_keywords(&[Keyword::KEY, Keyword::SHARE])?)
1503 }
1504 _ => parser.expected_failure("UPDATE, SHARE, NO KEY UPDATE or KEY SHARE here")?,
1505 };
1506
1507 if let LockStrength::NoKeyUpdate(s) | LockStrength::KeyShare(s) = &strength
1508 && !parser.options.dialect.is_postgresql()
1509 {
1510 parser.err("Only support by PostgreSQL", s);
1511 }
1512
1513 let of = if let Some(of_span) = parser.skip_keyword(Keyword::OF) {
1514 let mut table_references = Vec::new();
1515 loop {
1516 table_references.push(parser.consume_plain_identifier_unreserved()?);
1517 if parser.skip_token(Token::Comma).is_none() {
1518 break;
1519 }
1520 }
1521 Some((of_span, table_references))
1522 } else {
1523 None
1524 };
1525
1526 let wait = match &parser.token {
1527 Token::Ident(_, Keyword::NOWAIT) => {
1528 LockWait::NoWait(parser.consume_keyword(Keyword::NOWAIT)?)
1529 }
1530 Token::Ident(_, Keyword::SKIP) => {
1531 LockWait::SkipLocket(parser.consume_keywords(&[Keyword::SKIP, Keyword::LOCKED])?)
1532 }
1533 _ => LockWait::Default,
1534 };
1535 Some(Locking {
1536 for_span,
1537 strength,
1538 of,
1539 wait,
1540 })
1541 } else {
1542 None
1543 };
1544
1545 Ok(Select {
1557 select_span,
1558 flags,
1559 select_exprs,
1560 from_span,
1561 table_references,
1562 where_,
1563 group_by,
1564 having,
1565 window_span,
1566 order_by,
1567 limit,
1568 distinct_on,
1569 offset,
1570 fetch,
1571 locking,
1572 })
1573}