linkrs_query/parser/parsing/dml_parser/
delete.rs1use super::*;
2
3impl DmlParser {
4 pub fn parse_delete_statement(&mut self, ctx: &mut ParseContext) -> Result<Stmt, ParseError> {
6 use crate::parser::ast::stmt::{DeleteStmt, DeleteTarget};
7
8 ctx.with_edge_syntax_mode(|ctx| {
12 let start_span = ctx.current_span();
13
14 let detach = ctx.match_token(TokenKind::Detach);
16
17 ctx.expect_token(TokenKind::Delete)?;
18
19 let target = if ctx.match_token(TokenKind::Vertex) {
21 let tag = ctx.expect_identifier()?;
23 ctx.expect_token(TokenKind::From)?;
24 let mut vids = vec![];
25 loop {
26 vids.push(self.parse_expression(ctx)?);
27 if !ctx.match_token(TokenKind::Comma) {
28 break;
29 }
30 }
31 DeleteTarget::Vertices { tag, vids }
32 } else if ctx.match_token(TokenKind::Edge) {
33 let first = self.parse_expression(ctx)?;
40 let (edge_type, edges) = if ctx.check_token(TokenKind::Arrow) {
41 let mut edges = vec![];
43 let mut current_src = first;
44 loop {
45 ctx.expect_token(TokenKind::Arrow)?;
46 let dst = self.parse_expression(ctx)?;
47
48 let rank = if ctx.match_token(TokenKind::At) {
49 Some(self.parse_expression(ctx)?)
50 } else {
51 None
52 };
53
54 edges.push((current_src.clone(), dst, rank));
55
56 if !ctx.match_token(TokenKind::Comma) {
57 break;
58 }
59 current_src = self.parse_expression(ctx)?;
60 }
61 ctx.expect_token(TokenKind::Of)?;
62 let type_name = ctx.expect_identifier()?;
63 (Some(type_name), edges)
64 } else {
65 let type_name = match first.expression().map(|meta| meta.inner().clone()) {
67 Some(linkrs_core::types::Expression::Variable(name)) => name,
68 Some(linkrs_core::types::Expression::Literal(
69 linkrs_core::Value::FixedString(s),
70 )) => s.to_string(),
71 Some(linkrs_core::types::Expression::Literal(
72 linkrs_core::Value::String(s),
73 )) => s.to_string(),
74 _ => {
75 return Err(ParseError::new(
76 ParseErrorKind::UnexpectedToken,
77 "Expected edge type name before source expression".to_string(),
78 ctx.current_position(),
79 ));
80 }
81 };
82 let edge_type = Some(type_name);
83
84 let mut edges = vec![];
85 loop {
86 let src = self.parse_expression(ctx)?;
87 ctx.expect_token(TokenKind::Arrow)?;
88 let dst = self.parse_expression(ctx)?;
89
90 let rank = if ctx.match_token(TokenKind::At) {
91 Some(self.parse_expression(ctx)?)
92 } else {
93 None
94 };
95
96 edges.push((src, dst, rank));
97
98 if !ctx.match_token(TokenKind::Comma) {
99 break;
100 }
101 }
102 (edge_type, edges)
103 };
104
105 DeleteTarget::Edges { edge_type, edges }
106 } else {
107 return Err(ParseError::new(
108 crate::parser::core::error::ParseErrorKind::UnexpectedToken,
109 "DELETE VERTEX requires a tag qualifier: DELETE VERTEX <tag> FROM <vid>, ..."
110 .to_string(),
111 ctx.current_position(),
112 ));
113 };
114
115 let with_edge = if ctx.match_token(TokenKind::With) {
116 ctx.expect_token(TokenKind::Edge)?;
117 true
118 } else {
119 false
120 };
121
122 let span = ctx.span_since(start_span.start);
123
124 Ok(Stmt::Delete(DeleteStmt {
125 span,
126 target,
127 with_edge,
128 detach,
129 }))
130 })
131 }
132}