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 },
352 Join {
354 join: JoinType,
356 left: Box<TableReference<'a>>,
358 right: Box<TableReference<'a>>,
360 specification: Option<JoinSpecification<'a>>,
362 },
363}
364
365impl<'a> Spanned for TableReference<'a> {
366 fn span(&self) -> Span {
367 match &self {
368 TableReference::Table {
369 identifier,
370 as_span,
371 as_,
372 index_hints,
373 } => identifier
374 .opt_join_span(as_span)
375 .opt_join_span(as_)
376 .opt_join_span(index_hints)
377 .expect("span of table"),
378 TableReference::Query {
379 query,
380 as_span,
381 as_,
382 col_list,
383 } => query.join_span(as_span).join_span(as_).join_span(col_list),
384 TableReference::JsonTable {
385 json_table_span,
386 json_expr,
387 path,
388 columns_keyword_span,
389 columns,
390 as_span,
391 as_,
392 } => json_table_span
393 .join_span(json_expr)
394 .join_span(path)
395 .join_span(columns_keyword_span)
396 .join_span(columns)
397 .join_span(as_span)
398 .join_span(as_),
399 TableReference::Function {
400 name,
401 args,
402 with_ordinality,
403 as_span,
404 as_,
405 } => name
406 .span()
407 .join_span(args)
408 .join_span(with_ordinality)
409 .join_span(as_span)
410 .join_span(as_),
411 TableReference::Join {
412 join,
413 left,
414 right,
415 specification,
416 } => join
417 .join_span(left)
418 .join_span(right)
419 .join_span(specification),
420 }
421 }
422}
423
424pub(crate) fn parse_table_reference_inner<'a>(
425 parser: &mut Parser<'a, '_>,
426 additional_restrict: crate::keywords::Restrict,
427) -> Result<TableReference<'a>, ParseError> {
428 match &parser.token {
436 Token::Ident(_, Keyword::LATERAL) => {
437 let lateral_span = parser.consume_keyword(Keyword::LATERAL)?;
439 parser.postgres_only(&lateral_span);
440 let query = parse_compound_query(parser)?;
441 let as_span = parser.skip_keyword(Keyword::AS);
442 let as_ = if as_span.is_some()
443 || (matches!(&parser.token, Token::Ident(_, k) if !k.restricted(parser.reserved() | additional_restrict)))
444 {
445 Some(
446 parser.consume_plain_identifier_restrict(
447 parser.reserved() | additional_restrict,
448 )?,
449 )
450 } else {
451 None
452 };
453 Ok(TableReference::Query {
454 query: Box::new(query),
455 as_span: as_span
456 .map(|s| lateral_span.join_span(&s))
457 .or(Some(lateral_span)),
458 as_,
459 col_list: Vec::new(),
460 })
461 }
462 Token::Ident(_, Keyword::SELECT) | Token::LParen => {
463 let is_join_group = matches!(parser.token, Token::LParen)
467 && !matches!(
468 parser.peek(),
469 Token::Ident(_, Keyword::SELECT | Keyword::VALUES | Keyword::WITH)
470 );
471 if is_join_group {
472 parser.consume_token(Token::LParen)?;
473 let inner = parse_table_reference(parser, additional_restrict)?;
474 parser.consume_token(Token::RParen)?;
475 return Ok(inner);
476 }
477 let query = parse_compound_query(parser)?;
478 let as_span = parser.skip_keyword(Keyword::AS);
479 let as_ = if as_span.is_some()
480 || (matches!(&parser.token, Token::Ident(_, k) if !k.restricted(parser.reserved() | additional_restrict)))
481 {
482 Some(
483 parser.consume_plain_identifier_restrict(
484 parser.reserved() | additional_restrict,
485 )?,
486 )
487 } else {
488 None
489 };
490 let mut col_list = Vec::new();
492 if as_.is_some() && matches!(parser.token, Token::LParen) {
493 parser.consume_token(Token::LParen)?;
494 loop {
495 parser.recovered(
496 "')' or ','",
497 &|t| matches!(t, Token::RParen | Token::Comma),
498 |parser| {
499 col_list
500 .push(parser.consume_plain_identifier_restrict(Restrict::EMPTY)?);
501 Ok(())
502 },
503 )?;
504 if parser.skip_token(Token::Comma).is_none() {
505 break;
506 }
507 }
508 parser.consume_token(Token::RParen)?;
509 };
510 Ok(TableReference::Query {
511 query: Box::new(query),
512 as_span,
513 as_,
514 col_list,
515 })
516 }
517 Token::Ident(_, _) => parse_table_reference_named(parser, additional_restrict),
518 Token::String(_, StringType::DoubleQuoted) if parser.options.dialect.is_postgresql() => {
519 parse_table_reference_named(parser, additional_restrict)
520 }
521 _ => parser.expected_failure("subquery or identifier"),
522 }
523}
524
525fn parse_table_reference_named<'a>(
526 parser: &mut Parser<'a, '_>,
527 additional_restrict: Restrict,
528) -> Result<TableReference<'a>, ParseError> {
529 if matches!(parser.token, Token::Ident(_, Keyword::JSON_TABLE))
530 && matches!(parser.peek(), Token::LParen)
531 {
532 let json_table_span = parser.consume_keyword(Keyword::JSON_TABLE)?;
533
534 parser.consume_token(Token::LParen)?;
535
536 let json_expr = parse_expression_unreserved(parser, PRIORITY_MAX)?;
538
539 parser.consume_token(Token::Comma)?;
541
542 let path = match &parser.token {
544 Token::String(s, _) => {
545 let val = *s;
546 let span = parser.consume();
547 Expression::String(Box::new(SString::new(Cow::Borrowed(val), span)))
548 }
549 _ => {
550 parse_expression_unreserved(parser, PRIORITY_MAX)?
552 }
553 };
554
555 let columns_keyword_span = parser.consume_keyword(Keyword::COLUMNS)?;
557 parser.consume_token(Token::LParen)?;
558
559 let columns = parser.recovered(")", &|t| t == &Token::RParen, |parser| {
560 parse_json_table_columns(parser)
562 })?;
563
564 parser.consume_token(Token::RParen)?;
565
566 parser.consume_token(Token::RParen)?;
568
569 let as_span = parser.skip_keyword(Keyword::AS);
571 let as_ = if as_span.is_some()
572 || (matches!(&parser.token, Token::Ident(_, k) if !k.restricted(parser.reserved() | additional_restrict)))
573 {
574 Some(parser.consume_plain_identifier_unreserved()?)
575 } else {
576 None
577 };
578
579 return Ok(TableReference::JsonTable {
580 json_table_span,
581 json_expr,
582 path,
583 columns_keyword_span,
584 columns,
585 as_span,
586 as_,
587 });
588 }
589
590 let first_kw = match &parser.token {
594 Token::Ident(_, kw) => Some(*kw),
595 _ => None,
596 };
597 let identifier = parse_qualified_name_unreserved(parser)?;
598
599 if matches!(parser.token, Token::LParen) {
600 let func_name = if identifier.prefix.is_empty() {
602 match first_kw {
603 Some(Keyword::UNNEST) => TableFunctionName::Unnest(identifier.identifier.span),
604 Some(Keyword::GENERATE_SERIES) => {
605 TableFunctionName::GenerateSeries(identifier.identifier.span)
606 }
607 Some(Keyword::STRING_TO_TABLE) => {
608 TableFunctionName::StringToTable(identifier.identifier.span)
609 }
610 _ => TableFunctionName::Other(identifier),
611 }
612 } else {
613 TableFunctionName::Other(identifier)
614 };
615 parser.consume_token(Token::LParen)?;
616 let mut args = Vec::new();
617 if !matches!(parser.token, Token::RParen) {
618 loop {
619 parser.recovered(
620 "')' or ','",
621 &|t| matches!(t, Token::RParen | Token::Comma),
622 |parser| {
623 args.push(parse_expression_unreserved(parser, PRIORITY_MAX)?);
624 Ok(())
625 },
626 )?;
627 if parser.skip_token(Token::Comma).is_none() {
628 break;
629 }
630 }
631 }
632 parser.consume_token(Token::RParen)?;
633 let with_ordinality = if let Some(with_span) = parser.skip_keyword(Keyword::WITH) {
635 let ord_span = parser.consume_keyword(Keyword::ORDINALITY)?;
636 Some(with_span.join_span(&ord_span))
637 } else {
638 None
639 };
640 let as_span = parser.skip_keyword(Keyword::AS);
641 let as_ = if as_span.is_some()
642 || (matches!(&parser.token, Token::Ident(_, k) if !k.restricted(parser.reserved() | additional_restrict)))
643 {
644 Some(parser.consume_plain_identifier_unreserved()?)
645 } else {
646 None
647 };
648 return Ok(TableReference::Function {
649 name: func_name,
650 args,
651 with_ordinality,
652 as_span,
653 as_,
654 });
655 }
656
657 let as_span = parser.skip_keyword(Keyword::AS);
659 let as_ = if as_span.is_some()
660 || (matches!(&parser.token, Token::Ident(_, k) if !k.restricted(parser.reserved() | additional_restrict)))
661 {
662 Some(parser.consume_plain_identifier_restrict(parser.reserved() | additional_restrict)?)
663 } else {
664 None
665 };
666
667 let mut index_hints = Vec::new();
668 loop {
669 let use_ = match parser.token {
670 Token::Ident(_, Keyword::USE) => IndexHintUse::Use(parser.consume()),
671 Token::Ident(_, Keyword::IGNORE) => IndexHintUse::Ignore(parser.consume()),
672 Token::Ident(_, Keyword::FORCE) => IndexHintUse::Force(parser.consume()),
673 _ => break,
674 };
675 let type_ = match parser.token {
676 Token::Ident(_, Keyword::INDEX) => IndexHintType::Index(parser.consume()),
677 Token::Ident(_, Keyword::KEY) => IndexHintType::Key(parser.consume()),
678 _ => parser.expected_failure("'INDEX' or 'KEY'")?,
679 };
680 let for_ = if let Some(for_span) = parser.skip_keyword(Keyword::FOR) {
681 let v = match parser.token {
682 Token::Ident(_, Keyword::JOIN) => IndexHintFor::Join(parser.consume()),
683 Token::Ident(_, Keyword::GROUP) => {
684 IndexHintFor::GroupBy(parser.consume_keywords(&[Keyword::GROUP, Keyword::BY])?)
685 }
686 Token::Ident(_, Keyword::ORDER) => {
687 IndexHintFor::OrderBy(parser.consume_keywords(&[Keyword::ORDER, Keyword::BY])?)
688 }
689 _ => parser.expected_failure("'JOIN', 'GROUP BY' or 'ORDER BY'")?,
690 };
691 Some((for_span, v))
692 } else {
693 None
694 };
695 let lparen = parser.consume_token(Token::LParen)?;
696 let mut index_list = Vec::new();
697 loop {
698 parser.recovered(
699 "')' or ','",
700 &|t| matches!(t, Token::RParen | Token::Comma),
701 |parser| {
702 index_list.push(parser.consume_plain_identifier_unreserved()?);
703 Ok(())
704 },
705 )?;
706 if matches!(parser.token, Token::RParen) {
707 break;
708 }
709 parser.consume_token(Token::Comma)?;
710 }
711 let rparen = parser.consume_token(Token::RParen)?;
712 index_hints.push(IndexHint {
713 use_,
714 type_,
715 for_,
716 lparen,
717 index_list,
718 rparen,
719 })
720 }
721
722 if !index_hints.is_empty() && !parser.options.dialect.is_maria() {
723 parser.err(
724 "Index hints only supported by MariaDb",
725 &index_hints.opt_span().unwrap(),
726 );
727 }
728
729 Ok(TableReference::Table {
730 identifier,
731 as_span,
732 as_,
733 index_hints,
734 })
735}
736
737fn parse_json_table_columns<'a>(
738 parser: &mut Parser<'a, '_>,
739) -> Result<Vec<JsonTableColumn<'a>>, ParseError> {
740 let mut columns = Vec::new();
741
742 loop {
743 if let Some(nested_span) = parser.skip_keyword(Keyword::NESTED) {
745 let path_span = parser.consume_keyword(Keyword::PATH)?;
746 let path = match &parser.token {
747 Token::String(s, _) => {
748 let val = *s;
749 let span = parser.consume();
750 Expression::String(Box::new(SString::new(Cow::Borrowed(val), span)))
751 }
752 _ => parse_expression_unreserved(parser, PRIORITY_MAX)?,
753 };
754 let columns_span = parser.consume_keyword(Keyword::COLUMNS)?;
755 parser.consume_token(Token::LParen)?;
756 let nested_columns = parser.recovered(")", &|t| t == &Token::RParen, |parser| {
757 parse_json_table_columns(parser)
758 })?;
759 parser.consume_token(Token::RParen)?;
760
761 columns.push(JsonTableColumn::Nested {
762 nested_span,
763 path_span,
764 path,
765 columns_span,
766 columns: nested_columns,
767 });
768 } else {
769 let name = parser.consume_plain_identifier_unreserved()?;
771
772 if let Some(for_span) = parser.skip_keyword(Keyword::FOR) {
774 let ordinality_span = parser.consume_keyword(Keyword::ORDINALITY)?;
775 let for_ordinality_span = for_span.join_span(&ordinality_span);
776
777 columns.push(JsonTableColumn::Ordinality {
778 name,
779 for_ordinality_span,
780 });
781 } else {
782 let data_type = parse_data_type(parser, DataTypeContext::FunctionReturn)?;
784
785 let _ = parser.skip_keyword(Keyword::EXISTS);
787
788 let path_span = parser.consume_keyword(Keyword::PATH)?;
790 let path = match &parser.token {
791 Token::String(s, _) => {
792 let val = *s;
793 let span = parser.consume();
794 Expression::String(Box::new(SString::new(Cow::Borrowed(val), span)))
795 }
796 _ => parse_expression_unreserved(parser, PRIORITY_MAX)?,
797 };
798
799 let mut on_empty = None;
802 let mut on_error = None;
803
804 loop {
805 let behavior_start = parser.span.span().start;
806 let behavior = match &parser.token {
807 Token::Ident(_, Keyword::DEFAULT) => {
808 parser.consume();
809 let default_val = parse_expression_unreserved(parser, PRIORITY_MAX)?;
811 Some(JsonTableOnErrorEmpty::Default(default_val))
812 }
813 Token::Ident(_, Keyword::ERROR) => {
814 let error_span = parser.consume();
815 Some(JsonTableOnErrorEmpty::Error(error_span))
816 }
817 Token::Ident(_, Keyword::NULL) => {
818 let null_span = parser.consume();
819 Some(JsonTableOnErrorEmpty::Null(null_span))
820 }
821 _ => None,
822 };
823
824 if let Some(behavior) = behavior {
825 parser.consume_keyword(Keyword::ON)?;
826 let clause_end = parser.span.span().end;
827 match &parser.token {
828 Token::Ident(_, Keyword::EMPTY) => {
829 parser.consume();
830 let span = behavior_start..clause_end;
831 on_empty = Some((behavior, span));
832 }
833 Token::Ident(_, Keyword::ERROR) => {
834 parser.consume();
835 let span = behavior_start..clause_end;
836 on_error = Some((behavior, span));
837 }
838 _ => {
839 parser.expected_failure("EMPTY or ERROR")?;
841 }
842 }
843 } else {
844 break;
846 }
847 }
848
849 columns.push(JsonTableColumn::Column {
850 name,
851 data_type,
852 path_span,
853 path,
854 on_empty,
855 on_error,
856 });
857 }
858 }
859
860 if parser.skip_token(Token::Comma).is_none() {
862 break;
863 }
864
865 if matches!(parser.token, Token::RParen) {
867 break;
868 }
869 }
870
871 Ok(columns)
872}
873
874pub(crate) fn parse_table_reference<'a>(
875 parser: &mut Parser<'a, '_>,
876 additional_restrict: crate::keywords::Restrict,
877) -> Result<TableReference<'a>, ParseError> {
878 let mut ans = parse_table_reference_inner(parser, additional_restrict)?;
879 loop {
880 let join = match parser.token {
881 Token::Ident(_, Keyword::FULL) => {
882 let full = parser.consume_keyword(Keyword::FULL)?;
883 parser.postgres_only(&full);
884 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
885 JoinType::FullOuter(
886 full.join_span(&outer)
887 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
888 )
889 } else {
890 JoinType::FullOuter(full.join_span(&parser.consume_keyword(Keyword::JOIN)?))
891 }
892 }
893 Token::Ident(_, Keyword::INNER) => JoinType::Inner(
894 parser
895 .consume_keyword(Keyword::INNER)?
896 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
897 ),
898 Token::Ident(_, Keyword::CROSS) => JoinType::Cross(
899 parser
900 .consume_keyword(Keyword::CROSS)?
901 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
902 ),
903 Token::Ident(_, Keyword::JOIN) => {
904 JoinType::Normal(parser.consume_keyword(Keyword::JOIN)?)
905 }
906 Token::Ident(_, Keyword::STRAIGHT_JOIN) => {
907 JoinType::Straight(parser.consume_keyword(Keyword::STRAIGHT_JOIN)?)
908 }
909 Token::Ident(_, Keyword::LEFT) => {
910 let left = parser.consume_keyword(Keyword::LEFT)?;
911 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
912 JoinType::Left(
913 left.join_span(&outer)
914 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
915 )
916 } else {
917 JoinType::Left(left.join_span(&parser.consume_keyword(Keyword::JOIN)?))
918 }
919 }
920 Token::Ident(_, Keyword::RIGHT) => {
921 let right = parser.consume_keyword(Keyword::RIGHT)?;
922 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
923 JoinType::Right(
924 right
925 .join_span(&outer)
926 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
927 )
928 } else {
929 JoinType::Right(right.join_span(&parser.consume_keyword(Keyword::JOIN)?))
930 }
931 }
932 Token::Ident(_, Keyword::NATURAL) => {
933 let natural = parser.consume_keyword(Keyword::NATURAL)?;
934 match &parser.token {
935 Token::Ident(_, Keyword::INNER) => JoinType::NaturalInner(
936 natural
937 .join_span(&parser.consume_keywords(&[Keyword::INNER, Keyword::JOIN])?),
938 ),
939 Token::Ident(_, Keyword::LEFT) => {
940 let left = parser.consume_keyword(Keyword::LEFT)?;
941 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
942 JoinType::NaturalLeft(
943 left.join_span(&outer)
944 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
945 )
946 } else {
947 JoinType::NaturalLeft(
948 left.join_span(&parser.consume_keyword(Keyword::JOIN)?),
949 )
950 }
951 }
952 Token::Ident(_, Keyword::RIGHT) => {
953 let right = parser.consume_keyword(Keyword::RIGHT)?;
954 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
955 JoinType::NaturalRight(
956 right
957 .join_span(&outer)
958 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
959 )
960 } else {
961 JoinType::NaturalRight(
962 right.join_span(&parser.consume_keyword(Keyword::JOIN)?),
963 )
964 }
965 }
966 Token::Ident(_, Keyword::JOIN) => JoinType::Natural(
967 natural.join_span(&parser.consume_keyword(Keyword::JOIN)?),
968 ),
969 _ => parser.expected_failure("'INNER', 'LEFT', 'RIGHT' or 'JOIN'")?,
970 }
971 }
972 _ => break,
973 };
974
975 let right = parse_table_reference_inner(parser, additional_restrict)?;
976
977 let specification = match &parser.token {
978 Token::Ident(_, Keyword::ON) => {
979 let on = parser.consume_keyword(Keyword::ON)?;
980 let expr = parse_expression_unreserved(parser, PRIORITY_MAX)?;
981 Some(JoinSpecification::On(expr, on))
982 }
983 Token::Ident(_, Keyword::USING) => {
984 let using = parser.consume_keyword(Keyword::USING)?;
985 let mut join_column_list = Vec::new();
986 loop {
987 join_column_list.push(parser.consume_plain_identifier_unreserved()?);
988 if parser.skip_token(Token::Comma).is_none() {
989 break;
990 }
991 }
992 Some(JoinSpecification::Using(join_column_list, using))
993 }
994 _ => None,
995 };
996
997 ans = TableReference::Join {
998 join,
999 left: Box::new(ans),
1000 right: Box::new(right),
1001 specification,
1002 };
1003 }
1004 Ok(ans)
1005}
1006
1007#[derive(Debug, Clone)]
1009pub enum SelectFlag {
1010 All(Span),
1011 Distinct(Span),
1012 DistinctOn(Span),
1013 DistinctRow(Span),
1014 HighPriority(Span),
1015 StraightJoin(Span),
1016 SqlSmallResult(Span),
1017 SqlBigResult(Span),
1018 SqlBufferResult(Span),
1019 SqlNoCache(Span),
1020 SqlCalcFoundRows(Span),
1021}
1022
1023impl Spanned for SelectFlag {
1024 fn span(&self) -> Span {
1025 match &self {
1026 SelectFlag::All(v) => v.span(),
1027 SelectFlag::Distinct(v) => v.span(),
1028 SelectFlag::DistinctOn(v) => v.span(),
1029 SelectFlag::DistinctRow(v) => v.span(),
1030 SelectFlag::HighPriority(v) => v.span(),
1031 SelectFlag::StraightJoin(v) => v.span(),
1032 SelectFlag::SqlSmallResult(v) => v.span(),
1033 SelectFlag::SqlBigResult(v) => v.span(),
1034 SelectFlag::SqlBufferResult(v) => v.span(),
1035 SelectFlag::SqlNoCache(v) => v.span(),
1036 SelectFlag::SqlCalcFoundRows(v) => v.span(),
1037 }
1038 }
1039}
1040
1041#[derive(Debug, Clone)]
1043pub enum OrderFlag {
1044 Asc(Span),
1045 Desc(Span),
1046 AscNullsFirst(Span),
1047 AscNullsLast(Span),
1048 DescNullsFirst(Span),
1049 DescNullsLast(Span),
1050 NullsFirst(Span),
1051 NullsLast(Span),
1052 None,
1053}
1054impl OptSpanned for OrderFlag {
1055 fn opt_span(&self) -> Option<Span> {
1056 match &self {
1057 OrderFlag::Asc(v) => v.opt_span(),
1058 OrderFlag::Desc(v) => v.opt_span(),
1059 OrderFlag::AscNullsFirst(v) => v.opt_span(),
1060 OrderFlag::AscNullsLast(v) => v.opt_span(),
1061 OrderFlag::DescNullsFirst(v) => v.opt_span(),
1062 OrderFlag::DescNullsLast(v) => v.opt_span(),
1063 OrderFlag::NullsFirst(v) => v.opt_span(),
1064 OrderFlag::NullsLast(v) => v.opt_span(),
1065 OrderFlag::None => None,
1066 }
1067 }
1068}
1069
1070#[derive(Debug, Clone)]
1072pub enum LockStrength {
1073 Update(Span),
1074 Share(Span),
1075 NoKeyUpdate(Span),
1076 KeyShare(Span),
1077}
1078impl Spanned for LockStrength {
1079 fn span(&self) -> Span {
1080 match &self {
1081 LockStrength::Update(v) => v.span(),
1082 LockStrength::Share(v) => v.span(),
1083 LockStrength::NoKeyUpdate(v) => v.span(),
1084 LockStrength::KeyShare(v) => v.span(),
1085 }
1086 }
1087}
1088
1089#[derive(Debug, Clone)]
1090pub enum LockWait {
1091 NoWait(Span),
1092 SkipLocket(Span),
1093 Default,
1094}
1095impl OptSpanned for LockWait {
1096 fn opt_span(&self) -> Option<Span> {
1097 match &self {
1098 LockWait::NoWait(v) => v.opt_span(),
1099 LockWait::SkipLocket(v) => v.opt_span(),
1100 LockWait::Default => None,
1101 }
1102 }
1103}
1104
1105#[derive(Debug, Clone)]
1106pub struct Locking<'a> {
1107 pub for_span: Span,
1109 pub strength: LockStrength,
1110 pub of: Option<(Span, Vec<Identifier<'a>>)>,
1111 pub wait: LockWait,
1112}
1113impl<'a> Spanned for Locking<'a> {
1114 fn span(&self) -> Span {
1115 self.for_span
1116 .join_span(&self.strength)
1117 .join_span(&self.of)
1118 .join_span(&self.wait)
1119 }
1120}
1121
1122#[derive(Debug, Clone)]
1164pub struct Select<'a> {
1165 pub select_span: Span,
1167 pub flags: Vec<SelectFlag>,
1169 pub select_exprs: Vec<SelectExpr<'a>>,
1171 pub from_span: Option<Span>,
1173 pub table_references: Option<Vec<TableReference<'a>>>,
1175 pub where_: Option<(Expression<'a>, Span)>,
1177 pub group_by: Option<(Span, Vec<Expression<'a>>)>,
1179 pub having: Option<(Expression<'a>, Span)>,
1181 pub window_span: Option<Span>,
1183 pub order_by: Option<(Span, Vec<(Expression<'a>, OrderFlag)>)>,
1185 pub limit: Option<(Span, Option<Expression<'a>>, Expression<'a>)>,
1187 pub distinct_on: Option<(Span, Vec<Expression<'a>>)>,
1189 pub offset: Option<(Span, Expression<'a>)>,
1191 pub fetch: Option<(Span, Expression<'a>)>,
1193 pub locking: Option<Locking<'a>>,
1195}
1196
1197impl<'a> Spanned for Select<'a> {
1198 fn span(&self) -> Span {
1199 self.select_span
1200 .join_span(&self.flags)
1201 .join_span(&self.select_exprs)
1202 .join_span(&self.from_span)
1203 .join_span(&self.table_references)
1204 .join_span(&self.where_)
1205 .join_span(&self.group_by)
1206 .join_span(&self.having)
1207 .join_span(&self.window_span)
1208 .join_span(&self.order_by)
1209 .join_span(&self.limit)
1210 .join_span(&self.distinct_on)
1211 .join_span(&self.offset)
1212 .join_span(&self.fetch)
1213 }
1214}
1215
1216pub(crate) fn parse_select<'a>(parser: &mut Parser<'a, '_>) -> Result<Select<'a>, ParseError> {
1217 let select_span = parser.consume_keyword(Keyword::SELECT)?;
1218 let mut flags = Vec::new();
1219 let mut select_exprs = Vec::new();
1220
1221 loop {
1222 match &parser.token {
1223 Token::Ident(_, Keyword::ALL) => {
1224 flags.push(SelectFlag::All(parser.consume_keyword(Keyword::ALL)?))
1225 }
1226 Token::Ident(_, Keyword::DISTINCT) => {
1227 let distinct_span = parser.consume_keyword(Keyword::DISTINCT)?;
1228 if matches!(parser.token, Token::Ident(_, Keyword::ON)) {
1230 flags.push(SelectFlag::DistinctOn(distinct_span));
1231 } else {
1232 flags.push(SelectFlag::Distinct(distinct_span));
1233 }
1234 }
1235 Token::Ident(_, Keyword::DISTINCTROW) => flags.push(SelectFlag::DistinctRow(
1236 parser.consume_keyword(Keyword::DISTINCTROW)?,
1237 )),
1238 Token::Ident(_, Keyword::HIGH_PRIORITY) => flags.push(SelectFlag::HighPriority(
1239 parser.consume_keyword(Keyword::HIGH_PRIORITY)?,
1240 )),
1241 Token::Ident(_, Keyword::STRAIGHT_JOIN) => flags.push(SelectFlag::StraightJoin(
1242 parser.consume_keyword(Keyword::STRAIGHT_JOIN)?,
1243 )),
1244 Token::Ident(_, Keyword::SQL_SMALL_RESULT) => flags.push(SelectFlag::SqlSmallResult(
1245 parser.consume_keyword(Keyword::SQL_SMALL_RESULT)?,
1246 )),
1247 Token::Ident(_, Keyword::SQL_BIG_RESULT) => flags.push(SelectFlag::SqlBigResult(
1248 parser.consume_keyword(Keyword::SQL_BIG_RESULT)?,
1249 )),
1250 Token::Ident(_, Keyword::SQL_BUFFER_RESULT) => flags.push(SelectFlag::SqlBufferResult(
1251 parser.consume_keyword(Keyword::SQL_BUFFER_RESULT)?,
1252 )),
1253 Token::Ident(_, Keyword::SQL_NO_CACHE) => flags.push(SelectFlag::SqlNoCache(
1254 parser.consume_keyword(Keyword::SQL_NO_CACHE)?,
1255 )),
1256 Token::Ident(_, Keyword::SQL_CALC_FOUND_ROWS) => flags.push(
1257 SelectFlag::SqlCalcFoundRows(parser.consume_keyword(Keyword::SQL_CALC_FOUND_ROWS)?),
1258 ),
1259 _ => break,
1260 }
1261 }
1262
1263 let distinct_on = if flags
1265 .last()
1266 .is_some_and(|f| matches!(f, SelectFlag::DistinctOn(_)))
1267 {
1268 let on_span = parser.consume_keyword(Keyword::ON)?;
1269 parser.postgres_only(&on_span);
1270 parser.consume_token(Token::LParen)?;
1271 let mut exprs = Vec::new();
1272 loop {
1273 parser.recovered(
1274 "')' or ','",
1275 &|t| matches!(t, Token::RParen | Token::Comma),
1276 |parser| {
1277 exprs.push(parse_expression_unreserved(parser, PRIORITY_MAX)?);
1278 Ok(())
1279 },
1280 )?;
1281 if parser.skip_token(Token::Comma).is_none() {
1282 break;
1283 }
1284 }
1285 parser.consume_token(Token::RParen)?;
1286 Some((on_span, exprs))
1287 } else {
1288 None
1289 };
1290
1291 loop {
1292 select_exprs.push(parse_select_expr(parser)?);
1293 if parser.skip_token(Token::Comma).is_none() {
1294 break;
1295 }
1296 }
1297
1298 let from_span = parser.skip_keyword(Keyword::FROM);
1301
1302 let table_references = if from_span.is_some() {
1303 let mut table_references = Vec::new();
1304 loop {
1305 table_references.push(parse_table_reference(parser, Restrict::EMPTY)?);
1306 if parser.skip_token(Token::Comma).is_none() {
1307 break;
1308 }
1309 }
1310 Some(table_references)
1311 } else {
1312 None
1313 };
1314
1315 let where_ = if let Some(span) = parser.skip_keyword(Keyword::WHERE) {
1317 Some((parse_expression_unreserved(parser, PRIORITY_MAX)?, span))
1318 } else {
1319 None
1320 };
1321
1322 let group_by = if let Some(group_span) = parser.skip_keyword(Keyword::GROUP) {
1323 let span = parser.consume_keyword(Keyword::BY)?.join_span(&group_span);
1324 let mut groups = Vec::new();
1325 loop {
1326 groups.push(parse_expression_unreserved(parser, PRIORITY_MAX)?);
1327 if parser.skip_token(Token::Comma).is_none() {
1328 break;
1329 }
1330 }
1331 Some((span, groups))
1333 } else {
1334 None
1335 };
1336
1337 let having = if let Some(span) = parser.skip_keyword(Keyword::HAVING) {
1338 Some((parse_expression_unreserved(parser, PRIORITY_MAX)?, span))
1339 } else {
1340 None
1341 };
1342
1343 let window_span = parser.skip_keyword(Keyword::WINDOW);
1344 if window_span.is_some() {
1345 }
1347
1348 let order_by = if let Some(span) = parser.skip_keyword(Keyword::ORDER) {
1349 let span = parser.consume_keyword(Keyword::BY)?.join_span(&span);
1350 let mut order = Vec::new();
1351 loop {
1352 let e = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1353 let dir_span_opt = match &parser.token {
1354 Token::Ident(_, Keyword::ASC) => Some((true, parser.consume())),
1355 Token::Ident(_, Keyword::DESC) => Some((false, parser.consume())),
1356 _ => None,
1357 };
1358 let f = if let Some(nulls_span) = parser.skip_keyword(Keyword::NULLS) {
1359 match &parser.token {
1360 Token::Ident(_, Keyword::FIRST) => {
1361 let s = parser.consume().join_span(&nulls_span);
1362 parser.postgres_only(&s);
1363 match dir_span_opt {
1364 Some((true, _)) => OrderFlag::AscNullsFirst(s),
1365 Some((false, _)) => OrderFlag::DescNullsFirst(s),
1366 None => OrderFlag::NullsFirst(s),
1367 }
1368 }
1369 Token::Ident(_, Keyword::LAST) => {
1370 let s = parser.consume().join_span(&nulls_span);
1371 parser.postgres_only(&s);
1372 match dir_span_opt {
1373 Some((true, _)) => OrderFlag::AscNullsLast(s),
1374 Some((false, _)) => OrderFlag::DescNullsLast(s),
1375 None => OrderFlag::NullsLast(s),
1376 }
1377 }
1378 _ => parser.expected_failure("FIRST or LAST")?,
1379 }
1380 } else {
1381 match dir_span_opt {
1382 Some((true, s)) => OrderFlag::Asc(s),
1383 Some((false, s)) => OrderFlag::Desc(s),
1384 None => OrderFlag::None,
1385 }
1386 };
1387 order.push((e, f));
1388 if parser.skip_token(Token::Comma).is_none() {
1389 break;
1390 }
1391 }
1392 Some((span, order))
1393 } else {
1394 None
1395 };
1396
1397 let limit = if let Some(span) = parser.skip_keyword(Keyword::LIMIT) {
1398 let n = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1399 match parser.token {
1400 Token::Comma => {
1401 parser.consume();
1402 Some((
1403 span,
1404 Some(n),
1405 parse_expression_unreserved(parser, PRIORITY_MAX)?,
1406 ))
1407 }
1408 Token::Ident(_, Keyword::OFFSET) => {
1409 parser.consume();
1410 Some((
1411 span,
1412 Some(parse_expression_unreserved(parser, PRIORITY_MAX)?),
1413 n,
1414 ))
1415 }
1416 _ => Some((span, None, n)),
1417 }
1418 } else {
1419 None
1420 };
1421
1422 let offset = if limit.is_none() {
1424 if let Some(offset_span) = parser.skip_keyword(Keyword::OFFSET) {
1425 parser.postgres_only(&offset_span);
1426 let n = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1427 if matches!(parser.token, Token::Ident(_, Keyword::ROWS | Keyword::ROW)) {
1429 parser.consume();
1430 }
1431 Some((offset_span, n))
1432 } else {
1433 None
1434 }
1435 } else {
1436 None
1437 };
1438
1439 let fetch = if let Some(fetch_span) = parser.skip_keyword(Keyword::FETCH) {
1441 parser.postgres_only(&fetch_span);
1442 match &parser.token {
1443 Token::Ident(_, Keyword::FIRST | Keyword::NEXT) => {
1444 parser.consume();
1445 }
1446 _ => parser.expected_failure("FIRST or NEXT")?,
1447 }
1448 let n = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1449 if matches!(parser.token, Token::Ident(_, Keyword::ROWS | Keyword::ROW)) {
1450 parser.consume();
1451 }
1452 parser.consume_keyword(Keyword::ONLY)?;
1453 Some((fetch_span, n))
1454 } else {
1455 None
1456 };
1457
1458 let locking = if let Some(for_span) = parser.skip_keyword(Keyword::FOR) {
1459 let strength = match &parser.token {
1460 Token::Ident(_, Keyword::UPDATE) => {
1461 LockStrength::Update(parser.consume_keyword(Keyword::UPDATE)?)
1462 }
1463 Token::Ident(_, Keyword::SHARE) => {
1464 LockStrength::Share(parser.consume_keyword(Keyword::SHARE)?)
1465 }
1466 Token::Ident(_, Keyword::NO) => {
1467 LockStrength::NoKeyUpdate(parser.consume_keywords(&[
1468 Keyword::NO,
1469 Keyword::KEY,
1470 Keyword::UPDATE,
1471 ])?)
1472 }
1473 Token::Ident(_, Keyword::KEY) => {
1474 LockStrength::KeyShare(parser.consume_keywords(&[Keyword::KEY, Keyword::SHARE])?)
1475 }
1476 _ => parser.expected_failure("UPDATE, SHARE, NO KEY UPDATE or KEY SHARE here")?,
1477 };
1478
1479 if let LockStrength::NoKeyUpdate(s) | LockStrength::KeyShare(s) = &strength
1480 && !parser.options.dialect.is_postgresql()
1481 {
1482 parser.err("Only support by PostgreSQL", s);
1483 }
1484
1485 let of = if let Some(of_span) = parser.skip_keyword(Keyword::OF) {
1486 let mut table_references = Vec::new();
1487 loop {
1488 table_references.push(parser.consume_plain_identifier_unreserved()?);
1489 if parser.skip_token(Token::Comma).is_none() {
1490 break;
1491 }
1492 }
1493 Some((of_span, table_references))
1494 } else {
1495 None
1496 };
1497
1498 let wait = match &parser.token {
1499 Token::Ident(_, Keyword::NOWAIT) => {
1500 LockWait::NoWait(parser.consume_keyword(Keyword::NOWAIT)?)
1501 }
1502 Token::Ident(_, Keyword::SKIP) => {
1503 LockWait::SkipLocket(parser.consume_keywords(&[Keyword::SKIP, Keyword::LOCKED])?)
1504 }
1505 _ => LockWait::Default,
1506 };
1507 Some(Locking {
1508 for_span,
1509 strength,
1510 of,
1511 wait,
1512 })
1513 } else {
1514 None
1515 };
1516
1517 Ok(Select {
1529 select_span,
1530 flags,
1531 select_exprs,
1532 from_span,
1533 table_references,
1534 where_,
1535 group_by,
1536 having,
1537 window_span,
1538 order_by,
1539 limit,
1540 distinct_on,
1541 offset,
1542 fetch,
1543 locking,
1544 })
1545}