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