1use alloc::vec::Vec;
13
14use crate::{
15 expression::{parse_expression, Expression},
16 keywords::Keyword,
17 lexer::Token,
18 parser::{ParseError, Parser},
19 qualified_name::parse_qualified_name,
20 select::{parse_select, parse_select_expr, Select, SelectExpr},
21 Identifier, OptSpanned, QualifiedName, Span, Spanned,
22};
23
24#[derive(Clone, Debug)]
26pub enum InsertReplaceFlag {
27 LowPriority(Span),
28 HighPriority(Span),
29 Delayed(Span),
30 Ignore(Span),
31}
32
33impl Spanned for InsertReplaceFlag {
34 fn span(&self) -> Span {
35 match &self {
36 InsertReplaceFlag::LowPriority(v) => v.span(),
37 InsertReplaceFlag::HighPriority(v) => v.span(),
38 InsertReplaceFlag::Delayed(v) => v.span(),
39 InsertReplaceFlag::Ignore(v) => v.span(),
40 }
41 }
42}
43
44#[derive(Clone, Debug)]
45pub enum InsertReplaceType {
46 Insert(Span),
47 Replace(Span),
48}
49
50impl Spanned for InsertReplaceType {
51 fn span(&self) -> Span {
52 match self {
53 InsertReplaceType::Insert(a) => a.clone(),
54 InsertReplaceType::Replace(a) => a.clone(),
55 }
56 }
57}
58
59#[derive(Clone, Debug)]
60pub enum OnConflictTarget<'a> {
61 Columns {
62 names: Vec<Identifier<'a>>,
63 },
64 OnConstraint {
65 on_constraint_span: Span,
66 name: Identifier<'a>,
67 },
68 None,
69}
70
71impl<'a> OptSpanned for OnConflictTarget<'a> {
72 fn opt_span(&self) -> Option<Span> {
73 match self {
74 OnConflictTarget::Columns { names } => names.opt_span(),
75 OnConflictTarget::OnConstraint {
76 on_constraint_span: token,
77 name,
78 } => Some(token.join_span(name)),
79 OnConflictTarget::None => None,
80 }
81 }
82}
83
84#[derive(Clone, Debug)]
85pub enum OnConflictAction<'a> {
86 DoNothing(Span),
87 DoUpdateSet {
88 do_update_set_span: Span,
89 sets: Vec<(Identifier<'a>, Expression<'a>)>,
90 where_: Option<(Span, alloc::boxed::Box<Expression<'a>>)>,
91 },
92}
93
94impl<'a> Spanned for OnConflictAction<'a> {
95 fn span(&self) -> Span {
96 match self {
97 OnConflictAction::DoNothing(span) => span.span(),
98 OnConflictAction::DoUpdateSet {
99 do_update_set_span,
100 sets,
101 where_,
102 } => do_update_set_span.join_span(sets).join_span(where_),
103 }
104 }
105}
106
107#[derive(Clone, Debug)]
108pub struct OnConflict<'a> {
109 pub on_conflict_span: Span,
110 pub target: OnConflictTarget<'a>,
111 pub action: OnConflictAction<'a>,
112}
113
114impl<'a> Spanned for OnConflict<'a> {
115 fn span(&self) -> Span {
116 self.on_conflict_span
117 .join_span(&self.target)
118 .join_span(&self.action)
119 }
120}
121
122#[derive(Clone, Debug)]
123pub struct InsertReplaceSetPair<'a> {
124 pub column: Identifier<'a>,
125 pub equal_span: Span,
126 pub value: Expression<'a>,
127}
128
129impl<'a> Spanned for InsertReplaceSetPair<'a> {
130 fn span(&self) -> Span {
131 self.column
132 .join_span(&self.equal_span)
133 .join_span(&self.value)
134 }
135}
136
137#[derive(Clone, Debug)]
138pub struct InsertReplaceSet<'a> {
139 pub set_span: Span,
140 pub pairs: Vec<InsertReplaceSetPair<'a>>,
141}
142
143impl<'a> Spanned for InsertReplaceSet<'a> {
144 fn span(&self) -> Span {
145 self.set_span.join_span(&self.pairs)
146 }
147}
148
149#[derive(Clone, Debug)]
150pub struct InsertReplaceOnDuplicateKeyUpdate<'a> {
151 pub on_duplicate_key_update_span: Span,
152 pub pairs: Vec<InsertReplaceSetPair<'a>>,
153}
154
155impl<'a> Spanned for InsertReplaceOnDuplicateKeyUpdate<'a> {
156 fn span(&self) -> Span {
157 self.on_duplicate_key_update_span.join_span(&self.pairs)
158 }
159}
160
161#[derive(Clone, Debug)]
220pub struct InsertReplace<'a> {
221 pub type_: InsertReplaceType,
223 pub flags: Vec<InsertReplaceFlag>,
225 pub into_span: Option<Span>,
227 pub table: QualifiedName<'a>,
229 pub columns: Vec<Identifier<'a>>,
231 pub values: Option<(Span, Vec<Vec<Expression<'a>>>)>,
233 pub select: Option<Select<'a>>,
235 pub set: Option<InsertReplaceSet<'a>>,
237 pub on_duplicate_key_update: Option<InsertReplaceOnDuplicateKeyUpdate<'a>>,
239 pub on_conflict: Option<OnConflict<'a>>,
241 pub returning: Option<(Span, Vec<SelectExpr<'a>>)>,
243}
244
245impl<'a> Spanned for InsertReplace<'a> {
246 fn span(&self) -> Span {
247 self.type_
248 .join_span(&self.flags)
249 .join_span(&self.into_span)
250 .join_span(&self.table)
251 .join_span(&self.values)
252 .join_span(&self.select)
253 .join_span(&self.set)
254 .join_span(&self.on_duplicate_key_update)
255 .join_span(&self.on_conflict)
256 .join_span(&self.returning)
257 }
258}
259
260pub(crate) fn parse_insert_replace<'a>(
261 parser: &mut Parser<'a, '_>,
262) -> Result<InsertReplace<'a>, ParseError> {
263 let type_ = match &parser.token {
264 Token::Ident(_, Keyword::INSERT) => InsertReplaceType::Insert(parser.consume()),
265 Token::Ident(_, Keyword::REPLACE) => InsertReplaceType::Replace(parser.consume()),
266 _ => parser.expected_failure("INSERT or REPLACE")?,
267 };
268
269 let insert = matches!(type_, InsertReplaceType::Insert(_));
270
271 let mut flags = Vec::new();
272 loop {
273 match &parser.token {
274 Token::Ident(_, Keyword::LOW_PRIORITY) => flags.push(InsertReplaceFlag::LowPriority(
275 parser.consume_keyword(Keyword::LOW_PRIORITY)?,
276 )),
277 Token::Ident(_, Keyword::HIGH_PRIORITY) => flags.push(InsertReplaceFlag::HighPriority(
278 parser.consume_keyword(Keyword::HIGH_PRIORITY)?,
279 )),
280 Token::Ident(_, Keyword::DELAYED) => flags.push(InsertReplaceFlag::Delayed(
281 parser.consume_keyword(Keyword::DELAYED)?,
282 )),
283 Token::Ident(_, Keyword::IGNORE) => flags.push(InsertReplaceFlag::Ignore(
284 parser.consume_keyword(Keyword::IGNORE)?,
285 )),
286 _ => break,
287 }
288 }
289
290 for flag in &flags {
291 match flag {
292 InsertReplaceFlag::LowPriority(_) => {}
293 InsertReplaceFlag::HighPriority(s) => {
294 if !insert {
295 parser.err("Not supported for replace", s);
296 }
297 }
298 InsertReplaceFlag::Delayed(_) => {}
299 InsertReplaceFlag::Ignore(s) => {
300 if !insert {
301 parser.err("Not supported for replace", s);
302 }
303 }
304 }
305 }
306
307 let into_span = parser.skip_keyword(Keyword::INTO);
308 let table = parse_qualified_name(parser)?;
309 let mut columns = Vec::new();
312 if parser.skip_token(Token::LParen).is_some() {
313 parser.recovered(")", &|t| t == &Token::RParen, |parser| {
314 loop {
315 columns.push(parser.consume_plain_identifier()?);
316 if parser.skip_token(Token::Comma).is_none() {
317 break;
318 }
319 }
320 Ok(())
321 })?;
322 parser.consume_token(Token::RParen)?;
323 }
324
325 let mut select = None;
326 let mut values = None;
327 let mut set = None;
328 match &parser.token {
329 Token::Ident(_, Keyword::SELECT) => {
330 select = Some(parse_select(parser)?);
331 }
332 Token::Ident(_, Keyword::VALUE | Keyword::VALUES) => {
333 let values_span = parser.consume();
334 let mut values_items = Vec::new();
335 loop {
336 let mut vals = Vec::new();
337 parser.consume_token(Token::LParen)?;
338 parser.recovered(")", &|t| t == &Token::RParen, |parser| {
339 loop {
340 vals.push(parse_expression(parser, false)?);
341 if parser.skip_token(Token::Comma).is_none() {
342 break;
343 }
344 }
345 Ok(())
346 })?;
347 parser.consume_token(Token::RParen)?;
348 values_items.push(vals);
349 if parser.skip_token(Token::Comma).is_none() {
350 break;
351 }
352 }
353 values = Some((values_span, values_items));
354 }
355 Token::Ident(_, Keyword::SET) => {
356 let set_span = parser.consume_keyword(Keyword::SET)?;
357 let mut pairs = Vec::new();
358 loop {
359 let column = parser.consume_plain_identifier()?;
360 let equal_span = parser.consume_token(Token::Eq)?;
361 let value: Expression<'_> = parse_expression(parser, false)?;
362 pairs.push(InsertReplaceSetPair {
363 column,
364 equal_span,
365 value,
366 });
367 if parser.skip_token(Token::Comma).is_none() {
368 break;
369 }
370 }
371 if let Some(cs) = columns.opt_span() {
372 parser
373 .err("Columns may not be used here", &cs)
374 .frag("Together with SET", &set_span);
375 }
376 set = Some(InsertReplaceSet { set_span, pairs });
377 }
378 _ => {
379 parser.expected_error("VALUE, VALUES, SELECT or SET");
380 }
381 }
382
383 let (on_duplicate_key_update, on_conflict) =
384 if matches!(parser.token, Token::Ident(_, Keyword::ON)) {
385 let on = parser.consume_keyword(Keyword::ON)?;
386 match &parser.token {
387 Token::Ident(_, Keyword::DUPLICATE) => {
388 let on_duplicate_key_update_span =
389 on.join_span(&parser.consume_keywords(&[
390 Keyword::DUPLICATE,
391 Keyword::KEY,
392 Keyword::UPDATE,
393 ])?);
394 let mut pairs = Vec::new();
395 loop {
396 let column = parser.consume_plain_identifier()?;
397 let equal_span = parser.consume_token(Token::Eq)?;
398 let value = parse_expression(parser, false)?;
399 pairs.push(InsertReplaceSetPair {
400 column,
401 equal_span,
402 value,
403 });
404 if parser.skip_token(Token::Comma).is_none() {
405 break;
406 }
407 }
408 if !parser.options.dialect.is_maria() {
409 parser.err(
410 "Only support by mariadb",
411 &on_duplicate_key_update_span.join_span(&pairs),
412 );
413 }
414 (
415 Some(InsertReplaceOnDuplicateKeyUpdate {
416 on_duplicate_key_update_span,
417 pairs,
418 }),
419 None,
420 )
421 }
422 Token::Ident(_, Keyword::CONFLICT) => {
423 let on_conflict_span =
424 on.join_span(&parser.consume_keyword(Keyword::CONFLICT)?);
425
426 let target = match &parser.token {
427 Token::LParen => {
428 parser.consume_token(Token::LParen)?;
429 let mut names = Vec::new();
430 names.push(parser.consume_plain_identifier()?);
431 while parser.skip_token(Token::Comma).is_some() {
432 names.push(parser.consume_plain_identifier()?);
433 }
434 parser.consume_token(Token::RParen)?;
435 OnConflictTarget::Columns { names }
436 }
437 Token::Ident(_, Keyword::ON) => {
438 let on_constraint =
439 parser.consume_keywords(&[Keyword::ON, Keyword::CONSTRAINT])?;
440 let name = parser.consume_plain_identifier()?;
441 OnConflictTarget::OnConstraint {
442 on_constraint_span: on_constraint,
443 name,
444 }
445 }
446 _ => OnConflictTarget::None,
447 };
448
449 let do_ = parser.consume_keyword(Keyword::DO)?;
450 let action = match &parser.token {
451 Token::Ident(_, Keyword::NOTHING) => OnConflictAction::DoNothing(
452 do_.join_span(&parser.consume_keyword(Keyword::NOTHING)?),
453 ),
454 Token::Ident(_, Keyword::UPDATE) => {
455 let do_update_set_span = do_.join_span(
456 &parser.consume_keywords(&[Keyword::UPDATE, Keyword::SET])?,
457 );
458 let mut sets = Vec::new();
459 loop {
460 let name = parser.consume_plain_identifier()?;
461 parser.consume_token(Token::Eq)?;
462 let expr = parse_expression(parser, false)?;
463 sets.push((name, expr));
464 if parser.skip_token(Token::Comma).is_none() {
465 break;
466 }
467 }
468 let where_ = if matches!(parser.token, Token::Ident(_, Keyword::WHERE))
469 {
470 let where_span = parser.consume_keyword(Keyword::WHERE)?;
471 let where_expr =
472 alloc::boxed::Box::new(parse_expression(parser, false)?);
473 Some((where_span, where_expr))
474 } else {
475 None
476 };
477 OnConflictAction::DoUpdateSet {
478 do_update_set_span,
479 sets,
480 where_,
481 }
482 }
483 _ => parser.expected_failure("'NOTHING' or 'UPDATE'")?,
484 };
485
486 let on_conflict = OnConflict {
487 on_conflict_span,
488 target,
489 action,
490 };
491
492 if !parser.options.dialect.is_postgresql() {
493 parser.err("Only support by postgesql", &on_conflict);
494 }
495
496 (None, Some(on_conflict))
497 }
498 _ => parser.expected_failure("'DUPLICATE' OR 'CONFLICT'")?,
499 }
500 } else {
501 (None, None)
502 };
503
504 let returning = if let Some(returning_span) = parser.skip_keyword(Keyword::RETURNING) {
505 let mut returning_exprs = Vec::new();
506 loop {
507 returning_exprs.push(parse_select_expr(parser)?);
508 if parser.skip_token(Token::Comma).is_none() {
509 break;
510 }
511 }
512 Some((returning_span, returning_exprs))
513 } else {
514 None
515 };
516
517 Ok(InsertReplace {
518 type_,
519 flags,
520 table,
521 columns,
522 into_span,
523 values,
524 select,
525 set,
526 on_duplicate_key_update,
527 on_conflict,
528 returning,
529 })
530}