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 NodeByIdSeek(NodeByIdSeek),
21 NodeByPropertyScan(NodeByPropertyScan),
22 NodeByPropertyRangeScan(NodeByPropertyRangeScan),
23 NodeByTextScan(NodeByTextScan),
24 NodeByPointScan(NodeByPointScan),
25 RelByPropertyRangeScan(RelByPropertyRangeScan),
26 RelByTextScan(RelByTextScan),
27 RelByPointScan(RelByPointScan),
28 RelByIdSeek(RelByIdSeek),
29 Expand(Expand),
30 Filter(Filter),
31 Projection(Projection),
32 Unwind(Unwind),
33 Aggregation(Aggregation),
34 Sort(Sort),
35 Limit(Limit),
36 Merge(Merge),
37 Delete(Delete),
38 Set(Set),
39 Remove(Remove),
40 Create(Create),
41 Foreach(Foreach),
42 OptionalMatch(OptionalMatch),
43 PathBuild(PathBuild),
44 CallSubquery(CallSubquery),
45}
46
47#[derive(Debug, Clone)]
53pub struct Foreach {
54 pub input: PlanNodeId,
55 pub variable: VarId,
56 pub list: ResolvedExpr,
57 pub body: Vec<ResolvedClause>,
58}
59
60#[derive(Debug, Clone)]
66pub struct CallSubquery {
67 pub input: PlanNodeId,
68 pub inner: PlanNodeId,
69 pub new_vars: Vec<VarId>,
70}
71
72#[derive(Debug, Clone)]
74pub struct PathBuild {
75 pub input: PlanNodeId,
76 pub output: VarId,
78 pub node_vars: Vec<VarId>,
80 pub rel_vars: Vec<VarId>,
82 pub shortest_path_all: Option<bool>,
84}
85
86#[derive(Debug, Clone)]
89pub struct OptionalMatch {
90 pub input: PlanNodeId,
92 pub inner: PlanNodeId,
94 pub new_vars: Vec<VarId>,
96}
97
98#[derive(Debug, Clone)]
99pub struct Argument;
100
101#[derive(Debug, Clone)]
102pub struct NodeScan {
103 pub input: Option<PlanNodeId>,
104 pub var: VarId,
105 pub labels: Vec<Vec<String>>,
107}
108
109#[derive(Debug, Clone)]
116pub struct NodeByIdSeek {
117 pub input: Option<PlanNodeId>,
118 pub var: VarId,
119 pub labels: Vec<Vec<String>>,
121 pub ids: ResolvedExpr,
122 pub in_list: bool,
124}
125
126#[derive(Debug, Clone)]
127pub struct NodeByPropertyScan {
128 pub input: Option<PlanNodeId>,
129 pub var: VarId,
130 pub labels: Vec<Vec<String>>,
132 pub key: String,
133 pub value: ResolvedExpr,
134 pub in_list: bool,
137}
138
139#[derive(Debug, Clone)]
144pub struct NodeByPropertyRangeScan {
145 pub input: Option<PlanNodeId>,
146 pub var: VarId,
147 pub labels: Vec<Vec<String>>,
148 pub key: String,
149 pub lo: Option<ResolvedExpr>,
150 pub lo_inclusive: bool,
151 pub hi: Option<ResolvedExpr>,
152 pub hi_inclusive: bool,
153 pub order: Option<lora_ast::SortDirection>,
157}
158
159#[derive(Debug, Clone)]
163pub struct NodeByTextScan {
164 pub input: Option<PlanNodeId>,
165 pub var: VarId,
166 pub labels: Vec<Vec<String>>,
167 pub key: String,
168 pub predicate: TextPredicate,
169 pub query: ResolvedExpr,
170}
171
172#[derive(Debug, Clone, Copy, PartialEq, Eq)]
173pub enum TextPredicate {
174 StartsWith,
175 EndsWith,
176 Contains,
177}
178
179#[derive(Debug, Clone)]
186pub struct NodeByPointScan {
187 pub input: Option<PlanNodeId>,
188 pub var: VarId,
189 pub labels: Vec<Vec<String>>,
190 pub key: String,
191 pub predicate: PointPredicate,
192}
193
194#[derive(Debug, Clone)]
195pub enum PointPredicate {
196 WithinBBox {
197 lower_left: ResolvedExpr,
198 upper_right: ResolvedExpr,
199 },
200 WithinDistance {
201 center: ResolvedExpr,
202 max_distance: ResolvedExpr,
203 inclusive: bool,
204 },
205}
206
207#[derive(Debug, Clone)]
214pub struct RelByPropertyRangeScan {
215 pub input: Option<PlanNodeId>,
216 pub src: VarId,
217 pub rel: VarId,
218 pub dst: VarId,
219 pub types: Vec<String>,
220 pub direction: Direction,
221 pub key: String,
222 pub lo: Option<ResolvedExpr>,
223 pub lo_inclusive: bool,
224 pub hi: Option<ResolvedExpr>,
225 pub hi_inclusive: bool,
226}
227
228#[derive(Debug, Clone)]
230pub struct RelByTextScan {
231 pub input: Option<PlanNodeId>,
232 pub src: VarId,
233 pub rel: VarId,
234 pub dst: VarId,
235 pub types: Vec<String>,
236 pub direction: Direction,
237 pub key: String,
238 pub predicate: TextPredicate,
239 pub query: ResolvedExpr,
240}
241
242#[derive(Debug, Clone)]
244pub struct RelByPointScan {
245 pub input: Option<PlanNodeId>,
246 pub src: VarId,
247 pub rel: VarId,
248 pub dst: VarId,
249 pub types: Vec<String>,
250 pub direction: Direction,
251 pub key: String,
252 pub predicate: PointPredicate,
253}
254
255#[derive(Debug, Clone)]
263pub struct RelByIdSeek {
264 pub input: Option<PlanNodeId>,
265 pub src: VarId,
266 pub src_labels: Vec<Vec<String>>,
267 pub rel: VarId,
268 pub dst: VarId,
269 pub types: Vec<String>,
270 pub direction: Direction,
271 pub ids: ResolvedExpr,
272 pub in_list: bool,
273}
274
275#[derive(Debug, Clone)]
276pub struct Expand {
277 pub input: PlanNodeId,
278 pub src: VarId,
279 pub rel: Option<VarId>,
280 pub dst: VarId,
281 pub types: Vec<String>,
282 pub direction: Direction,
283 pub rel_properties: Option<ResolvedExpr>,
284 pub range: Option<RangeLiteral>,
285}
286
287#[derive(Debug, Clone)]
288pub struct Filter {
289 pub input: PlanNodeId,
290 pub predicate: ResolvedExpr,
291}
292
293#[derive(Debug, Clone)]
294pub struct Projection {
295 pub input: PlanNodeId,
296 pub distinct: bool,
297 pub items: Vec<ResolvedProjection>,
298 pub include_existing: bool,
299}
300
301#[derive(Debug, Clone)]
302pub struct Unwind {
303 pub input: PlanNodeId,
304 pub expr: ResolvedExpr,
305 pub alias: VarId,
306}
307
308#[derive(Debug, Clone)]
309pub struct Aggregation {
310 pub input: PlanNodeId,
311 pub group_by: Vec<ResolvedProjection>,
312 pub aggregates: Vec<ResolvedProjection>,
313}
314
315#[derive(Debug, Clone)]
316pub struct Sort {
317 pub input: PlanNodeId,
318 pub items: Vec<ResolvedSortItem>,
319 pub top_k: Option<usize>,
322 pub limit: Option<SortLimit>,
326}
327
328#[derive(Debug, Clone)]
330pub struct SortLimit {
331 pub skip: Option<ResolvedExpr>,
332 pub limit: ResolvedExpr,
333}
334
335#[derive(Debug, Clone)]
336pub struct Limit {
337 pub input: PlanNodeId,
338 pub skip: Option<ResolvedExpr>,
339 pub limit: Option<ResolvedExpr>,
340}
341
342#[derive(Debug, Clone)]
343pub struct Create {
344 pub input: PlanNodeId,
345 pub pattern: ResolvedPattern,
346}
347
348#[derive(Debug, Clone)]
349pub struct Merge {
350 pub input: PlanNodeId,
351 pub pattern_part: ResolvedPatternPart,
352 pub actions: Vec<ResolvedMergeAction>,
353}
354
355#[derive(Debug, Clone)]
356pub struct Delete {
357 pub input: PlanNodeId,
358 pub detach: bool,
359 pub expressions: Vec<ResolvedExpr>,
360}
361
362#[derive(Debug, Clone)]
363pub struct Set {
364 pub input: PlanNodeId,
365 pub items: Vec<ResolvedSetItem>,
366}
367
368#[derive(Debug, Clone)]
369pub struct Remove {
370 pub input: PlanNodeId,
371 pub items: Vec<ResolvedRemoveItem>,
372}