linkrs_query/parser/parsing/dml_parser/
merge.rs1use super::*;
2
3impl DmlParser {
4 pub fn parse_merge_statement(&mut self, ctx: &mut ParseContext) -> Result<Stmt, ParseError> {
6 let start_span = ctx.current_span();
7 ctx.expect_token(TokenKind::Merge)?;
8
9 if ctx.check_token(TokenKind::Edge) || ctx.check_token(TokenKind::Vertex) {
11 ctx.set_upsert_mode(true);
12 let result = self.parse_update_after_token(ctx, start_span);
13 ctx.set_upsert_mode(false);
14 return result;
15 }
16
17 let pattern = TraversalParser::new().parse_pattern(ctx)?;
18
19 let (mut on_create, mut on_match) = if ctx.match_token(TokenKind::On) {
23 if ctx.match_token(TokenKind::Create) {
24 (Some(Self::parse_merge_set_clause(ctx)?), None)
25 } else if ctx.match_token(TokenKind::Match) {
26 (None, Some(Self::parse_merge_set_clause(ctx)?))
27 } else {
28 return Err(ParseError::new(
29 ParseErrorKind::SyntaxError,
30 "Expected CREATE or MATCH after ON in MERGE statement".to_string(),
31 ctx.current_position(),
32 ));
33 }
34 } else {
35 (None, None)
36 };
37 if ctx.match_token(TokenKind::On) {
38 if ctx.match_token(TokenKind::Create) {
39 if on_create.is_some() {
40 return Err(ParseError::new(
41 ParseErrorKind::SyntaxError,
42 "Duplicate ON CREATE clause in MERGE statement".to_string(),
43 ctx.current_position(),
44 ));
45 }
46 on_create = Some(Self::parse_merge_set_clause(ctx)?);
47 } else if ctx.match_token(TokenKind::Match) {
48 if on_match.is_some() {
49 return Err(ParseError::new(
50 ParseErrorKind::SyntaxError,
51 "Duplicate ON MATCH clause in MERGE statement".to_string(),
52 ctx.current_position(),
53 ));
54 }
55 on_match = Some(Self::parse_merge_set_clause(ctx)?);
56 } else {
57 return Err(ParseError::new(
58 ParseErrorKind::SyntaxError,
59 "Expected CREATE or MATCH after ON in MERGE statement".to_string(),
60 ctx.current_position(),
61 ));
62 }
63 }
64
65 if ctx.match_token(TokenKind::Set) {
71 let bare = ClauseParser::new().parse_set_clause(ctx)?;
72 if !bare.assignments.is_empty() {
73 if let Some(clause) = on_create.as_mut() {
74 clause.assignments.extend(bare.assignments.iter().cloned());
75 } else {
76 on_create = Some(bare.clone());
77 }
78 if let Some(clause) = on_match.as_mut() {
79 clause.assignments.extend(bare.assignments);
80 } else {
81 on_match = Some(bare);
82 }
83 }
84 }
85
86 Ok(Stmt::Merge(MergeStmt {
87 span: start_span,
88 pattern,
89 on_create,
90 on_match,
91 }))
92 }
93
94 fn parse_merge_set_clause(ctx: &mut ParseContext) -> Result<SetClause, ParseError> {
99 if ctx.match_token(TokenKind::Set) {
100 ClauseParser::new().parse_set_clause(ctx)
101 } else {
102 Ok(SetClause {
103 span: ctx.current_span(),
104 assignments: Vec::new(),
105 })
106 }
107 }
108}