1use crate::keywords::Keyword;
8use crate::lexer::Token;
9use crate::parser::{ParseError, Parser};
10use crate::{Expression, OptSpanned, Span, Spanned};
11use alloc::format;
12use alloc::vec::Vec;
13
14#[derive(Debug, Clone)]
16pub enum FetchDirection {
17 First(Span),
19 Next(Span),
21}
22
23impl Spanned for FetchDirection {
24 fn span(&self) -> Span {
25 match self {
26 FetchDirection::First(span) => span.clone(),
27 FetchDirection::Next(span) => span.clone(),
28 }
29 }
30}
31
32#[derive(Debug, Clone)]
34pub struct Fetch<'a> {
35 pub fetch_span: Span,
37 pub direction: Option<FetchDirection>,
39 pub count: Option<Expression<'a>>,
41 pub row_span: Span,
43}
44
45impl<'a> Spanned for Fetch<'a> {
47 fn span(&self) -> Span {
48 self.fetch_span
49 .join_span(&self.direction)
50 .join_span(&self.count)
51 .join_span(&self.row_span)
52 }
53}
54
55fn parse_fetch<'a>(parser: &mut Parser<'a, '_>, fetch_span: Span) -> Result<Fetch<'a>, ParseError> {
57 let direction = match &parser.token {
58 Token::Ident(_, Keyword::FIRST) => Some(FetchDirection::First(parser.consume())),
59 Token::Ident(_, Keyword::NEXT) => Some(FetchDirection::Next(parser.consume())),
60 _ => None,
61 };
62 let count = if !matches!(
63 &parser.token,
64 Token::Ident(_, Keyword::ROW | Keyword::ROWS | Keyword::ONLY)
65 ) {
66 Some(crate::expression::parse_expression_unreserved(
67 parser,
68 crate::expression::PRIORITY_MAX,
69 )?)
70 } else {
71 None
72 };
73 let row_span = match &parser.token {
75 Token::Ident(_, Keyword::ROW | Keyword::ROWS) => Some(parser.consume()),
76 _ => None,
77 };
78 let row_span = parser.consume_keyword(Keyword::ONLY)?.join_span(&row_span);
79 Ok(Fetch {
80 fetch_span,
81 direction,
82 count,
83 row_span,
84 })
85}
86
87#[derive(Debug, Clone)]
106pub struct Values<'a> {
107 pub values_span: Span,
108 pub rows: Vec<Vec<Expression<'a>>>,
109 pub order_by: Option<(Span, Vec<(Expression<'a>, crate::select::OrderFlag)>)>, pub limit: Option<(Span, Expression<'a>)>,
111 pub offset: Option<(Span, Expression<'a>)>,
112 pub fetch: Option<Fetch<'a>>,
113}
114
115impl<'a> Spanned for Values<'a> {
116 fn span(&self) -> Span {
117 self.values_span
118 .join_span(&self.rows)
119 .join_span(&self.order_by)
120 .join_span(&self.limit)
121 .join_span(&self.offset)
122 .join_span(&self.fetch)
123 }
124}
125
126pub(crate) fn parse_values<'a>(parser: &mut Parser<'a, '_>) -> Result<Values<'a>, ParseError> {
128 let values_span = parser.consume_keyword(Keyword::VALUES)?;
129 parser.postgres_only(&values_span);
130
131 let mut rows = Vec::new();
132 loop {
133 parser.consume_token(Token::LParen)?;
134 let mut row = Vec::new();
135 parser.recovered(
136 "')' or ','",
137 &|t| matches!(t, Token::RParen | Token::Comma),
138 |parser| {
139 loop {
140 row.push(crate::expression::parse_expression_unreserved(
141 parser,
142 crate::expression::PRIORITY_MAX,
143 )?);
144 if parser.skip_token(Token::Comma).is_none() {
145 break;
146 }
147 }
148 Ok(())
149 },
150 )?;
151 parser.consume_token(Token::RParen)?;
152 rows.push(row);
153 if parser.skip_token(Token::Comma).is_none() {
154 break;
155 }
156 }
157 if let Some(first_row) = rows.first() {
159 let cols = first_row.len();
160 for row in rows.iter() {
161 if row.len() != cols {
162 parser
163 .err(
164 format!("This row has {} members", row.len()),
165 &row.opt_span().unwrap(),
166 )
167 .frag(
168 format!("Expected {} members", cols),
169 &first_row.opt_span().unwrap(),
170 );
171 }
172 }
173 }
174
175 let order_by = if let Some(order_span) = parser.skip_keyword(Keyword::ORDER) {
177 let by_span = parser.consume_keyword(Keyword::BY)?;
178 let span = order_span.join_span(&by_span);
179 let mut items = Vec::new();
180 loop {
181 let expr = crate::expression::parse_expression_unreserved(
182 parser,
183 crate::expression::PRIORITY_MAX,
184 )?;
185 let order_flag = match &parser.token {
186 Token::Ident(_, Keyword::ASC) => crate::select::OrderFlag::Asc(parser.consume()),
187 Token::Ident(_, Keyword::DESC) => crate::select::OrderFlag::Desc(parser.consume()),
188 _ => crate::select::OrderFlag::None,
189 };
190 items.push((expr, order_flag));
191 if parser.skip_token(Token::Comma).is_none() {
192 break;
193 }
194 }
195 Some((span, items))
196 } else {
197 None
198 };
199
200 let limit = if let Some(limit_span) = parser.skip_keyword(Keyword::LIMIT) {
202 let expr = crate::expression::parse_expression_unreserved(
203 parser,
204 crate::expression::PRIORITY_MAX,
205 )?;
206 Some((limit_span, expr))
207 } else {
208 None
209 };
210
211 let offset = if let Some(offset_span) = parser.skip_keyword(Keyword::OFFSET) {
213 let expr = crate::expression::parse_expression_unreserved(
214 parser,
215 crate::expression::PRIORITY_MAX,
216 )?;
217 if matches!(parser.token, Token::Ident(_, Keyword::ROW | Keyword::ROWS)) {
219 parser.consume();
220 }
221 Some((offset_span, expr))
222 } else {
223 None
224 };
225
226 let fetch = if let Some(fetch_span) = parser.skip_keyword(Keyword::FETCH) {
228 Some(parse_fetch(parser, fetch_span)?)
229 } else {
230 None
231 };
232
233 Ok(Values {
234 values_span,
235 rows,
236 order_by,
237 limit,
238 offset,
239 fetch,
240 })
241}