1use lora_analyzer::symbols::VarId;
2use lora_analyzer::{
3 ResolvedClause, ResolvedExpr, ResolvedMergeAction, ResolvedPattern, ResolvedPatternPart,
4 ResolvedProjection, ResolvedRemoveItem, ResolvedSetItem, ResolvedSortItem,
5};
6use lora_ast::{Direction, RangeLiteral};
7
8pub type PlanNodeId = usize;
9
10#[derive(Debug, Clone)]
11pub struct LogicalPlan {
12 pub root: PlanNodeId,
13 pub nodes: Vec<LogicalOp>,
14}
15
16#[derive(Debug, Clone)]
17pub enum LogicalOp {
18 Argument(Argument),
19 NodeScan(NodeScan),
20 NodeByPropertyScan(NodeByPropertyScan),
21 NodeByPropertyRangeScan(NodeByPropertyRangeScan),
22 NodeByTextScan(NodeByTextScan),
23 NodeByPointScan(NodeByPointScan),
24 RelByPropertyRangeScan(RelByPropertyRangeScan),
25 RelByTextScan(RelByTextScan),
26 RelByPointScan(RelByPointScan),
27 Expand(Expand),
28 Filter(Filter),
29 Projection(Projection),
30 Unwind(Unwind),
31 Aggregation(Aggregation),
32 Sort(Sort),
33 Limit(Limit),
34 Merge(Merge),
35 Delete(Delete),
36 Set(Set),
37 Remove(Remove),
38 Create(Create),
39 Foreach(Foreach),
40 OptionalMatch(OptionalMatch),
41 PathBuild(PathBuild),
42 CallSubquery(CallSubquery),
43}
44
45#[derive(Debug, Clone)]
51pub struct Foreach {
52 pub input: PlanNodeId,
53 pub variable: VarId,
54 pub list: ResolvedExpr,
55 pub body: Vec<ResolvedClause>,
56}
57
58#[derive(Debug, Clone)]
64pub struct CallSubquery {
65 pub input: PlanNodeId,
66 pub inner: PlanNodeId,
67 pub new_vars: Vec<VarId>,
68}
69
70#[derive(Debug, Clone)]
72pub struct PathBuild {
73 pub input: PlanNodeId,
74 pub output: VarId,
76 pub node_vars: Vec<VarId>,
78 pub rel_vars: Vec<VarId>,
80 pub shortest_path_all: Option<bool>,
82}
83
84#[derive(Debug, Clone)]
87pub struct OptionalMatch {
88 pub input: PlanNodeId,
90 pub inner: PlanNodeId,
92 pub new_vars: Vec<VarId>,
94}
95
96#[derive(Debug, Clone)]
97pub struct Argument;
98
99#[derive(Debug, Clone)]
100pub struct NodeScan {
101 pub input: Option<PlanNodeId>,
102 pub var: VarId,
103 pub labels: Vec<Vec<String>>,
105}
106
107#[derive(Debug, Clone)]
108pub struct NodeByPropertyScan {
109 pub input: Option<PlanNodeId>,
110 pub var: VarId,
111 pub labels: Vec<Vec<String>>,
113 pub key: String,
114 pub value: ResolvedExpr,
115}
116
117#[derive(Debug, Clone)]
122pub struct NodeByPropertyRangeScan {
123 pub input: Option<PlanNodeId>,
124 pub var: VarId,
125 pub labels: Vec<Vec<String>>,
126 pub key: String,
127 pub lo: Option<ResolvedExpr>,
128 pub lo_inclusive: bool,
129 pub hi: Option<ResolvedExpr>,
130 pub hi_inclusive: bool,
131}
132
133#[derive(Debug, Clone)]
137pub struct NodeByTextScan {
138 pub input: Option<PlanNodeId>,
139 pub var: VarId,
140 pub labels: Vec<Vec<String>>,
141 pub key: String,
142 pub predicate: TextPredicate,
143 pub query: ResolvedExpr,
144}
145
146#[derive(Debug, Clone, Copy, PartialEq, Eq)]
147pub enum TextPredicate {
148 StartsWith,
149 EndsWith,
150 Contains,
151}
152
153#[derive(Debug, Clone)]
160pub struct NodeByPointScan {
161 pub input: Option<PlanNodeId>,
162 pub var: VarId,
163 pub labels: Vec<Vec<String>>,
164 pub key: String,
165 pub predicate: PointPredicate,
166}
167
168#[derive(Debug, Clone)]
169pub enum PointPredicate {
170 WithinBBox {
171 lower_left: ResolvedExpr,
172 upper_right: ResolvedExpr,
173 },
174 WithinDistance {
175 center: ResolvedExpr,
176 max_distance: ResolvedExpr,
177 inclusive: bool,
178 },
179}
180
181#[derive(Debug, Clone)]
188pub struct RelByPropertyRangeScan {
189 pub input: Option<PlanNodeId>,
190 pub src: VarId,
191 pub rel: VarId,
192 pub dst: VarId,
193 pub types: Vec<String>,
194 pub direction: Direction,
195 pub key: String,
196 pub lo: Option<ResolvedExpr>,
197 pub lo_inclusive: bool,
198 pub hi: Option<ResolvedExpr>,
199 pub hi_inclusive: bool,
200}
201
202#[derive(Debug, Clone)]
204pub struct RelByTextScan {
205 pub input: Option<PlanNodeId>,
206 pub src: VarId,
207 pub rel: VarId,
208 pub dst: VarId,
209 pub types: Vec<String>,
210 pub direction: Direction,
211 pub key: String,
212 pub predicate: TextPredicate,
213 pub query: ResolvedExpr,
214}
215
216#[derive(Debug, Clone)]
218pub struct RelByPointScan {
219 pub input: Option<PlanNodeId>,
220 pub src: VarId,
221 pub rel: VarId,
222 pub dst: VarId,
223 pub types: Vec<String>,
224 pub direction: Direction,
225 pub key: String,
226 pub predicate: PointPredicate,
227}
228
229#[derive(Debug, Clone)]
230pub struct Expand {
231 pub input: PlanNodeId,
232 pub src: VarId,
233 pub rel: Option<VarId>,
234 pub dst: VarId,
235 pub types: Vec<String>,
236 pub direction: Direction,
237 pub rel_properties: Option<ResolvedExpr>,
238 pub range: Option<RangeLiteral>,
239}
240
241#[derive(Debug, Clone)]
242pub struct Filter {
243 pub input: PlanNodeId,
244 pub predicate: ResolvedExpr,
245}
246
247#[derive(Debug, Clone)]
248pub struct Projection {
249 pub input: PlanNodeId,
250 pub distinct: bool,
251 pub items: Vec<ResolvedProjection>,
252 pub include_existing: bool,
253}
254
255#[derive(Debug, Clone)]
256pub struct Unwind {
257 pub input: PlanNodeId,
258 pub expr: ResolvedExpr,
259 pub alias: VarId,
260}
261
262#[derive(Debug, Clone)]
263pub struct Aggregation {
264 pub input: PlanNodeId,
265 pub group_by: Vec<ResolvedProjection>,
266 pub aggregates: Vec<ResolvedProjection>,
267}
268
269#[derive(Debug, Clone)]
270pub struct Sort {
271 pub input: PlanNodeId,
272 pub items: Vec<ResolvedSortItem>,
273 pub top_k: Option<usize>,
276}
277
278#[derive(Debug, Clone)]
279pub struct Limit {
280 pub input: PlanNodeId,
281 pub skip: Option<ResolvedExpr>,
282 pub limit: Option<ResolvedExpr>,
283}
284
285#[derive(Debug, Clone)]
286pub struct Create {
287 pub input: PlanNodeId,
288 pub pattern: ResolvedPattern,
289}
290
291#[derive(Debug, Clone)]
292pub struct Merge {
293 pub input: PlanNodeId,
294 pub pattern_part: ResolvedPatternPart,
295 pub actions: Vec<ResolvedMergeAction>,
296}
297
298#[derive(Debug, Clone)]
299pub struct Delete {
300 pub input: PlanNodeId,
301 pub detach: bool,
302 pub expressions: Vec<ResolvedExpr>,
303}
304
305#[derive(Debug, Clone)]
306pub struct Set {
307 pub input: PlanNodeId,
308 pub items: Vec<ResolvedSetItem>,
309}
310
311#[derive(Debug, Clone)]
312pub struct Remove {
313 pub input: PlanNodeId,
314 pub items: Vec<ResolvedRemoveItem>,
315}