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 base_restrict = parser.reserved() | additional_restrict;
714 let as_ = if as_span.is_some()
715 || (matches!(&parser.token, Token::Ident(_, k) if !k.restricted(base_restrict | Restrict::FROM_ALIAS)))
716 {
717 Some(parser.consume_plain_identifier_restrict(base_restrict)?)
718 } else {
719 None
720 };
721
722 let mut index_hints = Vec::new();
723 loop {
724 let use_ = match parser.token {
725 Token::Ident(_, Keyword::USE) => IndexHintUse::Use(parser.consume()),
726 Token::Ident(_, Keyword::IGNORE) => IndexHintUse::Ignore(parser.consume()),
727 Token::Ident(_, Keyword::FORCE) => IndexHintUse::Force(parser.consume()),
728 _ => break,
729 };
730 let type_ = match parser.token {
731 Token::Ident(_, Keyword::INDEX) => IndexHintType::Index(parser.consume()),
732 Token::Ident(_, Keyword::KEY) => IndexHintType::Key(parser.consume()),
733 _ => parser.expected_failure("'INDEX' or 'KEY'")?,
734 };
735 let for_ = if let Some(for_span) = parser.skip_keyword(Keyword::FOR) {
736 let v = match parser.token {
737 Token::Ident(_, Keyword::JOIN) => IndexHintFor::Join(parser.consume()),
738 Token::Ident(_, Keyword::GROUP) => {
739 IndexHintFor::GroupBy(parser.consume_keywords(&[Keyword::GROUP, Keyword::BY])?)
740 }
741 Token::Ident(_, Keyword::ORDER) => {
742 IndexHintFor::OrderBy(parser.consume_keywords(&[Keyword::ORDER, Keyword::BY])?)
743 }
744 _ => parser.expected_failure("'JOIN', 'GROUP BY' or 'ORDER BY'")?,
745 };
746 Some((for_span, v))
747 } else {
748 None
749 };
750 let lparen = parser.consume_token(Token::LParen)?;
751 let mut index_list = Vec::new();
752 loop {
753 parser.recovered(
754 "')' or ','",
755 &|t| matches!(t, Token::RParen | Token::Comma),
756 |parser| {
757 index_list.push(parser.consume_plain_identifier_unreserved()?);
758 Ok(())
759 },
760 )?;
761 if matches!(parser.token, Token::RParen) {
762 break;
763 }
764 parser.consume_token(Token::Comma)?;
765 }
766 let rparen = parser.consume_token(Token::RParen)?;
767 index_hints.push(IndexHint {
768 use_,
769 type_,
770 for_,
771 lparen,
772 index_list,
773 rparen,
774 })
775 }
776
777 if !index_hints.is_empty() && !parser.options.dialect.is_maria() {
778 parser.err(
779 "Index hints only supported by MariaDb",
780 &index_hints.opt_span().unwrap(),
781 );
782 }
783
784 Ok(TableReference::Table {
785 identifier,
786 as_span,
787 as_,
788 index_hints,
789 })
790}
791
792fn parse_json_table_columns<'a>(
793 parser: &mut Parser<'a, '_>,
794) -> Result<Vec<JsonTableColumn<'a>>, ParseError> {
795 let mut columns = Vec::new();
796
797 loop {
798 if let Some(nested_span) = parser.skip_keyword(Keyword::NESTED) {
800 let path_span = parser.consume_keyword(Keyword::PATH)?;
801 let path = match &parser.token {
802 Token::String(s, _) => {
803 let val = *s;
804 let span = parser.consume();
805 Expression::String(Box::new(SString::new(Cow::Borrowed(val), span)))
806 }
807 _ => parse_expression_unreserved(parser, PRIORITY_MAX)?,
808 };
809 let columns_span = parser.consume_keyword(Keyword::COLUMNS)?;
810 parser.consume_token(Token::LParen)?;
811 let nested_columns = parser.recovered(")", &|t| t == &Token::RParen, |parser| {
812 parse_json_table_columns(parser)
813 })?;
814 parser.consume_token(Token::RParen)?;
815
816 columns.push(JsonTableColumn::Nested {
817 nested_span,
818 path_span,
819 path,
820 columns_span,
821 columns: nested_columns,
822 });
823 } else {
824 let name = parser.consume_plain_identifier_unreserved()?;
826
827 if let Some(for_span) = parser.skip_keyword(Keyword::FOR) {
829 let ordinality_span = parser.consume_keyword(Keyword::ORDINALITY)?;
830 let for_ordinality_span = for_span.join_span(&ordinality_span);
831
832 columns.push(JsonTableColumn::Ordinality {
833 name,
834 for_ordinality_span,
835 });
836 } else {
837 let data_type = parse_data_type(parser, DataTypeContext::FunctionReturn)?;
839
840 let _ = parser.skip_keyword(Keyword::EXISTS);
842
843 let path_span = parser.consume_keyword(Keyword::PATH)?;
845 let path = match &parser.token {
846 Token::String(s, _) => {
847 let val = *s;
848 let span = parser.consume();
849 Expression::String(Box::new(SString::new(Cow::Borrowed(val), span)))
850 }
851 _ => parse_expression_unreserved(parser, PRIORITY_MAX)?,
852 };
853
854 let mut on_empty = None;
857 let mut on_error = None;
858
859 loop {
860 let behavior_start = parser.span.span().start;
861 let behavior = match &parser.token {
862 Token::Ident(_, Keyword::DEFAULT) => {
863 parser.consume();
864 let default_val = parse_expression_unreserved(parser, PRIORITY_MAX)?;
866 Some(JsonTableOnErrorEmpty::Default(default_val))
867 }
868 Token::Ident(_, Keyword::ERROR) => {
869 let error_span = parser.consume();
870 Some(JsonTableOnErrorEmpty::Error(error_span))
871 }
872 Token::Ident(_, Keyword::NULL) => {
873 let null_span = parser.consume();
874 Some(JsonTableOnErrorEmpty::Null(null_span))
875 }
876 _ => None,
877 };
878
879 if let Some(behavior) = behavior {
880 parser.consume_keyword(Keyword::ON)?;
881 let clause_end = parser.span.span().end;
882 match &parser.token {
883 Token::Ident(_, Keyword::EMPTY) => {
884 parser.consume();
885 let span = behavior_start..clause_end;
886 on_empty = Some((behavior, span));
887 }
888 Token::Ident(_, Keyword::ERROR) => {
889 parser.consume();
890 let span = behavior_start..clause_end;
891 on_error = Some((behavior, span));
892 }
893 _ => {
894 parser.expected_failure("EMPTY or ERROR")?;
896 }
897 }
898 } else {
899 break;
901 }
902 }
903
904 columns.push(JsonTableColumn::Column {
905 name,
906 data_type,
907 path_span,
908 path,
909 on_empty,
910 on_error,
911 });
912 }
913 }
914
915 if parser.skip_token(Token::Comma).is_none() {
917 break;
918 }
919
920 if matches!(parser.token, Token::RParen) {
922 break;
923 }
924 }
925
926 Ok(columns)
927}
928
929pub(crate) fn parse_table_reference<'a>(
930 parser: &mut Parser<'a, '_>,
931 additional_restrict: crate::keywords::Restrict,
932) -> Result<TableReference<'a>, ParseError> {
933 let mut ans = parse_table_reference_inner(parser, additional_restrict)?;
934 loop {
935 let join = match parser.token {
936 Token::Ident(_, Keyword::FULL) => {
937 let full = parser.consume_keyword(Keyword::FULL)?;
938 parser.postgres_only(&full);
939 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
940 JoinType::FullOuter(
941 full.join_span(&outer)
942 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
943 )
944 } else {
945 JoinType::FullOuter(full.join_span(&parser.consume_keyword(Keyword::JOIN)?))
946 }
947 }
948 Token::Ident(_, Keyword::INNER) => JoinType::Inner(
949 parser
950 .consume_keyword(Keyword::INNER)?
951 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
952 ),
953 Token::Ident(_, Keyword::CROSS) => JoinType::Cross(
954 parser
955 .consume_keyword(Keyword::CROSS)?
956 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
957 ),
958 Token::Ident(_, Keyword::JOIN) => {
959 JoinType::Normal(parser.consume_keyword(Keyword::JOIN)?)
960 }
961 Token::Ident(_, Keyword::STRAIGHT_JOIN) => {
962 JoinType::Straight(parser.consume_keyword(Keyword::STRAIGHT_JOIN)?)
963 }
964 Token::Ident(_, Keyword::LEFT) => {
965 let left = parser.consume_keyword(Keyword::LEFT)?;
966 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
967 JoinType::Left(
968 left.join_span(&outer)
969 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
970 )
971 } else {
972 JoinType::Left(left.join_span(&parser.consume_keyword(Keyword::JOIN)?))
973 }
974 }
975 Token::Ident(_, Keyword::RIGHT) => {
976 let right = parser.consume_keyword(Keyword::RIGHT)?;
977 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
978 JoinType::Right(
979 right
980 .join_span(&outer)
981 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
982 )
983 } else {
984 JoinType::Right(right.join_span(&parser.consume_keyword(Keyword::JOIN)?))
985 }
986 }
987 Token::Ident(_, Keyword::NATURAL) => {
988 let natural = parser.consume_keyword(Keyword::NATURAL)?;
989 match &parser.token {
990 Token::Ident(_, Keyword::INNER) => JoinType::NaturalInner(
991 natural
992 .join_span(&parser.consume_keywords(&[Keyword::INNER, Keyword::JOIN])?),
993 ),
994 Token::Ident(_, Keyword::LEFT) => {
995 let left = parser.consume_keyword(Keyword::LEFT)?;
996 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
997 JoinType::NaturalLeft(
998 left.join_span(&outer)
999 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
1000 )
1001 } else {
1002 JoinType::NaturalLeft(
1003 left.join_span(&parser.consume_keyword(Keyword::JOIN)?),
1004 )
1005 }
1006 }
1007 Token::Ident(_, Keyword::RIGHT) => {
1008 let right = parser.consume_keyword(Keyword::RIGHT)?;
1009 if let Some(outer) = parser.skip_keyword(Keyword::OUTER) {
1010 JoinType::NaturalRight(
1011 right
1012 .join_span(&outer)
1013 .join_span(&parser.consume_keyword(Keyword::JOIN)?),
1014 )
1015 } else {
1016 JoinType::NaturalRight(
1017 right.join_span(&parser.consume_keyword(Keyword::JOIN)?),
1018 )
1019 }
1020 }
1021 Token::Ident(_, Keyword::JOIN) => JoinType::Natural(
1022 natural.join_span(&parser.consume_keyword(Keyword::JOIN)?),
1023 ),
1024 _ => parser.expected_failure("'INNER', 'LEFT', 'RIGHT' or 'JOIN'")?,
1025 }
1026 }
1027 _ => break,
1028 };
1029
1030 let right = parse_table_reference_inner(parser, additional_restrict)?;
1031
1032 let specification = match &parser.token {
1033 Token::Ident(_, Keyword::ON) => {
1034 let on = parser.consume_keyword(Keyword::ON)?;
1035 let expr = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1036 Some(JoinSpecification::On(expr, on))
1037 }
1038 Token::Ident(_, Keyword::USING) => {
1039 let using = parser.consume_keyword(Keyword::USING)?;
1040 let mut join_column_list = Vec::new();
1041 loop {
1042 join_column_list.push(parser.consume_plain_identifier_unreserved()?);
1043 if parser.skip_token(Token::Comma).is_none() {
1044 break;
1045 }
1046 }
1047 Some(JoinSpecification::Using(join_column_list, using))
1048 }
1049 _ => None,
1050 };
1051
1052 ans = TableReference::Join {
1053 join,
1054 left: Box::new(ans),
1055 right: Box::new(right),
1056 specification,
1057 };
1058 }
1059 Ok(ans)
1060}
1061
1062#[derive(Debug, Clone)]
1064pub enum SelectFlag {
1065 All(Span),
1066 Distinct(Span),
1067 DistinctOn(Span),
1068 DistinctRow(Span),
1069 HighPriority(Span),
1070 StraightJoin(Span),
1071 SqlSmallResult(Span),
1072 SqlBigResult(Span),
1073 SqlBufferResult(Span),
1074 SqlNoCache(Span),
1075 SqlCalcFoundRows(Span),
1076}
1077
1078impl Spanned for SelectFlag {
1079 fn span(&self) -> Span {
1080 match &self {
1081 SelectFlag::All(v) => v.span(),
1082 SelectFlag::Distinct(v) => v.span(),
1083 SelectFlag::DistinctOn(v) => v.span(),
1084 SelectFlag::DistinctRow(v) => v.span(),
1085 SelectFlag::HighPriority(v) => v.span(),
1086 SelectFlag::StraightJoin(v) => v.span(),
1087 SelectFlag::SqlSmallResult(v) => v.span(),
1088 SelectFlag::SqlBigResult(v) => v.span(),
1089 SelectFlag::SqlBufferResult(v) => v.span(),
1090 SelectFlag::SqlNoCache(v) => v.span(),
1091 SelectFlag::SqlCalcFoundRows(v) => v.span(),
1092 }
1093 }
1094}
1095
1096#[derive(Debug, Clone)]
1098pub enum OrderFlag {
1099 Asc(Span),
1100 Desc(Span),
1101 AscNullsFirst(Span),
1102 AscNullsLast(Span),
1103 DescNullsFirst(Span),
1104 DescNullsLast(Span),
1105 NullsFirst(Span),
1106 NullsLast(Span),
1107 None,
1108}
1109impl OptSpanned for OrderFlag {
1110 fn opt_span(&self) -> Option<Span> {
1111 match &self {
1112 OrderFlag::Asc(v) => v.opt_span(),
1113 OrderFlag::Desc(v) => v.opt_span(),
1114 OrderFlag::AscNullsFirst(v) => v.opt_span(),
1115 OrderFlag::AscNullsLast(v) => v.opt_span(),
1116 OrderFlag::DescNullsFirst(v) => v.opt_span(),
1117 OrderFlag::DescNullsLast(v) => v.opt_span(),
1118 OrderFlag::NullsFirst(v) => v.opt_span(),
1119 OrderFlag::NullsLast(v) => v.opt_span(),
1120 OrderFlag::None => None,
1121 }
1122 }
1123}
1124
1125#[derive(Debug, Clone)]
1127pub enum LockStrength {
1128 Update(Span),
1129 Share(Span),
1130 NoKeyUpdate(Span),
1131 KeyShare(Span),
1132}
1133impl Spanned for LockStrength {
1134 fn span(&self) -> Span {
1135 match &self {
1136 LockStrength::Update(v) => v.span(),
1137 LockStrength::Share(v) => v.span(),
1138 LockStrength::NoKeyUpdate(v) => v.span(),
1139 LockStrength::KeyShare(v) => v.span(),
1140 }
1141 }
1142}
1143
1144#[derive(Debug, Clone)]
1145pub enum LockWait {
1146 NoWait(Span),
1147 SkipLocket(Span),
1148 Default,
1149}
1150impl OptSpanned for LockWait {
1151 fn opt_span(&self) -> Option<Span> {
1152 match &self {
1153 LockWait::NoWait(v) => v.opt_span(),
1154 LockWait::SkipLocket(v) => v.opt_span(),
1155 LockWait::Default => None,
1156 }
1157 }
1158}
1159
1160#[derive(Debug, Clone)]
1161pub struct Locking<'a> {
1162 pub for_span: Span,
1164 pub strength: LockStrength,
1165 pub of: Option<(Span, Vec<Identifier<'a>>)>,
1166 pub wait: LockWait,
1167}
1168impl<'a> Spanned for Locking<'a> {
1169 fn span(&self) -> Span {
1170 self.for_span
1171 .join_span(&self.strength)
1172 .join_span(&self.of)
1173 .join_span(&self.wait)
1174 }
1175}
1176
1177#[derive(Debug, Clone)]
1219pub struct Select<'a> {
1220 pub select_span: Span,
1222 pub flags: Vec<SelectFlag>,
1224 pub select_exprs: Vec<SelectExpr<'a>>,
1226 pub from_span: Option<Span>,
1228 pub table_references: Option<Vec<TableReference<'a>>>,
1230 pub where_: Option<(Expression<'a>, Span)>,
1232 pub group_by: Option<(Span, Vec<Expression<'a>>)>,
1234 pub having: Option<(Expression<'a>, Span)>,
1236 pub window_span: Option<Span>,
1238 pub order_by: Option<(Span, Vec<(Expression<'a>, OrderFlag)>)>,
1240 pub limit: Option<(Span, Option<Expression<'a>>, Expression<'a>)>,
1242 pub distinct_on: Option<(Span, Vec<Expression<'a>>)>,
1244 pub offset: Option<(Span, Expression<'a>)>,
1246 pub fetch: Option<(Span, Expression<'a>)>,
1248 pub locking: Option<Locking<'a>>,
1250}
1251
1252impl<'a> Spanned for Select<'a> {
1253 fn span(&self) -> Span {
1254 self.select_span
1255 .join_span(&self.flags)
1256 .join_span(&self.select_exprs)
1257 .join_span(&self.from_span)
1258 .join_span(&self.table_references)
1259 .join_span(&self.where_)
1260 .join_span(&self.group_by)
1261 .join_span(&self.having)
1262 .join_span(&self.window_span)
1263 .join_span(&self.order_by)
1264 .join_span(&self.limit)
1265 .join_span(&self.distinct_on)
1266 .join_span(&self.offset)
1267 .join_span(&self.fetch)
1268 .join_span(&self.locking)
1269 }
1270}
1271
1272pub(crate) fn parse_select_body<'a>(
1275 parser: &mut Parser<'a, '_>,
1276 select_span: Span,
1277) -> Result<Select<'a>, ParseError> {
1278 let mut flags = Vec::new();
1279 let mut select_exprs = Vec::new();
1280
1281 loop {
1282 match &parser.token {
1283 Token::Ident(_, Keyword::ALL) => {
1284 flags.push(SelectFlag::All(parser.consume_keyword(Keyword::ALL)?))
1285 }
1286 Token::Ident(_, Keyword::DISTINCT) => {
1287 let distinct_span = parser.consume_keyword(Keyword::DISTINCT)?;
1288 if matches!(parser.token, Token::Ident(_, Keyword::ON)) {
1290 flags.push(SelectFlag::DistinctOn(distinct_span));
1291 } else {
1292 flags.push(SelectFlag::Distinct(distinct_span));
1293 }
1294 }
1295 Token::Ident(_, Keyword::DISTINCTROW) => flags.push(SelectFlag::DistinctRow(
1296 parser.consume_keyword(Keyword::DISTINCTROW)?,
1297 )),
1298 Token::Ident(_, Keyword::HIGH_PRIORITY) => flags.push(SelectFlag::HighPriority(
1299 parser.consume_keyword(Keyword::HIGH_PRIORITY)?,
1300 )),
1301 Token::Ident(_, Keyword::STRAIGHT_JOIN) => flags.push(SelectFlag::StraightJoin(
1302 parser.consume_keyword(Keyword::STRAIGHT_JOIN)?,
1303 )),
1304 Token::Ident(_, Keyword::SQL_SMALL_RESULT) => flags.push(SelectFlag::SqlSmallResult(
1305 parser.consume_keyword(Keyword::SQL_SMALL_RESULT)?,
1306 )),
1307 Token::Ident(_, Keyword::SQL_BIG_RESULT) => flags.push(SelectFlag::SqlBigResult(
1308 parser.consume_keyword(Keyword::SQL_BIG_RESULT)?,
1309 )),
1310 Token::Ident(_, Keyword::SQL_BUFFER_RESULT) => flags.push(SelectFlag::SqlBufferResult(
1311 parser.consume_keyword(Keyword::SQL_BUFFER_RESULT)?,
1312 )),
1313 Token::Ident(_, Keyword::SQL_NO_CACHE) => flags.push(SelectFlag::SqlNoCache(
1314 parser.consume_keyword(Keyword::SQL_NO_CACHE)?,
1315 )),
1316 Token::Ident(_, Keyword::SQL_CALC_FOUND_ROWS) => flags.push(
1317 SelectFlag::SqlCalcFoundRows(parser.consume_keyword(Keyword::SQL_CALC_FOUND_ROWS)?),
1318 ),
1319 _ => break,
1320 }
1321 }
1322
1323 let distinct_on = if flags
1325 .last()
1326 .is_some_and(|f| matches!(f, SelectFlag::DistinctOn(_)))
1327 {
1328 let on_span = parser.consume_keyword(Keyword::ON)?;
1329 parser.postgres_only(&on_span);
1330 parser.consume_token(Token::LParen)?;
1331 let mut exprs = Vec::new();
1332 loop {
1333 parser.recovered(
1334 "')' or ','",
1335 &|t| matches!(t, Token::RParen | Token::Comma),
1336 |parser| {
1337 exprs.push(parse_expression_unreserved(parser, PRIORITY_MAX)?);
1338 Ok(())
1339 },
1340 )?;
1341 if parser.skip_token(Token::Comma).is_none() {
1342 break;
1343 }
1344 }
1345 parser.consume_token(Token::RParen)?;
1346 Some((on_span, exprs))
1347 } else {
1348 None
1349 };
1350
1351 loop {
1352 select_exprs.push(parse_select_expr(parser)?);
1353 if parser.skip_token(Token::Comma).is_none() {
1354 break;
1355 }
1356 }
1357
1358 let from_span = parser.skip_keyword(Keyword::FROM);
1361
1362 let table_references = if from_span.is_some() {
1363 let mut table_references = Vec::new();
1364 loop {
1365 table_references.push(parse_table_reference(parser, Restrict::EMPTY)?);
1366 if parser.skip_token(Token::Comma).is_none() {
1367 break;
1368 }
1369 }
1370 Some(table_references)
1371 } else {
1372 None
1373 };
1374
1375 let where_ = if let Some(span) = parser.skip_keyword(Keyword::WHERE) {
1377 Some((parse_expression_unreserved(parser, PRIORITY_MAX)?, span))
1378 } else {
1379 None
1380 };
1381
1382 let group_by = if let Some(group_span) = parser.skip_keyword(Keyword::GROUP) {
1383 let span = parser.consume_keyword(Keyword::BY)?.join_span(&group_span);
1384 let mut groups = Vec::new();
1385 loop {
1386 groups.push(parse_expression_unreserved(parser, PRIORITY_MAX)?);
1387 if parser.skip_token(Token::Comma).is_none() {
1388 break;
1389 }
1390 }
1391 Some((span, groups))
1393 } else {
1394 None
1395 };
1396
1397 let having = if let Some(span) = parser.skip_keyword(Keyword::HAVING) {
1398 Some((parse_expression_unreserved(parser, PRIORITY_MAX)?, span))
1399 } else {
1400 None
1401 };
1402
1403 let window_span = parser.skip_keyword(Keyword::WINDOW);
1404 if window_span.is_some() {
1405 }
1407
1408 let order_by = if let Some(span) = parser.skip_keyword(Keyword::ORDER) {
1409 let span = parser.consume_keyword(Keyword::BY)?.join_span(&span);
1410 let mut order = Vec::new();
1411 loop {
1412 let e = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1413 let dir_span_opt = match &parser.token {
1414 Token::Ident(_, Keyword::ASC) => Some((true, parser.consume())),
1415 Token::Ident(_, Keyword::DESC) => Some((false, parser.consume())),
1416 _ => None,
1417 };
1418 let f = if let Some(nulls_span) = parser.skip_keyword(Keyword::NULLS) {
1419 match &parser.token {
1420 Token::Ident(_, Keyword::FIRST) => {
1421 let s = parser.consume().join_span(&nulls_span);
1422 parser.postgres_only(&s);
1423 match dir_span_opt {
1424 Some((true, _)) => OrderFlag::AscNullsFirst(s),
1425 Some((false, _)) => OrderFlag::DescNullsFirst(s),
1426 None => OrderFlag::NullsFirst(s),
1427 }
1428 }
1429 Token::Ident(_, Keyword::LAST) => {
1430 let s = parser.consume().join_span(&nulls_span);
1431 parser.postgres_only(&s);
1432 match dir_span_opt {
1433 Some((true, _)) => OrderFlag::AscNullsLast(s),
1434 Some((false, _)) => OrderFlag::DescNullsLast(s),
1435 None => OrderFlag::NullsLast(s),
1436 }
1437 }
1438 _ => parser.expected_failure("FIRST or LAST")?,
1439 }
1440 } else {
1441 match dir_span_opt {
1442 Some((true, s)) => OrderFlag::Asc(s),
1443 Some((false, s)) => OrderFlag::Desc(s),
1444 None => OrderFlag::None,
1445 }
1446 };
1447 order.push((e, f));
1448 if parser.skip_token(Token::Comma).is_none() {
1449 break;
1450 }
1451 }
1452 Some((span, order))
1453 } else {
1454 None
1455 };
1456
1457 let limit = if let Some(span) = parser.skip_keyword(Keyword::LIMIT) {
1458 let n = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1459 match parser.token {
1460 Token::Comma => {
1461 parser.consume();
1462 Some((
1463 span,
1464 Some(n),
1465 parse_expression_unreserved(parser, PRIORITY_MAX)?,
1466 ))
1467 }
1468 Token::Ident(_, Keyword::OFFSET) => {
1469 parser.consume();
1470 Some((
1471 span,
1472 Some(parse_expression_unreserved(parser, PRIORITY_MAX)?),
1473 n,
1474 ))
1475 }
1476 _ => Some((span, None, n)),
1477 }
1478 } else {
1479 None
1480 };
1481
1482 let offset = if limit.is_none() {
1484 if let Some(offset_span) = parser.skip_keyword(Keyword::OFFSET) {
1485 parser.postgres_only(&offset_span);
1486 let n = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1487 if matches!(parser.token, Token::Ident(_, Keyword::ROWS | Keyword::ROW)) {
1489 parser.consume();
1490 }
1491 Some((offset_span, n))
1492 } else {
1493 None
1494 }
1495 } else {
1496 None
1497 };
1498
1499 let fetch = if let Some(fetch_span) = parser.skip_keyword(Keyword::FETCH) {
1501 parser.postgres_only(&fetch_span);
1502 match &parser.token {
1503 Token::Ident(_, Keyword::FIRST | Keyword::NEXT) => {
1504 parser.consume();
1505 }
1506 _ => parser.expected_failure("FIRST or NEXT")?,
1507 }
1508 let n = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1509 if matches!(parser.token, Token::Ident(_, Keyword::ROWS | Keyword::ROW)) {
1510 parser.consume();
1511 }
1512 parser.consume_keyword(Keyword::ONLY)?;
1513 Some((fetch_span, n))
1514 } else {
1515 None
1516 };
1517
1518 let locking = if let Some(for_span) = parser.skip_keyword(Keyword::FOR) {
1519 let strength = match &parser.token {
1520 Token::Ident(_, Keyword::UPDATE) => {
1521 LockStrength::Update(parser.consume_keyword(Keyword::UPDATE)?)
1522 }
1523 Token::Ident(_, Keyword::SHARE) => {
1524 LockStrength::Share(parser.consume_keyword(Keyword::SHARE)?)
1525 }
1526 Token::Ident(_, Keyword::NO) => {
1527 LockStrength::NoKeyUpdate(parser.consume_keywords(&[
1528 Keyword::NO,
1529 Keyword::KEY,
1530 Keyword::UPDATE,
1531 ])?)
1532 }
1533 Token::Ident(_, Keyword::KEY) => {
1534 LockStrength::KeyShare(parser.consume_keywords(&[Keyword::KEY, Keyword::SHARE])?)
1535 }
1536 _ => parser.expected_failure("UPDATE, SHARE, NO KEY UPDATE or KEY SHARE here")?,
1537 };
1538
1539 if let LockStrength::NoKeyUpdate(s) | LockStrength::KeyShare(s) = &strength
1540 && !parser.options.dialect.is_postgresql()
1541 {
1542 parser.err("Only support by PostgreSQL", s);
1543 }
1544
1545 let of = if let Some(of_span) = parser.skip_keyword(Keyword::OF) {
1546 let mut table_references = Vec::new();
1547 loop {
1548 table_references.push(parser.consume_plain_identifier_unreserved()?);
1549 if parser.skip_token(Token::Comma).is_none() {
1550 break;
1551 }
1552 }
1553 Some((of_span, table_references))
1554 } else {
1555 None
1556 };
1557
1558 let wait = match &parser.token {
1559 Token::Ident(_, Keyword::NOWAIT) => {
1560 LockWait::NoWait(parser.consume_keyword(Keyword::NOWAIT)?)
1561 }
1562 Token::Ident(_, Keyword::SKIP) => {
1563 LockWait::SkipLocket(parser.consume_keywords(&[Keyword::SKIP, Keyword::LOCKED])?)
1564 }
1565 _ => LockWait::Default,
1566 };
1567 Some(Locking {
1568 for_span,
1569 strength,
1570 of,
1571 wait,
1572 })
1573 } else {
1574 None
1575 };
1576
1577 Ok(Select {
1589 select_span,
1590 flags,
1591 select_exprs,
1592 from_span,
1593 table_references,
1594 where_,
1595 group_by,
1596 having,
1597 window_span,
1598 order_by,
1599 limit,
1600 distinct_on,
1601 offset,
1602 fetch,
1603 locking,
1604 })
1605}
1606
1607pub(crate) fn parse_select<'a>(parser: &mut Parser<'a, '_>) -> Result<Select<'a>, ParseError> {
1608 let select_span = parser.consume_keyword(Keyword::SELECT)?;
1609 parse_select_body(parser, select_span)
1610}