drasi_query_ast/
ast.rs

1// Copyright 2024 The Drasi Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::collections::BTreeMap;
16use std::hash::Hasher;
17use std::sync::Arc;
18
19#[derive(Debug, Clone, PartialEq)]
20pub struct Query {
21    pub parts: Vec<QueryPart>,
22}
23
24#[derive(Debug, Clone, PartialEq)]
25pub struct QueryPart {
26    pub match_clauses: Vec<MatchClause>,
27    pub where_clauses: Vec<Expression>,
28    pub return_clause: ProjectionClause,
29}
30
31#[derive(Debug, Clone, PartialEq)]
32pub struct MatchClause {
33    pub start: NodeMatch,
34    pub path: Vec<(RelationMatch, NodeMatch)>,
35}
36
37#[derive(Debug, Clone, PartialEq)]
38pub enum ProjectionClause {
39    Item(Vec<Expression>),
40    GroupBy {
41        grouping: Vec<Expression>,
42        aggregates: Vec<Expression>,
43    },
44}
45
46#[derive(Debug, Clone, PartialEq)]
47pub struct SetClause {
48    pub name: Arc<str>,
49    pub key: Arc<str>,
50    pub value: Expression,
51}
52
53#[derive(Debug, Clone, PartialEq)]
54pub enum CreateClause {
55    CreateNode {
56        name: Option<Arc<str>>,
57        label: Arc<str>,
58        properties: Vec<(Arc<str>, Expression)>,
59    },
60    CreateEdge {
61        name: Option<Arc<str>>,
62        label: Arc<str>,
63        origin: Arc<str>,
64        target: Arc<str>,
65        properties: Vec<(Arc<str>, Expression)>,
66    },
67}
68
69#[derive(Debug, Clone, PartialEq)]
70pub struct Annotation {
71    pub name: Option<Arc<str>>,
72}
73
74impl Annotation {
75    #[allow(dead_code)]
76    pub fn new(name: Arc<str>) -> Self {
77        Self { name: Some(name) }
78    }
79
80    #[allow(dead_code)]
81    pub fn empty() -> Self {
82        Self { name: None }
83    }
84}
85
86#[derive(Debug, Clone, PartialEq)]
87pub struct NodeMatch {
88    pub annotation: Annotation,
89    pub labels: Vec<Arc<str>>,
90    pub property_predicates: Vec<Expression>,
91}
92
93impl NodeMatch {
94    #[allow(dead_code)]
95    pub fn new(
96        annotation: Annotation,
97        labels: Vec<Arc<str>>,
98        property_predicates: Vec<Expression>,
99    ) -> Self {
100        Self {
101            annotation,
102            labels,
103            property_predicates,
104        }
105    }
106
107    #[allow(dead_code)]
108    pub fn empty() -> Self {
109        Self {
110            annotation: Annotation::empty(),
111            labels: vec![],
112            property_predicates: vec![],
113        }
114    }
115
116    pub fn with_annotation(annotation: Annotation, label: Arc<str>) -> Self {
117        Self {
118            annotation,
119            labels: vec![label],
120            property_predicates: vec![],
121        }
122    }
123}
124
125#[derive(Debug, Clone, Copy, PartialEq)]
126pub enum Direction {
127    Left,
128    Right,
129    Either,
130}
131
132#[derive(Debug, Clone, PartialEq)]
133pub struct VariableLengthMatch {
134    pub min_hops: Option<i64>,
135    pub max_hops: Option<i64>,
136}
137
138#[derive(Debug, Clone, PartialEq)]
139pub struct RelationMatch {
140    pub direction: Direction,
141    pub annotation: Annotation,
142    pub variable_length: Option<VariableLengthMatch>,
143    pub labels: Vec<Arc<str>>,
144    pub property_predicates: Vec<Expression>,
145}
146
147impl RelationMatch {
148    pub fn either(
149        annotation: Annotation,
150        labels: Vec<Arc<str>>,
151        property_predicates: Vec<Expression>,
152        variable_length: Option<VariableLengthMatch>,
153    ) -> Self {
154        Self {
155            direction: Direction::Either,
156            annotation,
157            labels,
158            property_predicates,
159            variable_length,
160        }
161    }
162
163    pub fn left(
164        annotation: Annotation,
165        labels: Vec<Arc<str>>,
166        property_predicates: Vec<Expression>,
167        variable_length: Option<VariableLengthMatch>,
168    ) -> Self {
169        Self {
170            direction: Direction::Left,
171            annotation,
172            labels,
173            property_predicates,
174            variable_length,
175        }
176    }
177
178    pub fn right(
179        annotation: Annotation,
180        labels: Vec<Arc<str>>,
181        property_predicates: Vec<Expression>,
182        variable_length: Option<VariableLengthMatch>,
183    ) -> Self {
184        Self {
185            direction: Direction::Right,
186            annotation,
187            labels,
188            property_predicates,
189            variable_length,
190        }
191    }
192}
193
194#[derive(Debug, Clone, PartialEq)]
195pub enum Literal {
196    Integer(i64),
197    Real(f64),
198    Boolean(bool),
199    Text(Arc<str>),
200    Date(Arc<str>),
201    LocalTime(Arc<str>),
202    ZonedTime(Arc<str>),
203    LocalDateTime(Arc<str>),
204    ZonedDateTime(Arc<str>),
205    Duration(Arc<str>),
206    Object(Vec<(Arc<str>, Literal)>),
207    Expression(Box<Expression>),
208    Null,
209}
210
211impl std::hash::Hash for Literal {
212    fn hash<H: Hasher>(&self, state: &mut H) {
213        match self {
214            Literal::Integer(v) => v.hash(state),
215            Literal::Real(v) => v.to_bits().hash(state),
216            Literal::Boolean(v) => v.hash(state),
217            Literal::Text(v) => v.hash(state),
218            Literal::Date(v) => v.hash(state),
219            Literal::LocalTime(v) => v.hash(state),
220            Literal::ZonedTime(v) => v.hash(state),
221            Literal::LocalDateTime(v) => v.hash(state),
222            Literal::ZonedDateTime(v) => v.hash(state),
223            Literal::Duration(v) => v.hash(state),
224            Literal::Object(v) => v.hash(state),
225            Literal::Expression(v) => v.hash(state),
226            Literal::Null => state.write_u8(0),
227        }
228    }
229}
230
231impl Eq for Literal {}
232
233pub trait ParentExpression {
234    fn get_children(&self) -> Vec<&Expression>;
235}
236
237#[derive(Debug, Clone, PartialEq, Hash, Eq)]
238pub enum Expression {
239    UnaryExpression(UnaryExpression),
240    BinaryExpression(BinaryExpression),
241    FunctionExpression(FunctionExpression),
242    CaseExpression(CaseExpression),
243    ListExpression(ListExpression),
244    ObjectExpression(ObjectExpression), //do we really need this?
245    IteratorExpression(IteratorExpression),
246}
247
248impl ParentExpression for Expression {
249    fn get_children(&self) -> Vec<&Expression> {
250        match self {
251            Expression::UnaryExpression(expr) => expr.get_children(),
252            Expression::BinaryExpression(expr) => expr.get_children(),
253            Expression::FunctionExpression(expr) => expr.get_children(),
254            Expression::CaseExpression(expr) => expr.get_children(),
255            Expression::ListExpression(expr) => expr.get_children(),
256            Expression::ObjectExpression(expr) => expr.get_children(),
257            Expression::IteratorExpression(expr) => expr.get_children(),
258        }
259    }
260}
261
262#[derive(Debug, Clone, PartialEq, Hash, Eq)]
263pub enum UnaryExpression {
264    Not(Box<Expression>),
265    Exists(Box<Expression>),
266    IsNull(Box<Expression>),
267    IsNotNull(Box<Expression>),
268    Literal(Literal),
269    Property {
270        name: Arc<str>,
271        key: Arc<str>,
272    },
273    ExpressionProperty {
274        exp: Box<Expression>,
275        key: Arc<str>,
276    },
277    Parameter(Arc<str>),
278    Identifier(Arc<str>),
279    Variable {
280        name: Arc<str>,
281        value: Box<Expression>,
282    },
283    Alias {
284        source: Box<Expression>,
285        alias: Arc<str>,
286    },
287    ListRange {
288        //i64 instead of Expression?
289        start_bound: Option<Box<Expression>>,
290        end_bound: Option<Box<Expression>>,
291    },
292}
293
294impl UnaryExpression {
295    pub fn literal(value: Literal) -> Expression {
296        Expression::UnaryExpression(UnaryExpression::Literal(value))
297    }
298
299    pub fn parameter(name: Arc<str>) -> Expression {
300        Expression::UnaryExpression(UnaryExpression::Parameter(name))
301    }
302
303    pub fn property(name: Arc<str>, key: Arc<str>) -> Expression {
304        Expression::UnaryExpression(UnaryExpression::Property { name, key })
305    }
306
307    pub fn expression_property(exp: Expression, key: Arc<str>) -> Expression {
308        Expression::UnaryExpression(UnaryExpression::ExpressionProperty {
309            exp: Box::new(exp),
310            key,
311        })
312    }
313
314    pub fn alias(source: Expression, alias: Arc<str>) -> Expression {
315        Expression::UnaryExpression(Self::Alias {
316            source: Box::new(source),
317            alias,
318        })
319    }
320
321    pub fn not(cond: Expression) -> Expression {
322        Expression::UnaryExpression(Self::Not(Box::new(cond)))
323    }
324
325    pub fn ident(ident: &str) -> Expression {
326        Expression::UnaryExpression(Self::Identifier(ident.into()))
327    }
328
329    pub fn is_null(expr: Expression) -> Expression {
330        Expression::UnaryExpression(Self::IsNull(Box::new(expr)))
331    }
332
333    pub fn variable(name: Arc<str>, value: Expression) -> Expression {
334        Expression::UnaryExpression(Self::Variable {
335            name,
336            value: Box::new(value),
337        })
338    }
339
340    pub fn is_not_null(expr: Expression) -> Expression {
341        Expression::UnaryExpression(Self::IsNotNull(Box::new(expr)))
342    }
343    pub fn list_range(
344        start_bound: Option<Expression>,
345        end_bound: Option<Expression>,
346    ) -> Expression {
347        Expression::UnaryExpression(Self::ListRange {
348            start_bound: start_bound.map(Box::new),
349            end_bound: end_bound.map(Box::new),
350        })
351    }
352}
353
354impl ParentExpression for UnaryExpression {
355    fn get_children(&self) -> Vec<&Expression> {
356        match self {
357            UnaryExpression::Not(expr) => vec![expr],
358            UnaryExpression::Exists(expr) => vec![expr],
359            UnaryExpression::IsNull(expr) => vec![expr],
360            UnaryExpression::IsNotNull(expr) => vec![expr],
361            UnaryExpression::Literal(_) => Vec::new(),
362            UnaryExpression::Property { .. } => Vec::new(),
363            UnaryExpression::Parameter(_) => Vec::new(),
364            UnaryExpression::Identifier(_) => Vec::new(),
365            UnaryExpression::Variable { name: _, value } => vec![value],
366            UnaryExpression::Alias { source, .. } => vec![source],
367            UnaryExpression::ExpressionProperty { .. } => Vec::new(),
368            UnaryExpression::ListRange { .. } => Vec::new(),
369        }
370    }
371}
372
373#[derive(Debug, Clone, PartialEq, Hash, Eq)]
374pub enum BinaryExpression {
375    And(Box<Expression>, Box<Expression>),
376    Or(Box<Expression>, Box<Expression>),
377
378    Eq(Box<Expression>, Box<Expression>),
379    Ne(Box<Expression>, Box<Expression>),
380    Lt(Box<Expression>, Box<Expression>),
381    Le(Box<Expression>, Box<Expression>),
382    Gt(Box<Expression>, Box<Expression>),
383    Ge(Box<Expression>, Box<Expression>),
384    In(Box<Expression>, Box<Expression>),
385
386    Add(Box<Expression>, Box<Expression>),
387    Subtract(Box<Expression>, Box<Expression>),
388    Multiply(Box<Expression>, Box<Expression>),
389    Divide(Box<Expression>, Box<Expression>),
390    Modulo(Box<Expression>, Box<Expression>),
391    Exponent(Box<Expression>, Box<Expression>),
392    HasLabel(Box<Expression>, Box<Expression>),
393    Index(Box<Expression>, Box<Expression>),
394}
395
396impl BinaryExpression {
397    pub fn and(a: Expression, b: Expression) -> Expression {
398        Expression::BinaryExpression(Self::And(Box::new(a), Box::new(b)))
399    }
400
401    pub fn or(a: Expression, b: Expression) -> Expression {
402        Expression::BinaryExpression(Self::Or(Box::new(a), Box::new(b)))
403    }
404
405    pub fn eq(a: Expression, b: Expression) -> Expression {
406        Expression::BinaryExpression(Self::Eq(Box::new(a), Box::new(b)))
407    }
408
409    pub fn ne(a: Expression, b: Expression) -> Expression {
410        Expression::BinaryExpression(Self::Ne(Box::new(a), Box::new(b)))
411    }
412
413    pub fn lt(a: Expression, b: Expression) -> Expression {
414        Expression::BinaryExpression(Self::Lt(Box::new(a), Box::new(b)))
415    }
416
417    pub fn le(a: Expression, b: Expression) -> Expression {
418        Expression::BinaryExpression(Self::Le(Box::new(a), Box::new(b)))
419    }
420
421    pub fn gt(a: Expression, b: Expression) -> Expression {
422        Expression::BinaryExpression(Self::Gt(Box::new(a), Box::new(b)))
423    }
424
425    pub fn in_(a: Expression, b: Expression) -> Expression {
426        Expression::BinaryExpression(Self::In(Box::new(a), Box::new(b)))
427    }
428
429    pub fn ge(a: Expression, b: Expression) -> Expression {
430        Expression::BinaryExpression(Self::Ge(Box::new(a), Box::new(b)))
431    }
432
433    pub fn add(a: Expression, b: Expression) -> Expression {
434        Expression::BinaryExpression(Self::Add(Box::new(a), Box::new(b)))
435    }
436
437    pub fn subtract(a: Expression, b: Expression) -> Expression {
438        Expression::BinaryExpression(Self::Subtract(Box::new(a), Box::new(b)))
439    }
440
441    pub fn multiply(a: Expression, b: Expression) -> Expression {
442        Expression::BinaryExpression(Self::Multiply(Box::new(a), Box::new(b)))
443    }
444
445    pub fn divide(a: Expression, b: Expression) -> Expression {
446        Expression::BinaryExpression(Self::Divide(Box::new(a), Box::new(b)))
447    }
448
449    pub fn modulo(a: Expression, b: Expression) -> Expression {
450        Expression::BinaryExpression(Self::Modulo(Box::new(a), Box::new(b)))
451    }
452
453    pub fn exponent(a: Expression, b: Expression) -> Expression {
454        Expression::BinaryExpression(Self::Exponent(Box::new(a), Box::new(b)))
455    }
456
457    pub fn has_label(a: Expression, b: Expression) -> Expression {
458        Expression::BinaryExpression(Self::HasLabel(Box::new(a), Box::new(b)))
459    }
460
461    pub fn index(a: Expression, b: Expression) -> Expression {
462        Expression::BinaryExpression(Self::Index(Box::new(a), Box::new(b)))
463    }
464}
465
466impl ParentExpression for BinaryExpression {
467    fn get_children(&self) -> Vec<&Expression> {
468        match self {
469            BinaryExpression::And(a, b) => vec![a, b],
470            BinaryExpression::Or(a, b) => vec![a, b],
471            BinaryExpression::Eq(a, b) => vec![a, b],
472            BinaryExpression::Ne(a, b) => vec![a, b],
473            BinaryExpression::Lt(a, b) => vec![a, b],
474            BinaryExpression::Le(a, b) => vec![a, b],
475            BinaryExpression::Gt(a, b) => vec![a, b],
476            BinaryExpression::Ge(a, b) => vec![a, b],
477            BinaryExpression::In(a, b) => vec![a, b],
478            BinaryExpression::Add(a, b) => vec![a, b],
479            BinaryExpression::Subtract(a, b) => vec![a, b],
480            BinaryExpression::Multiply(a, b) => vec![a, b],
481            BinaryExpression::Divide(a, b) => vec![a, b],
482            BinaryExpression::Modulo(a, b) => vec![a, b],
483            BinaryExpression::Exponent(a, b) => vec![a, b],
484            BinaryExpression::HasLabel(a, b) => vec![a, b],
485            BinaryExpression::Index(a, b) => vec![a, b],
486        }
487    }
488}
489
490#[derive(Debug, Clone, PartialEq, Hash, Eq)]
491pub struct FunctionExpression {
492    pub name: Arc<str>,
493    pub args: Vec<Expression>,
494    pub position_in_query: usize,
495}
496
497impl FunctionExpression {
498    pub fn function(name: Arc<str>, args: Vec<Expression>, position_in_query: usize) -> Expression {
499        Expression::FunctionExpression(FunctionExpression {
500            name,
501            args,
502            position_in_query,
503        })
504    }
505}
506
507impl ParentExpression for FunctionExpression {
508    fn get_children(&self) -> Vec<&Expression> {
509        self.args.iter().collect()
510    }
511}
512
513#[derive(Debug, Clone, PartialEq, Hash, Eq)]
514pub struct CaseExpression {
515    pub match_: Option<Box<Expression>>,
516    pub when: Vec<(Expression, Expression)>,
517    pub else_: Option<Box<Expression>>,
518}
519
520impl CaseExpression {
521    pub fn case(
522        match_: Option<Expression>,
523        when: Vec<(Expression, Expression)>,
524        else_: Option<Expression>,
525    ) -> Expression {
526        Expression::CaseExpression(CaseExpression {
527            match_: match_.map(Box::new),
528            when,
529            else_: else_.map(Box::new),
530        })
531    }
532}
533
534impl ParentExpression for CaseExpression {
535    fn get_children(&self) -> Vec<&Expression> {
536        let mut children = Vec::new();
537        if let Some(match_) = &self.match_ {
538            children.push(match_.as_ref());
539        }
540        for (when, then) in &self.when {
541            children.push(when);
542            children.push(then);
543        }
544        if let Some(else_) = &self.else_ {
545            children.push(else_);
546        }
547        children
548    }
549}
550
551#[derive(Debug, Clone, PartialEq, Hash, Eq)]
552pub struct ObjectExpression {
553    pub elements: BTreeMap<Arc<str>, Expression>,
554}
555
556impl ObjectExpression {
557    pub fn object_from_vec(elements: Vec<(Arc<str>, Expression)>) -> Expression {
558        let mut map = BTreeMap::new();
559        for (key, value) in elements {
560            map.insert(key, value);
561        }
562        Expression::ObjectExpression(ObjectExpression { elements: map })
563    }
564
565    pub fn object(elements: BTreeMap<Arc<str>, Expression>) -> Expression {
566        Expression::ObjectExpression(ObjectExpression { elements })
567    }
568}
569
570impl ParentExpression for ObjectExpression {
571    fn get_children(&self) -> Vec<&Expression> {
572        let keys: Vec<_> = self.elements.values().clone().collect();
573
574        keys
575    }
576}
577
578#[derive(Debug, Clone, PartialEq, Hash, Eq)]
579pub struct ListExpression {
580    pub elements: Vec<Expression>,
581}
582
583impl ListExpression {
584    pub fn list(elements: Vec<Expression>) -> Expression {
585        Expression::ListExpression(ListExpression { elements })
586    }
587}
588
589impl ParentExpression for ListExpression {
590    fn get_children(&self) -> Vec<&Expression> {
591        let mut children = Vec::new();
592        for element in &self.elements {
593            children.push(element);
594        }
595
596        children
597    }
598}
599
600#[derive(Debug, Clone, PartialEq, Hash, Eq)]
601pub struct IteratorExpression {
602    pub item_identifier: Arc<str>,
603    pub list_expression: Box<Expression>,
604    pub filter: Option<Box<Expression>>,
605    pub map_expression: Option<Box<Expression>>,
606}
607
608impl IteratorExpression {
609    pub fn map(
610        item_identifier: Arc<str>,
611        list_expression: Expression,
612        map_expression: Expression,
613    ) -> Expression {
614        Expression::IteratorExpression(IteratorExpression {
615            item_identifier,
616            list_expression: Box::new(list_expression),
617            filter: None,
618            map_expression: Some(Box::new(map_expression)),
619        })
620    }
621
622    pub fn map_with_filter(
623        item_identifier: Arc<str>,
624        list_expression: Expression,
625        map_expression: Expression,
626        filter: Expression,
627    ) -> Expression {
628        Expression::IteratorExpression(IteratorExpression {
629            item_identifier,
630            list_expression: Box::new(list_expression),
631            filter: Some(Box::new(filter)),
632            map_expression: Some(Box::new(map_expression)),
633        })
634    }
635
636    pub fn iterator(item_identifier: Arc<str>, list_expression: Expression) -> Expression {
637        Expression::IteratorExpression(IteratorExpression {
638            item_identifier,
639            list_expression: Box::new(list_expression),
640            filter: None,
641            map_expression: None,
642        })
643    }
644
645    pub fn iterator_with_filter(
646        item_identifier: Arc<str>,
647        list_expression: Expression,
648        filter: Expression,
649    ) -> Expression {
650        Expression::IteratorExpression(IteratorExpression {
651            item_identifier,
652            list_expression: Box::new(list_expression),
653            filter: Some(Box::new(filter)),
654            map_expression: None,
655        })
656    }
657}
658
659impl ParentExpression for IteratorExpression {
660    fn get_children(&self) -> Vec<&Expression> {
661        let mut children = Vec::new();
662        children.push(&*self.list_expression);
663        if let Some(filter) = &self.filter {
664            children.push(filter);
665        }
666        children
667    }
668}