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}
42
43#[derive(Debug, Clone)]
45pub struct PathBuild {
46 pub input: PlanNodeId,
47 pub output: VarId,
49 pub node_vars: Vec<VarId>,
51 pub rel_vars: Vec<VarId>,
53 pub shortest_path_all: Option<bool>,
55}
56
57#[derive(Debug, Clone)]
60pub struct OptionalMatch {
61 pub input: PlanNodeId,
63 pub inner: PlanNodeId,
65 pub new_vars: Vec<VarId>,
67}
68
69#[derive(Debug, Clone)]
70pub struct Argument;
71
72#[derive(Debug, Clone)]
73pub struct NodeScan {
74 pub input: Option<PlanNodeId>,
75 pub var: VarId,
76 pub labels: Vec<Vec<String>>,
78}
79
80#[derive(Debug, Clone)]
81pub struct NodeByPropertyScan {
82 pub input: Option<PlanNodeId>,
83 pub var: VarId,
84 pub labels: Vec<Vec<String>>,
86 pub key: String,
87 pub value: ResolvedExpr,
88}
89
90#[derive(Debug, Clone)]
95pub struct NodeByPropertyRangeScan {
96 pub input: Option<PlanNodeId>,
97 pub var: VarId,
98 pub labels: Vec<Vec<String>>,
99 pub key: String,
100 pub lo: Option<ResolvedExpr>,
101 pub lo_inclusive: bool,
102 pub hi: Option<ResolvedExpr>,
103 pub hi_inclusive: bool,
104}
105
106#[derive(Debug, Clone)]
110pub struct NodeByTextScan {
111 pub input: Option<PlanNodeId>,
112 pub var: VarId,
113 pub labels: Vec<Vec<String>>,
114 pub key: String,
115 pub predicate: TextPredicate,
116 pub query: ResolvedExpr,
117}
118
119#[derive(Debug, Clone, Copy, PartialEq, Eq)]
120pub enum TextPredicate {
121 StartsWith,
122 EndsWith,
123 Contains,
124}
125
126#[derive(Debug, Clone)]
133pub struct NodeByPointScan {
134 pub input: Option<PlanNodeId>,
135 pub var: VarId,
136 pub labels: Vec<Vec<String>>,
137 pub key: String,
138 pub predicate: PointPredicate,
139}
140
141#[derive(Debug, Clone)]
142pub enum PointPredicate {
143 WithinBBox {
144 lower_left: ResolvedExpr,
145 upper_right: ResolvedExpr,
146 },
147 WithinDistance {
148 center: ResolvedExpr,
149 max_distance: ResolvedExpr,
150 inclusive: bool,
151 },
152}
153
154#[derive(Debug, Clone)]
161pub struct RelByPropertyRangeScan {
162 pub input: Option<PlanNodeId>,
163 pub src: VarId,
164 pub rel: VarId,
165 pub dst: VarId,
166 pub types: Vec<String>,
167 pub direction: Direction,
168 pub key: String,
169 pub lo: Option<ResolvedExpr>,
170 pub lo_inclusive: bool,
171 pub hi: Option<ResolvedExpr>,
172 pub hi_inclusive: bool,
173}
174
175#[derive(Debug, Clone)]
177pub struct RelByTextScan {
178 pub input: Option<PlanNodeId>,
179 pub src: VarId,
180 pub rel: VarId,
181 pub dst: VarId,
182 pub types: Vec<String>,
183 pub direction: Direction,
184 pub key: String,
185 pub predicate: TextPredicate,
186 pub query: ResolvedExpr,
187}
188
189#[derive(Debug, Clone)]
191pub struct RelByPointScan {
192 pub input: Option<PlanNodeId>,
193 pub src: VarId,
194 pub rel: VarId,
195 pub dst: VarId,
196 pub types: Vec<String>,
197 pub direction: Direction,
198 pub key: String,
199 pub predicate: PointPredicate,
200}
201
202#[derive(Debug, Clone)]
203pub struct Expand {
204 pub input: PlanNodeId,
205 pub src: VarId,
206 pub rel: Option<VarId>,
207 pub dst: VarId,
208 pub types: Vec<String>,
209 pub direction: Direction,
210 pub rel_properties: Option<ResolvedExpr>,
211 pub range: Option<RangeLiteral>,
212}
213
214#[derive(Debug, Clone)]
215pub struct Filter {
216 pub input: PlanNodeId,
217 pub predicate: ResolvedExpr,
218}
219
220#[derive(Debug, Clone)]
221pub struct Projection {
222 pub input: PlanNodeId,
223 pub distinct: bool,
224 pub items: Vec<ResolvedProjection>,
225 pub include_existing: bool,
226}
227
228#[derive(Debug, Clone)]
229pub struct Unwind {
230 pub input: PlanNodeId,
231 pub expr: ResolvedExpr,
232 pub alias: VarId,
233}
234
235#[derive(Debug, Clone)]
236pub struct Aggregation {
237 pub input: PlanNodeId,
238 pub group_by: Vec<ResolvedProjection>,
239 pub aggregates: Vec<ResolvedProjection>,
240}
241
242#[derive(Debug, Clone)]
243pub struct Sort {
244 pub input: PlanNodeId,
245 pub items: Vec<ResolvedSortItem>,
246 pub top_k: Option<usize>,
249}
250
251#[derive(Debug, Clone)]
252pub struct Limit {
253 pub input: PlanNodeId,
254 pub skip: Option<ResolvedExpr>,
255 pub limit: Option<ResolvedExpr>,
256}
257
258#[derive(Debug, Clone)]
259pub struct Create {
260 pub input: PlanNodeId,
261 pub pattern: ResolvedPattern,
262}
263
264#[derive(Debug, Clone)]
265pub struct Merge {
266 pub input: PlanNodeId,
267 pub pattern_part: ResolvedPatternPart,
268 pub actions: Vec<ResolvedMergeAction>,
269}
270
271#[derive(Debug, Clone)]
272pub struct Delete {
273 pub input: PlanNodeId,
274 pub detach: bool,
275 pub expressions: Vec<ResolvedExpr>,
276}
277
278#[derive(Debug, Clone)]
279pub struct Set {
280 pub input: PlanNodeId,
281 pub items: Vec<ResolvedSetItem>,
282}
283
284#[derive(Debug, Clone)]
285pub struct Remove {
286 pub input: PlanNodeId,
287 pub items: Vec<ResolvedRemoveItem>,
288}