Skip to main content

lora_compiler/
logical.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 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    Expand(Expand),
21    Filter(Filter),
22    Projection(Projection),
23    Unwind(Unwind),
24    Aggregation(Aggregation),
25    Sort(Sort),
26    Limit(Limit),
27    Merge(Merge),
28    Delete(Delete),
29    Set(Set),
30    Remove(Remove),
31    Create(Create),
32    OptionalMatch(OptionalMatch),
33    PathBuild(PathBuild),
34}
35
36/// Assembles a path value from matched node and relationship VarIds.
37#[derive(Debug, Clone)]
38pub struct PathBuild {
39    pub input: PlanNodeId,
40    /// VarId to store the assembled path.
41    pub output: VarId,
42    /// Node VarIds in order: head, chain[0].node, chain[1].node, ...
43    pub node_vars: Vec<VarId>,
44    /// Relationship VarIds in order: chain[0].rel, chain[1].rel, ...
45    pub rel_vars: Vec<VarId>,
46    /// `None` = normal path, `Some(false)` = shortestPath, `Some(true)` = allShortestPaths
47    pub shortest_path_all: Option<bool>,
48}
49
50/// Left-outer-join style node: runs the inner sub-plan for each input row.
51/// If no rows are produced, emits one row with nulls for the new variables.
52#[derive(Debug, Clone)]
53pub struct OptionalMatch {
54    /// Upstream rows that feed the optional match.
55    pub input: PlanNodeId,
56    /// The root of the inner sub-plan that implements the pattern + filter.
57    pub inner: PlanNodeId,
58    /// Variables introduced by the optional match (need null-extension).
59    pub new_vars: Vec<VarId>,
60}
61
62#[derive(Debug, Clone)]
63pub struct Argument;
64
65#[derive(Debug, Clone)]
66pub struct NodeScan {
67    pub input: Option<PlanNodeId>,
68    pub var: VarId,
69    /// Each inner Vec is a disjunctive group (OR). Outer Vec is conjunctive (AND).
70    pub labels: Vec<Vec<String>>,
71}
72
73#[derive(Debug, Clone)]
74pub struct Expand {
75    pub input: PlanNodeId,
76    pub src: VarId,
77    pub rel: Option<VarId>,
78    pub dst: VarId,
79    pub types: Vec<String>,
80    pub direction: Direction,
81    pub rel_properties: Option<ResolvedExpr>,
82    pub range: Option<RangeLiteral>,
83}
84
85#[derive(Debug, Clone)]
86pub struct Filter {
87    pub input: PlanNodeId,
88    pub predicate: ResolvedExpr,
89}
90
91#[derive(Debug, Clone)]
92pub struct Projection {
93    pub input: PlanNodeId,
94    pub distinct: bool,
95    pub items: Vec<ResolvedProjection>,
96    pub include_existing: bool,
97}
98
99#[derive(Debug, Clone)]
100pub struct Unwind {
101    pub input: PlanNodeId,
102    pub expr: ResolvedExpr,
103    pub alias: VarId,
104}
105
106#[derive(Debug, Clone)]
107pub struct Aggregation {
108    pub input: PlanNodeId,
109    pub group_by: Vec<ResolvedProjection>,
110    pub aggregates: Vec<ResolvedProjection>,
111}
112
113#[derive(Debug, Clone)]
114pub struct Sort {
115    pub input: PlanNodeId,
116    pub items: Vec<ResolvedSortItem>,
117}
118
119#[derive(Debug, Clone)]
120pub struct Limit {
121    pub input: PlanNodeId,
122    pub skip: Option<ResolvedExpr>,
123    pub limit: Option<ResolvedExpr>,
124}
125
126#[derive(Debug, Clone)]
127pub struct Create {
128    pub input: PlanNodeId,
129    pub pattern: ResolvedPattern,
130}
131
132#[derive(Debug, Clone)]
133pub struct Merge {
134    pub input: PlanNodeId,
135    pub pattern_part: ResolvedPatternPart,
136    pub actions: Vec<ResolvedMergeAction>,
137}
138
139#[derive(Debug, Clone)]
140pub struct Delete {
141    pub input: PlanNodeId,
142    pub detach: bool,
143    pub expressions: Vec<ResolvedExpr>,
144}
145
146#[derive(Debug, Clone)]
147pub struct Set {
148    pub input: PlanNodeId,
149    pub items: Vec<ResolvedSetItem>,
150}
151
152#[derive(Debug, Clone)]
153pub struct Remove {
154    pub input: PlanNodeId,
155    pub items: Vec<ResolvedRemoveItem>,
156}