Skip to main content

lora_compiler/
physical.rs

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 PhysicalNodeId = usize;
9
10#[derive(Debug, Clone)]
11pub struct PhysicalPlan {
12    pub root: PhysicalNodeId,
13    pub nodes: Vec<PhysicalOp>,
14}
15
16#[derive(Debug, Clone)]
17pub enum PhysicalOp {
18    Argument(ArgumentExec),
19    NodeScan(NodeScanExec),
20    NodeByLabelScan(NodeByLabelScanExec),
21    NodeByPropertyScan(NodeByPropertyScanExec),
22    NodeByPropertyRangeScan(NodeByPropertyRangeScanExec),
23    NodeByTextScan(NodeByTextScanExec),
24    NodeByPointScan(NodeByPointScanExec),
25    RelByPropertyRangeScan(RelByPropertyRangeScanExec),
26    RelByTextScan(RelByTextScanExec),
27    RelByPointScan(RelByPointScanExec),
28    Expand(ExpandExec),
29    Filter(FilterExec),
30    Projection(ProjectionExec),
31    Unwind(UnwindExec),
32    HashAggregation(HashAggregationExec),
33    Sort(SortExec),
34    Limit(LimitExec),
35    Create(CreateExec),
36    Merge(MergeExec),
37    Delete(DeleteExec),
38    Set(SetExec),
39    Remove(RemoveExec),
40    OptionalMatch(OptionalMatchExec),
41    PathBuild(PathBuildExec),
42    CallSubquery(CallSubqueryExec),
43}
44
45/// `CALL { ... }` subquery executor node. See [`crate::logical::CallSubquery`].
46#[derive(Debug, Clone)]
47pub struct CallSubqueryExec {
48    pub input: PhysicalNodeId,
49    pub inner: PhysicalNodeId,
50    pub new_vars: Vec<VarId>,
51}
52
53#[derive(Debug, Clone)]
54pub struct PathBuildExec {
55    pub input: PhysicalNodeId,
56    pub output: VarId,
57    pub node_vars: Vec<VarId>,
58    pub rel_vars: Vec<VarId>,
59    pub shortest_path_all: Option<bool>,
60}
61
62/// Left-outer-join: for each input row, runs inner sub-plan.
63/// If inner produces nothing, emits one row with nulls for new_vars.
64#[derive(Debug, Clone)]
65pub struct OptionalMatchExec {
66    pub input: PhysicalNodeId,
67    pub inner: PhysicalNodeId,
68    pub new_vars: Vec<VarId>,
69}
70
71#[derive(Debug, Clone)]
72pub struct ArgumentExec;
73
74#[derive(Debug, Clone)]
75pub struct NodeScanExec {
76    pub input: Option<PhysicalNodeId>,
77    pub var: VarId,
78}
79
80#[derive(Debug, Clone)]
81pub struct NodeByLabelScanExec {
82    pub input: Option<PhysicalNodeId>,
83    pub var: VarId,
84    /// Each inner Vec is a disjunctive group (OR). Outer Vec is conjunctive (AND).
85    pub labels: Vec<Vec<String>>,
86}
87
88#[derive(Debug, Clone)]
89pub struct NodeByPropertyScanExec {
90    pub input: Option<PhysicalNodeId>,
91    pub var: VarId,
92    /// Each inner Vec is a disjunctive group (OR). Outer Vec is conjunctive (AND).
93    pub labels: Vec<Vec<String>>,
94    pub key: String,
95    pub value: ResolvedExpr,
96}
97
98#[derive(Debug, Clone)]
99pub struct NodeByPropertyRangeScanExec {
100    pub input: Option<PhysicalNodeId>,
101    pub var: VarId,
102    pub labels: Vec<Vec<String>>,
103    pub key: String,
104    pub lo: Option<ResolvedExpr>,
105    pub lo_inclusive: bool,
106    pub hi: Option<ResolvedExpr>,
107    pub hi_inclusive: bool,
108}
109
110#[derive(Debug, Clone)]
111pub struct NodeByTextScanExec {
112    pub input: Option<PhysicalNodeId>,
113    pub var: VarId,
114    pub labels: Vec<Vec<String>>,
115    pub key: String,
116    pub predicate: crate::logical::TextPredicate,
117    pub query: ResolvedExpr,
118}
119
120#[derive(Debug, Clone)]
121pub struct NodeByPointScanExec {
122    pub input: Option<PhysicalNodeId>,
123    pub var: VarId,
124    pub labels: Vec<Vec<String>>,
125    pub key: String,
126    pub predicate: crate::logical::PointPredicate,
127}
128
129#[derive(Debug, Clone)]
130pub struct RelByPropertyRangeScanExec {
131    pub input: Option<PhysicalNodeId>,
132    pub src: VarId,
133    pub rel: VarId,
134    pub dst: VarId,
135    pub types: Vec<String>,
136    pub direction: Direction,
137    pub key: String,
138    pub lo: Option<ResolvedExpr>,
139    pub lo_inclusive: bool,
140    pub hi: Option<ResolvedExpr>,
141    pub hi_inclusive: bool,
142}
143
144#[derive(Debug, Clone)]
145pub struct RelByTextScanExec {
146    pub input: Option<PhysicalNodeId>,
147    pub src: VarId,
148    pub rel: VarId,
149    pub dst: VarId,
150    pub types: Vec<String>,
151    pub direction: Direction,
152    pub key: String,
153    pub predicate: crate::logical::TextPredicate,
154    pub query: ResolvedExpr,
155}
156
157#[derive(Debug, Clone)]
158pub struct RelByPointScanExec {
159    pub input: Option<PhysicalNodeId>,
160    pub src: VarId,
161    pub rel: VarId,
162    pub dst: VarId,
163    pub types: Vec<String>,
164    pub direction: Direction,
165    pub key: String,
166    pub predicate: crate::logical::PointPredicate,
167}
168
169#[derive(Debug, Clone)]
170pub struct ExpandExec {
171    pub input: PhysicalNodeId,
172    pub src: VarId,
173    pub rel: Option<VarId>,
174    pub dst: VarId,
175    pub types: Vec<String>,
176    pub direction: Direction,
177    pub rel_properties: Option<ResolvedExpr>,
178    pub range: Option<RangeLiteral>,
179}
180
181#[derive(Debug, Clone)]
182pub struct FilterExec {
183    pub input: PhysicalNodeId,
184    pub predicate: ResolvedExpr,
185}
186
187#[derive(Debug, Clone)]
188pub struct ProjectionExec {
189    pub input: PhysicalNodeId,
190    pub distinct: bool,
191    pub items: Vec<ResolvedProjection>,
192    pub include_existing: bool,
193}
194
195#[derive(Debug, Clone)]
196pub struct UnwindExec {
197    pub input: PhysicalNodeId,
198    pub expr: ResolvedExpr,
199    pub alias: VarId,
200}
201
202#[derive(Debug, Clone)]
203pub struct HashAggregationExec {
204    pub input: PhysicalNodeId,
205    pub group_by: Vec<ResolvedProjection>,
206    pub aggregates: Vec<ResolvedProjection>,
207}
208
209#[derive(Debug, Clone)]
210pub struct SortExec {
211    pub input: PhysicalNodeId,
212    pub items: Vec<ResolvedSortItem>,
213    /// Optional upper bound for rows Sort must retain before a parent LIMIT.
214    pub top_k: Option<usize>,
215}
216
217#[derive(Debug, Clone)]
218pub struct LimitExec {
219    pub input: PhysicalNodeId,
220    pub skip: Option<ResolvedExpr>,
221    pub limit: Option<ResolvedExpr>,
222}
223
224#[derive(Debug, Clone)]
225pub struct CreateExec {
226    pub input: PhysicalNodeId,
227    pub pattern: ResolvedPattern,
228}
229
230#[derive(Debug, Clone)]
231pub struct MergeExec {
232    pub input: PhysicalNodeId,
233    pub pattern_part: ResolvedPatternPart,
234    pub actions: Vec<ResolvedMergeAction>,
235}
236
237#[derive(Debug, Clone)]
238pub struct DeleteExec {
239    pub input: PhysicalNodeId,
240    pub detach: bool,
241    pub expressions: Vec<ResolvedExpr>,
242}
243
244#[derive(Debug, Clone)]
245pub struct SetExec {
246    pub input: PhysicalNodeId,
247    pub items: Vec<ResolvedSetItem>,
248}
249
250#[derive(Debug, Clone)]
251pub struct RemoveExec {
252    pub input: PhysicalNodeId,
253    pub items: Vec<ResolvedRemoveItem>,
254}