Skip to main content

lora_analyzer/
resolved.rs

1use crate::symbols::*;
2use lora_ast::{
3    BinaryOp, Direction, ListPredicateKind, RangeLiteral, SortDirection, Span, UnaryOp,
4};
5
6#[derive(Debug, Clone)]
7pub struct ResolvedQuery {
8    pub clauses: Vec<ResolvedClause>,
9    /// Additional UNION branches. Each branch is a separate resolved query
10    /// that produces rows to be combined with the head query's results.
11    pub unions: Vec<ResolvedUnionPart>,
12}
13
14#[derive(Debug, Clone)]
15pub struct ResolvedUnionPart {
16    /// If true, this is UNION ALL (no deduplication). If false, plain UNION (deduplicate).
17    pub all: bool,
18    /// The resolved clauses for this branch.
19    pub clauses: Vec<ResolvedClause>,
20}
21
22#[derive(Debug, Clone)]
23pub enum ResolvedClause {
24    Match(ResolvedMatch),
25    Unwind(ResolvedUnwind),
26    Create(ResolvedCreate),
27    Merge(ResolvedMerge),
28    Delete(ResolvedDelete),
29    Set(ResolvedSet),
30    Remove(ResolvedRemove),
31    Return(ResolvedReturn),
32    With(ResolvedWith),
33}
34
35#[derive(Debug, Clone)]
36pub struct ResolvedMatch {
37    pub optional: bool,
38    pub pattern: ResolvedPattern,
39    pub where_: Option<ResolvedExpr>,
40}
41
42#[derive(Debug, Clone)]
43pub struct ResolvedUnwind {
44    pub expr: ResolvedExpr,
45    pub alias: VarId,
46}
47
48#[derive(Debug, Clone)]
49pub struct ResolvedCreate {
50    pub pattern: ResolvedPattern,
51}
52
53#[derive(Debug, Clone)]
54pub struct ResolvedMerge {
55    pub pattern_part: ResolvedPatternPart,
56    pub actions: Vec<ResolvedMergeAction>,
57}
58
59#[derive(Debug, Clone)]
60pub struct ResolvedMergeAction {
61    pub on_match: bool,
62    pub set: ResolvedSet,
63}
64
65#[derive(Debug, Clone)]
66pub struct ResolvedDelete {
67    pub detach: bool,
68    pub expressions: Vec<ResolvedExpr>,
69}
70
71#[derive(Debug, Clone)]
72pub struct ResolvedSet {
73    pub items: Vec<ResolvedSetItem>,
74}
75
76#[derive(Debug, Clone)]
77pub enum ResolvedSetItem {
78    SetProperty {
79        target: ResolvedExpr,
80        value: ResolvedExpr,
81    },
82    SetVariable {
83        variable: VarId,
84        value: ResolvedExpr,
85    },
86    MutateVariable {
87        variable: VarId,
88        value: ResolvedExpr,
89    },
90    SetLabels {
91        variable: VarId,
92        labels: Vec<String>,
93    },
94}
95
96#[derive(Debug, Clone)]
97pub struct ResolvedRemove {
98    pub items: Vec<ResolvedRemoveItem>,
99}
100
101#[derive(Debug, Clone)]
102pub enum ResolvedRemoveItem {
103    Labels {
104        variable: VarId,
105        labels: Vec<String>,
106    },
107    Property {
108        expr: ResolvedExpr,
109    },
110}
111
112#[derive(Debug, Clone)]
113pub struct ResolvedReturn {
114    pub distinct: bool,
115    pub items: Vec<ResolvedProjection>,
116    pub include_existing: bool,
117    pub order: Vec<ResolvedSortItem>,
118    pub skip: Option<ResolvedExpr>,
119    pub limit: Option<ResolvedExpr>,
120}
121
122#[derive(Debug, Clone)]
123pub struct ResolvedWith {
124    pub distinct: bool,
125    pub items: Vec<ResolvedProjection>,
126    pub include_existing: bool,
127    pub order: Vec<ResolvedSortItem>,
128    pub skip: Option<ResolvedExpr>,
129    pub limit: Option<ResolvedExpr>,
130    pub where_: Option<ResolvedExpr>,
131}
132
133#[derive(Debug, Clone)]
134pub struct ResolvedProjection {
135    pub expr: ResolvedExpr,
136    pub output: VarId,
137    pub name: String,
138    /// True when the name came from an explicit `AS` alias.
139    pub explicit_alias: bool,
140    pub span: Span,
141}
142
143#[derive(Debug, Clone)]
144pub struct ResolvedSortItem {
145    pub expr: ResolvedExpr,
146    pub direction: SortDirection,
147}
148
149#[derive(Debug, Clone)]
150pub struct ResolvedPattern {
151    pub parts: Vec<ResolvedPatternPart>,
152}
153
154#[derive(Debug, Clone)]
155pub struct ResolvedPatternPart {
156    pub binding: Option<VarId>,
157    pub element: ResolvedPatternElement,
158}
159
160#[derive(Debug, Clone)]
161pub enum ResolvedPatternElement {
162    Node {
163        var: Option<VarId>,
164        /// Each inner Vec is a disjunctive group (OR). Outer Vec is conjunctive (AND).
165        labels: Vec<Vec<String>>,
166        properties: Option<ResolvedExpr>,
167    },
168    NodeChain {
169        head: ResolvedNode,
170        chain: Vec<ResolvedChain>,
171    },
172    ShortestPath {
173        all: bool,
174        head: ResolvedNode,
175        chain: Vec<ResolvedChain>,
176    },
177}
178
179#[derive(Debug, Clone)]
180pub struct ResolvedNode {
181    pub var: Option<VarId>,
182    /// Each inner Vec is a disjunctive group (OR). Outer Vec is conjunctive (AND).
183    pub labels: Vec<Vec<String>>,
184    pub properties: Option<ResolvedExpr>,
185}
186
187#[derive(Debug, Clone)]
188pub struct ResolvedChain {
189    pub rel: ResolvedRel,
190    pub node: ResolvedNode,
191}
192
193#[derive(Debug, Clone)]
194pub struct ResolvedRel {
195    pub var: Option<VarId>,
196    pub types: Vec<String>,
197    pub direction: Direction,
198    pub range: Option<RangeLiteral>,
199    pub properties: Option<ResolvedExpr>,
200}
201
202#[derive(Debug, Clone)]
203pub enum ResolvedExpr {
204    Variable(VarId),
205    Literal(LiteralValue),
206    Property {
207        expr: Box<ResolvedExpr>,
208        property: String,
209    },
210    Binary {
211        lhs: Box<ResolvedExpr>,
212        op: BinaryOp,
213        rhs: Box<ResolvedExpr>,
214    },
215    Unary {
216        op: UnaryOp,
217        expr: Box<ResolvedExpr>,
218    },
219    Function {
220        name: String,
221        distinct: bool,
222        args: Vec<ResolvedExpr>,
223    },
224    List(Vec<ResolvedExpr>),
225    Map(Vec<(String, ResolvedExpr)>),
226    Case {
227        input: Option<Box<ResolvedExpr>>,
228        alternatives: Vec<(ResolvedExpr, ResolvedExpr)>,
229        else_expr: Option<Box<ResolvedExpr>>,
230    },
231    Parameter(String),
232    ListPredicate {
233        kind: ListPredicateKind,
234        variable: VarId,
235        list: Box<ResolvedExpr>,
236        predicate: Box<ResolvedExpr>,
237    },
238    ListComprehension {
239        variable: VarId,
240        list: Box<ResolvedExpr>,
241        filter: Option<Box<ResolvedExpr>>,
242        map_expr: Option<Box<ResolvedExpr>>,
243    },
244    Reduce {
245        accumulator: VarId,
246        init: Box<ResolvedExpr>,
247        variable: VarId,
248        list: Box<ResolvedExpr>,
249        expr: Box<ResolvedExpr>,
250    },
251    MapProjection {
252        base: Box<ResolvedExpr>,
253        selectors: Vec<ResolvedMapSelector>,
254    },
255    Index {
256        expr: Box<ResolvedExpr>,
257        index: Box<ResolvedExpr>,
258    },
259    Slice {
260        expr: Box<ResolvedExpr>,
261        from: Option<Box<ResolvedExpr>>,
262        to: Option<Box<ResolvedExpr>>,
263    },
264    ExistsSubquery {
265        pattern: ResolvedPattern,
266        where_: Option<Box<ResolvedExpr>>,
267    },
268    PatternComprehension {
269        pattern: ResolvedPattern,
270        where_: Option<Box<ResolvedExpr>>,
271        map_expr: Box<ResolvedExpr>,
272    },
273}
274
275#[derive(Debug, Clone)]
276pub enum ResolvedMapSelector {
277    Property(String),
278    AllProperties,
279    Literal(String, ResolvedExpr),
280}
281
282#[derive(Debug, Clone, PartialEq)]
283pub enum LiteralValue {
284    Integer(i64),
285    Float(f64),
286    String(String),
287    Bool(bool),
288    Null,
289}