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