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 outer_paren = if matches!(parser.token, Token::LParen) {
473 Some(parser.consume_token(Token::LParen)?)
474 } else {
475 None
476 };
477
478 let is_join_group = outer_paren.is_some()
482 && !matches!(
483 parser.token,
484 Token::Ident(_, Keyword::SELECT | Keyword::VALUES | Keyword::WITH)
485 )
486 && !(matches!(parser.token, Token::LParen)
487 && matches!(
488 parser.peek(),
489 Token::Ident(_, Keyword::SELECT | Keyword::VALUES | Keyword::WITH)
490 ));
491
492 if is_join_group {
493 let inner = parse_table_reference(parser, additional_restrict)?;
494 parser.consume_token(Token::RParen)?;
495 return Ok(inner);
496 }
497
498 let query = parse_compound_query(parser)?;
504
505 if outer_paren.is_some() {
506 parser.consume_token(Token::RParen)?;
507 }
508
509 let as_span = parser.skip_keyword(Keyword::AS);
510 let as_ = if as_span.is_some()
511 || (matches!(&parser.token, Token::Ident(_, k) if !k.restricted(parser.reserved() | additional_restrict)))
512 {
513 Some(
514 parser.consume_plain_identifier_restrict(
515 parser.reserved() | additional_restrict,
516 )?,
517 )
518 } else {
519 None
520 };
521 let mut col_list = Vec::new();
523 if as_.is_some() && matches!(parser.token, Token::LParen) {
524 parser.consume_token(Token::LParen)?;
525 loop {
526 parser.recovered(
527 "')' or ','",
528 &|t| matches!(t, Token::RParen | Token::Comma),
529 |parser| {
530 col_list
531 .push(parser.consume_plain_identifier_restrict(Restrict::EMPTY)?);
532 Ok(())
533 },
534 )?;
535 if parser.skip_token(Token::Comma).is_none() {
536 break;
537 }
538 }
539 parser.consume_token(Token::RParen)?;
540 };
541 Ok(TableReference::Query {
542 query: Box::new(query),
543 as_span,
544 as_,
545 col_list,
546 })
547 }
548 Token::Ident(_, _) => parse_table_reference_named(parser, additional_restrict),
549 Token::String(_, StringType::DoubleQuoted) if parser.options.dialect.is_postgresql() => {
550 parse_table_reference_named(parser, additional_restrict)
551 }
552 _ => parser.expected_failure("subquery or identifier"),
553 }
554}
555
556fn parse_table_reference_named<'a>(
557 parser: &mut Parser<'a, '_>,
558 additional_restrict: Restrict,
559) -> Result<TableReference<'a>, ParseError> {
560 if matches!(parser.token, Token::Ident(_, Keyword::JSON_TABLE))
561 && matches!(parser.peek(), Token::LParen)
562 {
563 let json_table_span = parser.consume_keyword(Keyword::JSON_TABLE)?;
564
565 parser.consume_token(Token::LParen)?;
566
567 let json_expr = parse_expression_unreserved(parser, PRIORITY_MAX)?;
569
570 parser.consume_token(Token::Comma)?;
572
573 let path = match &parser.token {
575 Token::String(s, _) => {
576 let val = *s;
577 let span = parser.consume();
578 Expression::String(Box::new(SString::new(Cow::Borrowed(val), span)))
579 }
580 _ => {
581 parse_expression_unreserved(parser, PRIORITY_MAX)?
583 }
584 };
585
586 let columns_keyword_span = parser.consume_keyword(Keyword::COLUMNS)?;
588 parser.consume_token(Token::LParen)?;
589
590 let columns = parser.recovered(")", &|t| t == &Token::RParen, |parser| {
591 parse_json_table_columns(parser)
593 })?;
594
595 parser.consume_token(Token::RParen)?;
596
597 parser.consume_token(Token::RParen)?;
599
600 let as_span = parser.skip_keyword(Keyword::AS);
602 let as_ = if as_span.is_some()
603 || (matches!(&parser.token, Token::Ident(_, k) if !k.restricted(parser.reserved() | additional_restrict)))
604 {
605 Some(parser.consume_plain_identifier_unreserved()?)
606 } else {
607 None
608 };
609
610 return Ok(TableReference::JsonTable {
611 json_table_span,
612 json_expr,
613 path,
614 columns_keyword_span,
615 columns,
616 as_span,
617 as_,
618 });
619 }
620
621 let first_kw = match &parser.token {
625 Token::Ident(_, kw) => Some(*kw),
626 _ => None,
627 };
628 let identifier = parse_qualified_name_unreserved(parser)?;
629
630 if matches!(parser.token, Token::LParen) {
631 let func_name = if identifier.prefix.is_empty() {
633 match first_kw {
634 Some(Keyword::UNNEST) => TableFunctionName::Unnest(identifier.identifier.span),
635 Some(Keyword::GENERATE_SERIES) => {
636 TableFunctionName::GenerateSeries(identifier.identifier.span)
637 }
638 Some(Keyword::STRING_TO_TABLE) => {
639 TableFunctionName::StringToTable(identifier.identifier.span)
640 }
641 _ => TableFunctionName::Other(identifier),
642 }
643 } else {
644 TableFunctionName::Other(identifier)
645 };
646 parser.consume_token(Token::LParen)?;
647 let mut args = Vec::new();
648 if !matches!(parser.token, Token::RParen) {
649 loop {
650 parser.recovered(
651 "')' or ','",
652 &|t| matches!(t, Token::RParen | Token::Comma),
653 |parser| {
654 args.push(parse_expression_unreserved(parser, PRIORITY_MAX)?);
655 Ok(())
656 },
657 )?;
658 if parser.skip_token(Token::Comma).is_none() {
659 break;
660 }
661 }
662 }
663 parser.consume_token(Token::RParen)?;
664 let with_ordinality = if let Some(with_span) = parser.skip_keyword(Keyword::WITH) {
666 let ord_span = parser.consume_keyword(Keyword::ORDINALITY)?;
667 Some(with_span.join_span(&ord_span))
668 } else {
669 None
670 };
671 let as_span = parser.skip_keyword(Keyword::AS);
672 let as_ = if as_span.is_some()
673 || (matches!(&parser.token, Token::Ident(_, k) if !k.restricted(parser.reserved() | additional_restrict)))
674 {
675 Some(parser.consume_plain_identifier_unreserved()?)
676 } else {
677 None
678 };
679 let col_list = if as_.is_some() && matches!(parser.token, Token::LParen) {
681 parser.consume_token(Token::LParen)?;
682 let mut cols = Vec::new();
683 loop {
684 parser.recovered(
685 "')' or ','",
686 &|t| matches!(t, Token::RParen | Token::Comma),
687 |parser| {
688 cols.push(parser.consume_plain_identifier_unreserved()?);
689 Ok(())
690 },
691 )?;
692 if parser.skip_token(Token::Comma).is_none() {
693 break;
694 }
695 }
696 parser.consume_token(Token::RParen)?;
697 cols
698 } else {
699 Vec::new()
700 };
701 return Ok(TableReference::Function {
702 name: func_name,
703 args,
704 with_ordinality,
705 as_span,
706 as_,
707 col_list,
708 });
709 }
710
711 let as_span = parser.skip_keyword(Keyword::AS);
713 let as_ = if as_span.is_some()
714 || (matches!(&parser.token, Token::Ident(_, k) if !k.restricted(parser.reserved() | additional_restrict)))
715 {
716 Some(parser.consume_plain_identifier_restrict(parser.reserved() | additional_restrict)?)
717 } else {
718 None
719 };
720
721 let mut index_hints = Vec::new();
722 loop {
723 let use_ = match parser.token {
724 Token::Ident(_, Keyword::USE) => IndexHintUse::Use(parser.consume()),
725 Token::Ident(_, Keyword::IGNORE) => IndexHintUse::Ignore(parser.consume()),
726 Token::Ident(_, Keyword::FORCE) => IndexHintUse::Force(parser.consume()),
727 _ => break,
728 };
729 let type_ = match parser.token {
730 Token::Ident(_, Keyword::INDEX) => IndexHintType::Index(parser.consume()),
731 Token::Ident(_, Keyword::KEY) => IndexHintType::Key(parser.consume()),
732 _ => parser.expected_failure("'INDEX' or 'KEY'")?,
733 };
734 let for_ = if let Some(for_span) = parser.skip_keyword(Keyword::FOR) {
735 let v = match parser.token {
736 Token::Ident(_, Keyword::JOIN) => IndexHintFor::Join(parser.consume()),
737 Token::Ident(_, Keyword::GROUP) => {
738 IndexHintFor::GroupBy(parser.consume_keywords(&[Keyword::GROUP, Keyword::BY])?)
739 }
740 Token::Ident(_, Keyword::ORDER) => {
741 IndexHintFor::OrderBy(parser.consume_keywords(&[Keyword::ORDER, Keyword::BY])?)
742 }
743 _ => parser.expected_failure("'JOIN', 'GROUP BY' or 'ORDER BY'")?,
744 };
745 Some((for_span, v))
746 } else {
747 None
748 };
749 let lparen = parser.consume_token(Token::LParen)?;
750 let mut index_list = Vec::new();
751 loop {
752 parser.recovered(
753 "')' or ','",
754 &|t| matches!(t, Token::RParen | Token::Comma),
755 |parser| {
756 index_list.push(parser.consume_plain_identifier_unreserved()?);
757 Ok(())
758 },
759 )?;
760 if matches!(parser.token, Token::RParen) {
761 break;
762 }
763 parser.consume_token(Token::Comma)?;
764 }
765 let rparen = parser.consume_token(Token::RParen)?;
766 index_hints.push(IndexHint {
767 use_,
768 type_,
769 for_,
770 lparen,
771 index_list,
772 rparen,
773 })
774 }
775
776 if !index_hints.is_empty() && !parser.options.dialect.is_maria() {
777 parser.err(
778 "Index hints only supported by MariaDb",
779 &index_hints.opt_span().unwrap(),
780 );
781 }
782
783 Ok(TableReference::Table {
784 identifier,
785 as_span,
786 as_,
787 index_hints,
788 })
789}
790
791fn parse_json_table_columns<'a>(
792 parser: &mut Parser<'a, '_>,
793) -> Result<Vec<JsonTableColumn<'a>>, ParseError> {
794 let mut columns = Vec::new();
795
796 loop {
797 if let Some(nested_span) = parser.skip_keyword(Keyword::NESTED) {
799 let path_span = parser.consume_keyword(Keyword::PATH)?;
800 let path = match &parser.token {
801 Token::String(s, _) => {
802 let val = *s;
803 let span = parser.consume();
804 Expression::String(Box::new(SString::new(Cow::Borrowed(val), span)))
805 }
806 _ => parse_expression_unreserved(parser, PRIORITY_MAX)?,
807 };
808 let columns_span = parser.consume_keyword(Keyword::COLUMNS)?;
809 parser.consume_token(Token::LParen)?;
810 let nested_columns = parser.recovered(")", &|t| t == &Token::RParen, |parser| {
811 parse_json_table_columns(parser)
812 })?;
813 parser.consume_token(Token::RParen)?;
814
815 columns.push(JsonTableColumn::Nested {
816 nested_span,
817 path_span,
818 path,
819 columns_span,
820 columns: nested_columns,
821 });
822 } else {
823 let name = parser.consume_plain_identifier_unreserved()?;
825
826 if let Some(for_span) = parser.skip_keyword(Keyword::FOR) {
828 let ordinality_span = parser.consume_keyword(Keyword::ORDINALITY)?;
829 let for_ordinality_span = for_span.join_span(&ordinality_span);
830
831 columns.push(JsonTableColumn::Ordinality {
832 name,
833 for_ordinality_span,
834 });
835 } else {
836 let data_type = parse_data_type(parser, DataTypeContext::FunctionReturn)?;
838
839 let _ = parser.skip_keyword(Keyword::EXISTS);
841
842 let path_span = parser.consume_keyword(Keyword::PATH)?;
844 let path = match &parser.token {
845 Token::String(s, _) => {
846 let val = *s;
847 let span = parser.consume();
848 Expression::String(Box::new(SString::new(Cow::Borrowed(val), span)))
849 }
850 _ => parse_expression_unreserved(parser, PRIORITY_MAX)?,
851 };
852
853 let mut on_empty = None;
856 let mut on_error = None;
857
858 loop {
859 let behavior_start = parser.span.span().start;
860 let behavior = match &parser.token {
861 Token::Ident(_, Keyword::DEFAULT) => {
862 parser.consume();
863 let default_val = parse_expression_unreserved(parser, PRIORITY_MAX)?;
865 Some(JsonTableOnErrorEmpty::Default(default_val))
866 }
867 Token::Ident(_, Keyword::ERROR) => {
868 let error_span = parser.consume();
869 Some(JsonTableOnErrorEmpty::Error(error_span))
870 }
871 Token::Ident(_, Keyword::NULL) => {
872 let null_span = parser.consume();
873 Some(JsonTableOnErrorEmpty::Null(null_span))
874 }
875 _ => None,
876 };
877
878 if let Some(behavior) = behavior {
879 parser.consume_keyword(Keyword::ON)?;
880 let clause_end = parser.span.span().end;
881 match &parser.token {
882 Token::Ident(_, Keyword::EMPTY) => {
883 parser.consume();
884 let span = behavior_start..clause_end;
885 on_empty = Some((behavior, span));
886 }
887 Token::Ident(_, Keyword::ERROR) => {
888 parser.consume();
889 let span = behavior_start..clause_end;
890 on_error = Some((behavior, span));
891 }
892 _ => {
893 parser.expected_failure("EMPTY or ERROR")?;
895 }
896 }
897 } else {
898 break;
900 }
901 }
902
903 columns.push(JsonTableColumn::Column {
904 name,
905 data_type,
906 path_span,
907 path,
908 on_empty,
909 on_error,
910 });
911 }
912 }
913
914 if parser.skip_token(Token::Comma).is_none() {
916 break;
917 }
918
919 if matches!(parser.token, Token::RParen) {
921 break;
922 }
923 }
924
925 Ok(columns)
926}
927
928pub(crate) fn parse_table_reference<'a>(
929 parser: &mut Parser<'a, '_>,
930 additional_restrict: crate::keywords::Restrict,
931) -> Result<TableReference<'a>, ParseError> {
932 let mut ans = parse_table_reference_inner(parser, additional_restrict)?;
933 loop {
934 let join = match parser.token {
935 Token::Ident(_, Keyword::FULL) => {
936 let full = parser.consume_keyword(Keyword::FULL)?;
937 parser.postgres_only(&full);
938 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
939 JoinType::FullOuter(
940 full.join_span(&outer)
941 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
942 )
943 } else {
944 JoinType::FullOuter(full.join_span(&parser.consume_keyword(Keyword::JOIN)?))
945 }
946 }
947 Token::Ident(_, Keyword::INNER) => JoinType::Inner(
948 parser
949 .consume_keyword(Keyword::INNER)?
950 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
951 ),
952 Token::Ident(_, Keyword::CROSS) => JoinType::Cross(
953 parser
954 .consume_keyword(Keyword::CROSS)?
955 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
956 ),
957 Token::Ident(_, Keyword::JOIN) => {
958 JoinType::Normal(parser.consume_keyword(Keyword::JOIN)?)
959 }
960 Token::Ident(_, Keyword::STRAIGHT_JOIN) => {
961 JoinType::Straight(parser.consume_keyword(Keyword::STRAIGHT_JOIN)?)
962 }
963 Token::Ident(_, Keyword::LEFT) => {
964 let left = parser.consume_keyword(Keyword::LEFT)?;
965 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
966 JoinType::Left(
967 left.join_span(&outer)
968 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
969 )
970 } else {
971 JoinType::Left(left.join_span(&parser.consume_keyword(Keyword::JOIN)?))
972 }
973 }
974 Token::Ident(_, Keyword::RIGHT) => {
975 let right = parser.consume_keyword(Keyword::RIGHT)?;
976 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
977 JoinType::Right(
978 right
979 .join_span(&outer)
980 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
981 )
982 } else {
983 JoinType::Right(right.join_span(&parser.consume_keyword(Keyword::JOIN)?))
984 }
985 }
986 Token::Ident(_, Keyword::NATURAL) => {
987 let natural = parser.consume_keyword(Keyword::NATURAL)?;
988 match &parser.token {
989 Token::Ident(_, Keyword::INNER) => JoinType::NaturalInner(
990 natural
991 .join_span(&parser.consume_keywords(&[Keyword::INNER, Keyword::JOIN])?),
992 ),
993 Token::Ident(_, Keyword::LEFT) => {
994 let left = parser.consume_keyword(Keyword::LEFT)?;
995 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
996 JoinType::NaturalLeft(
997 left.join_span(&outer)
998 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
999 )
1000 } else {
1001 JoinType::NaturalLeft(
1002 left.join_span(&parser.consume_keyword(Keyword::JOIN)?),
1003 )
1004 }
1005 }
1006 Token::Ident(_, Keyword::RIGHT) => {
1007 let right = parser.consume_keyword(Keyword::RIGHT)?;
1008 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
1009 JoinType::NaturalRight(
1010 right
1011 .join_span(&outer)
1012 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
1013 )
1014 } else {
1015 JoinType::NaturalRight(
1016 right.join_span(&parser.consume_keyword(Keyword::JOIN)?),
1017 )
1018 }
1019 }
1020 Token::Ident(_, Keyword::JOIN) => JoinType::Natural(
1021 natural.join_span(&parser.consume_keyword(Keyword::JOIN)?),
1022 ),
1023 _ => parser.expected_failure("'INNER', 'LEFT', 'RIGHT' or 'JOIN'")?,
1024 }
1025 }
1026 _ => break,
1027 };
1028
1029 let right = parse_table_reference_inner(parser, additional_restrict)?;
1030
1031 let specification = match &parser.token {
1032 Token::Ident(_, Keyword::ON) => {
1033 let on = parser.consume_keyword(Keyword::ON)?;
1034 let expr = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1035 Some(JoinSpecification::On(expr, on))
1036 }
1037 Token::Ident(_, Keyword::USING) => {
1038 let using = parser.consume_keyword(Keyword::USING)?;
1039 let mut join_column_list = Vec::new();
1040 loop {
1041 join_column_list.push(parser.consume_plain_identifier_unreserved()?);
1042 if parser.skip_token(Token::Comma).is_none() {
1043 break;
1044 }
1045 }
1046 Some(JoinSpecification::Using(join_column_list, using))
1047 }
1048 _ => None,
1049 };
1050
1051 ans = TableReference::Join {
1052 join,
1053 left: Box::new(ans),
1054 right: Box::new(right),
1055 specification,
1056 };
1057 }
1058 Ok(ans)
1059}
1060
1061#[derive(Debug, Clone)]
1063pub enum SelectFlag {
1064 All(Span),
1065 Distinct(Span),
1066 DistinctOn(Span),
1067 DistinctRow(Span),
1068 HighPriority(Span),
1069 StraightJoin(Span),
1070 SqlSmallResult(Span),
1071 SqlBigResult(Span),
1072 SqlBufferResult(Span),
1073 SqlNoCache(Span),
1074 SqlCalcFoundRows(Span),
1075}
1076
1077impl Spanned for SelectFlag {
1078 fn span(&self) -> Span {
1079 match &self {
1080 SelectFlag::All(v) => v.span(),
1081 SelectFlag::Distinct(v) => v.span(),
1082 SelectFlag::DistinctOn(v) => v.span(),
1083 SelectFlag::DistinctRow(v) => v.span(),
1084 SelectFlag::HighPriority(v) => v.span(),
1085 SelectFlag::StraightJoin(v) => v.span(),
1086 SelectFlag::SqlSmallResult(v) => v.span(),
1087 SelectFlag::SqlBigResult(v) => v.span(),
1088 SelectFlag::SqlBufferResult(v) => v.span(),
1089 SelectFlag::SqlNoCache(v) => v.span(),
1090 SelectFlag::SqlCalcFoundRows(v) => v.span(),
1091 }
1092 }
1093}
1094
1095#[derive(Debug, Clone)]
1097pub enum OrderFlag {
1098 Asc(Span),
1099 Desc(Span),
1100 AscNullsFirst(Span),
1101 AscNullsLast(Span),
1102 DescNullsFirst(Span),
1103 DescNullsLast(Span),
1104 NullsFirst(Span),
1105 NullsLast(Span),
1106 None,
1107}
1108impl OptSpanned for OrderFlag {
1109 fn opt_span(&self) -> Option<Span> {
1110 match &self {
1111 OrderFlag::Asc(v) => v.opt_span(),
1112 OrderFlag::Desc(v) => v.opt_span(),
1113 OrderFlag::AscNullsFirst(v) => v.opt_span(),
1114 OrderFlag::AscNullsLast(v) => v.opt_span(),
1115 OrderFlag::DescNullsFirst(v) => v.opt_span(),
1116 OrderFlag::DescNullsLast(v) => v.opt_span(),
1117 OrderFlag::NullsFirst(v) => v.opt_span(),
1118 OrderFlag::NullsLast(v) => v.opt_span(),
1119 OrderFlag::None => None,
1120 }
1121 }
1122}
1123
1124#[derive(Debug, Clone)]
1126pub enum LockStrength {
1127 Update(Span),
1128 Share(Span),
1129 NoKeyUpdate(Span),
1130 KeyShare(Span),
1131}
1132impl Spanned for LockStrength {
1133 fn span(&self) -> Span {
1134 match &self {
1135 LockStrength::Update(v) => v.span(),
1136 LockStrength::Share(v) => v.span(),
1137 LockStrength::NoKeyUpdate(v) => v.span(),
1138 LockStrength::KeyShare(v) => v.span(),
1139 }
1140 }
1141}
1142
1143#[derive(Debug, Clone)]
1144pub enum LockWait {
1145 NoWait(Span),
1146 SkipLocket(Span),
1147 Default,
1148}
1149impl OptSpanned for LockWait {
1150 fn opt_span(&self) -> Option<Span> {
1151 match &self {
1152 LockWait::NoWait(v) => v.opt_span(),
1153 LockWait::SkipLocket(v) => v.opt_span(),
1154 LockWait::Default => None,
1155 }
1156 }
1157}
1158
1159#[derive(Debug, Clone)]
1160pub struct Locking<'a> {
1161 pub for_span: Span,
1163 pub strength: LockStrength,
1164 pub of: Option<(Span, Vec<Identifier<'a>>)>,
1165 pub wait: LockWait,
1166}
1167impl<'a> Spanned for Locking<'a> {
1168 fn span(&self) -> Span {
1169 self.for_span
1170 .join_span(&self.strength)
1171 .join_span(&self.of)
1172 .join_span(&self.wait)
1173 }
1174}
1175
1176#[derive(Debug, Clone)]
1218pub struct Select<'a> {
1219 pub select_span: Span,
1221 pub flags: Vec<SelectFlag>,
1223 pub select_exprs: Vec<SelectExpr<'a>>,
1225 pub from_span: Option<Span>,
1227 pub table_references: Option<Vec<TableReference<'a>>>,
1229 pub where_: Option<(Expression<'a>, Span)>,
1231 pub group_by: Option<(Span, Vec<Expression<'a>>)>,
1233 pub having: Option<(Expression<'a>, Span)>,
1235 pub window_span: Option<Span>,
1237 pub order_by: Option<(Span, Vec<(Expression<'a>, OrderFlag)>)>,
1239 pub limit: Option<(Span, Option<Expression<'a>>, Expression<'a>)>,
1241 pub distinct_on: Option<(Span, Vec<Expression<'a>>)>,
1243 pub offset: Option<(Span, Expression<'a>)>,
1245 pub fetch: Option<(Span, Expression<'a>)>,
1247 pub locking: Option<Locking<'a>>,
1249}
1250
1251impl<'a> Spanned for Select<'a> {
1252 fn span(&self) -> Span {
1253 self.select_span
1254 .join_span(&self.flags)
1255 .join_span(&self.select_exprs)
1256 .join_span(&self.from_span)
1257 .join_span(&self.table_references)
1258 .join_span(&self.where_)
1259 .join_span(&self.group_by)
1260 .join_span(&self.having)
1261 .join_span(&self.window_span)
1262 .join_span(&self.order_by)
1263 .join_span(&self.limit)
1264 .join_span(&self.distinct_on)
1265 .join_span(&self.offset)
1266 .join_span(&self.fetch)
1267 }
1268}
1269
1270pub(crate) fn parse_select_body<'a>(
1273 parser: &mut Parser<'a, '_>,
1274 select_span: Span,
1275) -> Result<Select<'a>, ParseError> {
1276 let mut flags = Vec::new();
1277 let mut select_exprs = Vec::new();
1278
1279 loop {
1280 match &parser.token {
1281 Token::Ident(_, Keyword::ALL) => {
1282 flags.push(SelectFlag::All(parser.consume_keyword(Keyword::ALL)?))
1283 }
1284 Token::Ident(_, Keyword::DISTINCT) => {
1285 let distinct_span = parser.consume_keyword(Keyword::DISTINCT)?;
1286 if matches!(parser.token, Token::Ident(_, Keyword::ON)) {
1288 flags.push(SelectFlag::DistinctOn(distinct_span));
1289 } else {
1290 flags.push(SelectFlag::Distinct(distinct_span));
1291 }
1292 }
1293 Token::Ident(_, Keyword::DISTINCTROW) => flags.push(SelectFlag::DistinctRow(
1294 parser.consume_keyword(Keyword::DISTINCTROW)?,
1295 )),
1296 Token::Ident(_, Keyword::HIGH_PRIORITY) => flags.push(SelectFlag::HighPriority(
1297 parser.consume_keyword(Keyword::HIGH_PRIORITY)?,
1298 )),
1299 Token::Ident(_, Keyword::STRAIGHT_JOIN) => flags.push(SelectFlag::StraightJoin(
1300 parser.consume_keyword(Keyword::STRAIGHT_JOIN)?,
1301 )),
1302 Token::Ident(_, Keyword::SQL_SMALL_RESULT) => flags.push(SelectFlag::SqlSmallResult(
1303 parser.consume_keyword(Keyword::SQL_SMALL_RESULT)?,
1304 )),
1305 Token::Ident(_, Keyword::SQL_BIG_RESULT) => flags.push(SelectFlag::SqlBigResult(
1306 parser.consume_keyword(Keyword::SQL_BIG_RESULT)?,
1307 )),
1308 Token::Ident(_, Keyword::SQL_BUFFER_RESULT) => flags.push(SelectFlag::SqlBufferResult(
1309 parser.consume_keyword(Keyword::SQL_BUFFER_RESULT)?,
1310 )),
1311 Token::Ident(_, Keyword::SQL_NO_CACHE) => flags.push(SelectFlag::SqlNoCache(
1312 parser.consume_keyword(Keyword::SQL_NO_CACHE)?,
1313 )),
1314 Token::Ident(_, Keyword::SQL_CALC_FOUND_ROWS) => flags.push(
1315 SelectFlag::SqlCalcFoundRows(parser.consume_keyword(Keyword::SQL_CALC_FOUND_ROWS)?),
1316 ),
1317 _ => break,
1318 }
1319 }
1320
1321 let distinct_on = if flags
1323 .last()
1324 .is_some_and(|f| matches!(f, SelectFlag::DistinctOn(_)))
1325 {
1326 let on_span = parser.consume_keyword(Keyword::ON)?;
1327 parser.postgres_only(&on_span);
1328 parser.consume_token(Token::LParen)?;
1329 let mut exprs = Vec::new();
1330 loop {
1331 parser.recovered(
1332 "')' or ','",
1333 &|t| matches!(t, Token::RParen | Token::Comma),
1334 |parser| {
1335 exprs.push(parse_expression_unreserved(parser, PRIORITY_MAX)?);
1336 Ok(())
1337 },
1338 )?;
1339 if parser.skip_token(Token::Comma).is_none() {
1340 break;
1341 }
1342 }
1343 parser.consume_token(Token::RParen)?;
1344 Some((on_span, exprs))
1345 } else {
1346 None
1347 };
1348
1349 loop {
1350 select_exprs.push(parse_select_expr(parser)?);
1351 if parser.skip_token(Token::Comma).is_none() {
1352 break;
1353 }
1354 }
1355
1356 let from_span = parser.skip_keyword(Keyword::FROM);
1359
1360 let table_references = if from_span.is_some() {
1361 let mut table_references = Vec::new();
1362 loop {
1363 table_references.push(parse_table_reference(parser, Restrict::EMPTY)?);
1364 if parser.skip_token(Token::Comma).is_none() {
1365 break;
1366 }
1367 }
1368 Some(table_references)
1369 } else {
1370 None
1371 };
1372
1373 let where_ = if let Some(span) = parser.skip_keyword(Keyword::WHERE) {
1375 Some((parse_expression_unreserved(parser, PRIORITY_MAX)?, span))
1376 } else {
1377 None
1378 };
1379
1380 let group_by = if let Some(group_span) = parser.skip_keyword(Keyword::GROUP) {
1381 let span = parser.consume_keyword(Keyword::BY)?.join_span(&group_span);
1382 let mut groups = Vec::new();
1383 loop {
1384 groups.push(parse_expression_unreserved(parser, PRIORITY_MAX)?);
1385 if parser.skip_token(Token::Comma).is_none() {
1386 break;
1387 }
1388 }
1389 Some((span, groups))
1391 } else {
1392 None
1393 };
1394
1395 let having = if let Some(span) = parser.skip_keyword(Keyword::HAVING) {
1396 Some((parse_expression_unreserved(parser, PRIORITY_MAX)?, span))
1397 } else {
1398 None
1399 };
1400
1401 let window_span = parser.skip_keyword(Keyword::WINDOW);
1402 if window_span.is_some() {
1403 }
1405
1406 let order_by = if let Some(span) = parser.skip_keyword(Keyword::ORDER) {
1407 let span = parser.consume_keyword(Keyword::BY)?.join_span(&span);
1408 let mut order = Vec::new();
1409 loop {
1410 let e = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1411 let dir_span_opt = match &parser.token {
1412 Token::Ident(_, Keyword::ASC) => Some((true, parser.consume())),
1413 Token::Ident(_, Keyword::DESC) => Some((false, parser.consume())),
1414 _ => None,
1415 };
1416 let f = if let Some(nulls_span) = parser.skip_keyword(Keyword::NULLS) {
1417 match &parser.token {
1418 Token::Ident(_, Keyword::FIRST) => {
1419 let s = parser.consume().join_span(&nulls_span);
1420 parser.postgres_only(&s);
1421 match dir_span_opt {
1422 Some((true, _)) => OrderFlag::AscNullsFirst(s),
1423 Some((false, _)) => OrderFlag::DescNullsFirst(s),
1424 None => OrderFlag::NullsFirst(s),
1425 }
1426 }
1427 Token::Ident(_, Keyword::LAST) => {
1428 let s = parser.consume().join_span(&nulls_span);
1429 parser.postgres_only(&s);
1430 match dir_span_opt {
1431 Some((true, _)) => OrderFlag::AscNullsLast(s),
1432 Some((false, _)) => OrderFlag::DescNullsLast(s),
1433 None => OrderFlag::NullsLast(s),
1434 }
1435 }
1436 _ => parser.expected_failure("FIRST or LAST")?,
1437 }
1438 } else {
1439 match dir_span_opt {
1440 Some((true, s)) => OrderFlag::Asc(s),
1441 Some((false, s)) => OrderFlag::Desc(s),
1442 None => OrderFlag::None,
1443 }
1444 };
1445 order.push((e, f));
1446 if parser.skip_token(Token::Comma).is_none() {
1447 break;
1448 }
1449 }
1450 Some((span, order))
1451 } else {
1452 None
1453 };
1454
1455 let limit = if let Some(span) = parser.skip_keyword(Keyword::LIMIT) {
1456 let n = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1457 match parser.token {
1458 Token::Comma => {
1459 parser.consume();
1460 Some((
1461 span,
1462 Some(n),
1463 parse_expression_unreserved(parser, PRIORITY_MAX)?,
1464 ))
1465 }
1466 Token::Ident(_, Keyword::OFFSET) => {
1467 parser.consume();
1468 Some((
1469 span,
1470 Some(parse_expression_unreserved(parser, PRIORITY_MAX)?),
1471 n,
1472 ))
1473 }
1474 _ => Some((span, None, n)),
1475 }
1476 } else {
1477 None
1478 };
1479
1480 let offset = if limit.is_none() {
1482 if let Some(offset_span) = parser.skip_keyword(Keyword::OFFSET) {
1483 parser.postgres_only(&offset_span);
1484 let n = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1485 if matches!(parser.token, Token::Ident(_, Keyword::ROWS | Keyword::ROW)) {
1487 parser.consume();
1488 }
1489 Some((offset_span, n))
1490 } else {
1491 None
1492 }
1493 } else {
1494 None
1495 };
1496
1497 let fetch = if let Some(fetch_span) = parser.skip_keyword(Keyword::FETCH) {
1499 parser.postgres_only(&fetch_span);
1500 match &parser.token {
1501 Token::Ident(_, Keyword::FIRST | Keyword::NEXT) => {
1502 parser.consume();
1503 }
1504 _ => parser.expected_failure("FIRST or NEXT")?,
1505 }
1506 let n = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1507 if matches!(parser.token, Token::Ident(_, Keyword::ROWS | Keyword::ROW)) {
1508 parser.consume();
1509 }
1510 parser.consume_keyword(Keyword::ONLY)?;
1511 Some((fetch_span, n))
1512 } else {
1513 None
1514 };
1515
1516 let locking = if let Some(for_span) = parser.skip_keyword(Keyword::FOR) {
1517 let strength = match &parser.token {
1518 Token::Ident(_, Keyword::UPDATE) => {
1519 LockStrength::Update(parser.consume_keyword(Keyword::UPDATE)?)
1520 }
1521 Token::Ident(_, Keyword::SHARE) => {
1522 LockStrength::Share(parser.consume_keyword(Keyword::SHARE)?)
1523 }
1524 Token::Ident(_, Keyword::NO) => {
1525 LockStrength::NoKeyUpdate(parser.consume_keywords(&[
1526 Keyword::NO,
1527 Keyword::KEY,
1528 Keyword::UPDATE,
1529 ])?)
1530 }
1531 Token::Ident(_, Keyword::KEY) => {
1532 LockStrength::KeyShare(parser.consume_keywords(&[Keyword::KEY, Keyword::SHARE])?)
1533 }
1534 _ => parser.expected_failure("UPDATE, SHARE, NO KEY UPDATE or KEY SHARE here")?,
1535 };
1536
1537 if let LockStrength::NoKeyUpdate(s) | LockStrength::KeyShare(s) = &strength
1538 && !parser.options.dialect.is_postgresql()
1539 {
1540 parser.err("Only support by PostgreSQL", s);
1541 }
1542
1543 let of = if let Some(of_span) = parser.skip_keyword(Keyword::OF) {
1544 let mut table_references = Vec::new();
1545 loop {
1546 table_references.push(parser.consume_plain_identifier_unreserved()?);
1547 if parser.skip_token(Token::Comma).is_none() {
1548 break;
1549 }
1550 }
1551 Some((of_span, table_references))
1552 } else {
1553 None
1554 };
1555
1556 let wait = match &parser.token {
1557 Token::Ident(_, Keyword::NOWAIT) => {
1558 LockWait::NoWait(parser.consume_keyword(Keyword::NOWAIT)?)
1559 }
1560 Token::Ident(_, Keyword::SKIP) => {
1561 LockWait::SkipLocket(parser.consume_keywords(&[Keyword::SKIP, Keyword::LOCKED])?)
1562 }
1563 _ => LockWait::Default,
1564 };
1565 Some(Locking {
1566 for_span,
1567 strength,
1568 of,
1569 wait,
1570 })
1571 } else {
1572 None
1573 };
1574
1575 Ok(Select {
1587 select_span,
1588 flags,
1589 select_exprs,
1590 from_span,
1591 table_references,
1592 where_,
1593 group_by,
1594 having,
1595 window_span,
1596 order_by,
1597 limit,
1598 distinct_on,
1599 offset,
1600 fetch,
1601 locking,
1602 })
1603}
1604
1605pub(crate) fn parse_select<'a>(parser: &mut Parser<'a, '_>) -> Result<Select<'a>, ParseError> {
1606 let select_span = parser.consume_keyword(Keyword::SELECT)?;
1607 parse_select_body(parser, select_span)
1608}