1use lora_analyzer::symbols::VarId;
2use lora_analyzer::{
3 ResolvedExpr, ResolvedMergeAction, ResolvedPattern, ResolvedPatternPart, ResolvedProjection,
4 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 OptionalMatch(OptionalMatch),
40 PathBuild(PathBuild),
41 CallSubquery(CallSubquery),
42}
43
44#[derive(Debug, Clone)]
50pub struct CallSubquery {
51 pub input: PlanNodeId,
52 pub inner: PlanNodeId,
53 pub new_vars: Vec<VarId>,
54}
55
56#[derive(Debug, Clone)]
58pub struct PathBuild {
59 pub input: PlanNodeId,
60 pub output: VarId,
62 pub node_vars: Vec<VarId>,
64 pub rel_vars: Vec<VarId>,
66 pub shortest_path_all: Option<bool>,
68}
69
70#[derive(Debug, Clone)]
73pub struct OptionalMatch {
74 pub input: PlanNodeId,
76 pub inner: PlanNodeId,
78 pub new_vars: Vec<VarId>,
80}
81
82#[derive(Debug, Clone)]
83pub struct Argument;
84
85#[derive(Debug, Clone)]
86pub struct NodeScan {
87 pub input: Option<PlanNodeId>,
88 pub var: VarId,
89 pub labels: Vec<Vec<String>>,
91}
92
93#[derive(Debug, Clone)]
94pub struct NodeByPropertyScan {
95 pub input: Option<PlanNodeId>,
96 pub var: VarId,
97 pub labels: Vec<Vec<String>>,
99 pub key: String,
100 pub value: ResolvedExpr,
101}
102
103#[derive(Debug, Clone)]
108pub struct NodeByPropertyRangeScan {
109 pub input: Option<PlanNodeId>,
110 pub var: VarId,
111 pub labels: Vec<Vec<String>>,
112 pub key: String,
113 pub lo: Option<ResolvedExpr>,
114 pub lo_inclusive: bool,
115 pub hi: Option<ResolvedExpr>,
116 pub hi_inclusive: bool,
117}
118
119#[derive(Debug, Clone)]
123pub struct NodeByTextScan {
124 pub input: Option<PlanNodeId>,
125 pub var: VarId,
126 pub labels: Vec<Vec<String>>,
127 pub key: String,
128 pub predicate: TextPredicate,
129 pub query: ResolvedExpr,
130}
131
132#[derive(Debug, Clone, Copy, PartialEq, Eq)]
133pub enum TextPredicate {
134 StartsWith,
135 EndsWith,
136 Contains,
137}
138
139#[derive(Debug, Clone)]
146pub struct NodeByPointScan {
147 pub input: Option<PlanNodeId>,
148 pub var: VarId,
149 pub labels: Vec<Vec<String>>,
150 pub key: String,
151 pub predicate: PointPredicate,
152}
153
154#[derive(Debug, Clone)]
155pub enum PointPredicate {
156 WithinBBox {
157 lower_left: ResolvedExpr,
158 upper_right: ResolvedExpr,
159 },
160 WithinDistance {
161 center: ResolvedExpr,
162 max_distance: ResolvedExpr,
163 inclusive: bool,
164 },
165}
166
167#[derive(Debug, Clone)]
174pub struct RelByPropertyRangeScan {
175 pub input: Option<PlanNodeId>,
176 pub src: VarId,
177 pub rel: VarId,
178 pub dst: VarId,
179 pub types: Vec<String>,
180 pub direction: Direction,
181 pub key: String,
182 pub lo: Option<ResolvedExpr>,
183 pub lo_inclusive: bool,
184 pub hi: Option<ResolvedExpr>,
185 pub hi_inclusive: bool,
186}
187
188#[derive(Debug, Clone)]
190pub struct RelByTextScan {
191 pub input: Option<PlanNodeId>,
192 pub src: VarId,
193 pub rel: VarId,
194 pub dst: VarId,
195 pub types: Vec<String>,
196 pub direction: Direction,
197 pub key: String,
198 pub predicate: TextPredicate,
199 pub query: ResolvedExpr,
200}
201
202#[derive(Debug, Clone)]
204pub struct RelByPointScan {
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: PointPredicate,
213}
214
215#[derive(Debug, Clone)]
216pub struct Expand {
217 pub input: PlanNodeId,
218 pub src: VarId,
219 pub rel: Option<VarId>,
220 pub dst: VarId,
221 pub types: Vec<String>,
222 pub direction: Direction,
223 pub rel_properties: Option<ResolvedExpr>,
224 pub range: Option<RangeLiteral>,
225}
226
227#[derive(Debug, Clone)]
228pub struct Filter {
229 pub input: PlanNodeId,
230 pub predicate: ResolvedExpr,
231}
232
233#[derive(Debug, Clone)]
234pub struct Projection {
235 pub input: PlanNodeId,
236 pub distinct: bool,
237 pub items: Vec<ResolvedProjection>,
238 pub include_existing: bool,
239}
240
241#[derive(Debug, Clone)]
242pub struct Unwind {
243 pub input: PlanNodeId,
244 pub expr: ResolvedExpr,
245 pub alias: VarId,
246}
247
248#[derive(Debug, Clone)]
249pub struct Aggregation {
250 pub input: PlanNodeId,
251 pub group_by: Vec<ResolvedProjection>,
252 pub aggregates: Vec<ResolvedProjection>,
253}
254
255#[derive(Debug, Clone)]
256pub struct Sort {
257 pub input: PlanNodeId,
258 pub items: Vec<ResolvedSortItem>,
259 pub top_k: Option<usize>,
262}
263
264#[derive(Debug, Clone)]
265pub struct Limit {
266 pub input: PlanNodeId,
267 pub skip: Option<ResolvedExpr>,
268 pub limit: Option<ResolvedExpr>,
269}
270
271#[derive(Debug, Clone)]
272pub struct Create {
273 pub input: PlanNodeId,
274 pub pattern: ResolvedPattern,
275}
276
277#[derive(Debug, Clone)]
278pub struct Merge {
279 pub input: PlanNodeId,
280 pub pattern_part: ResolvedPatternPart,
281 pub actions: Vec<ResolvedMergeAction>,
282}
283
284#[derive(Debug, Clone)]
285pub struct Delete {
286 pub input: PlanNodeId,
287 pub detach: bool,
288 pub expressions: Vec<ResolvedExpr>,
289}
290
291#[derive(Debug, Clone)]
292pub struct Set {
293 pub input: PlanNodeId,
294 pub items: Vec<ResolvedSetItem>,
295}
296
297#[derive(Debug, Clone)]
298pub struct Remove {
299 pub input: PlanNodeId,
300 pub items: Vec<ResolvedRemoveItem>,
301}