Skip to main content

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    StartsWith(Box<Expression>, Box<Expression>),
414    EndsWith(Box<Expression>, Box<Expression>),
415    Contains(Box<Expression>, Box<Expression>),
416}
417
418impl BinaryExpression {
419    pub fn and(a: Expression, b: Expression) -> Expression {
420        Expression::BinaryExpression(Self::And(Box::new(a), Box::new(b)))
421    }
422
423    pub fn or(a: Expression, b: Expression) -> Expression {
424        Expression::BinaryExpression(Self::Or(Box::new(a), Box::new(b)))
425    }
426
427    pub fn eq(a: Expression, b: Expression) -> Expression {
428        Expression::BinaryExpression(Self::Eq(Box::new(a), Box::new(b)))
429    }
430
431    pub fn ne(a: Expression, b: Expression) -> Expression {
432        Expression::BinaryExpression(Self::Ne(Box::new(a), Box::new(b)))
433    }
434
435    pub fn lt(a: Expression, b: Expression) -> Expression {
436        Expression::BinaryExpression(Self::Lt(Box::new(a), Box::new(b)))
437    }
438
439    pub fn le(a: Expression, b: Expression) -> Expression {
440        Expression::BinaryExpression(Self::Le(Box::new(a), Box::new(b)))
441    }
442
443    pub fn gt(a: Expression, b: Expression) -> Expression {
444        Expression::BinaryExpression(Self::Gt(Box::new(a), Box::new(b)))
445    }
446
447    pub fn in_(a: Expression, b: Expression) -> Expression {
448        Expression::BinaryExpression(Self::In(Box::new(a), Box::new(b)))
449    }
450
451    pub fn ge(a: Expression, b: Expression) -> Expression {
452        Expression::BinaryExpression(Self::Ge(Box::new(a), Box::new(b)))
453    }
454
455    pub fn add(a: Expression, b: Expression) -> Expression {
456        Expression::BinaryExpression(Self::Add(Box::new(a), Box::new(b)))
457    }
458
459    pub fn subtract(a: Expression, b: Expression) -> Expression {
460        Expression::BinaryExpression(Self::Subtract(Box::new(a), Box::new(b)))
461    }
462
463    pub fn multiply(a: Expression, b: Expression) -> Expression {
464        Expression::BinaryExpression(Self::Multiply(Box::new(a), Box::new(b)))
465    }
466
467    pub fn divide(a: Expression, b: Expression) -> Expression {
468        Expression::BinaryExpression(Self::Divide(Box::new(a), Box::new(b)))
469    }
470
471    pub fn modulo(a: Expression, b: Expression) -> Expression {
472        Expression::BinaryExpression(Self::Modulo(Box::new(a), Box::new(b)))
473    }
474
475    pub fn exponent(a: Expression, b: Expression) -> Expression {
476        Expression::BinaryExpression(Self::Exponent(Box::new(a), Box::new(b)))
477    }
478
479    pub fn has_label(a: Expression, b: Expression) -> Expression {
480        Expression::BinaryExpression(Self::HasLabel(Box::new(a), Box::new(b)))
481    }
482
483    pub fn index(a: Expression, b: Expression) -> Expression {
484        Expression::BinaryExpression(Self::Index(Box::new(a), Box::new(b)))
485    }
486
487    pub fn starts_with(a: Expression, b: Expression) -> Expression {
488        Expression::BinaryExpression(Self::StartsWith(Box::new(a), Box::new(b)))
489    }
490
491    pub fn ends_with(a: Expression, b: Expression) -> Expression {
492        Expression::BinaryExpression(Self::EndsWith(Box::new(a), Box::new(b)))
493    }
494
495    pub fn contains(a: Expression, b: Expression) -> Expression {
496        Expression::BinaryExpression(Self::Contains(Box::new(a), Box::new(b)))
497    }
498}
499
500impl ParentExpression for BinaryExpression {
501    fn get_children(&self) -> Vec<&Expression> {
502        match self {
503            BinaryExpression::And(a, b) => vec![a, b],
504            BinaryExpression::Or(a, b) => vec![a, b],
505            BinaryExpression::Eq(a, b) => vec![a, b],
506            BinaryExpression::Ne(a, b) => vec![a, b],
507            BinaryExpression::Lt(a, b) => vec![a, b],
508            BinaryExpression::Le(a, b) => vec![a, b],
509            BinaryExpression::Gt(a, b) => vec![a, b],
510            BinaryExpression::Ge(a, b) => vec![a, b],
511            BinaryExpression::In(a, b) => vec![a, b],
512            BinaryExpression::Add(a, b) => vec![a, b],
513            BinaryExpression::Subtract(a, b) => vec![a, b],
514            BinaryExpression::Multiply(a, b) => vec![a, b],
515            BinaryExpression::Divide(a, b) => vec![a, b],
516            BinaryExpression::Modulo(a, b) => vec![a, b],
517            BinaryExpression::Exponent(a, b) => vec![a, b],
518            BinaryExpression::HasLabel(a, b) => vec![a, b],
519            BinaryExpression::Index(a, b) => vec![a, b],
520            BinaryExpression::StartsWith(a, b) => vec![a, b],
521            BinaryExpression::EndsWith(a, b) => vec![a, b],
522            BinaryExpression::Contains(a, b) => vec![a, b],
523        }
524    }
525}
526
527#[derive(Debug, Clone, PartialEq, Hash, Eq)]
528pub struct FunctionExpression {
529    pub name: Arc<str>,
530    pub args: Vec<Expression>,
531    pub position_in_query: usize,
532}
533
534impl FunctionExpression {
535    pub fn function(name: Arc<str>, args: Vec<Expression>, position_in_query: usize) -> Expression {
536        Expression::FunctionExpression(FunctionExpression {
537            name,
538            args,
539            position_in_query,
540        })
541    }
542
543    pub fn eq_ignore_position_in_query(&self, other: &Self) -> bool {
544        self.name == other.name && self.args == other.args
545    }
546}
547
548impl ParentExpression for FunctionExpression {
549    fn get_children(&self) -> Vec<&Expression> {
550        self.args.iter().collect()
551    }
552}
553
554#[derive(Debug, Clone, PartialEq, Hash, Eq)]
555pub struct CaseExpression {
556    pub match_: Option<Box<Expression>>,
557    pub when: Vec<(Expression, Expression)>,
558    pub else_: Option<Box<Expression>>,
559}
560
561impl CaseExpression {
562    pub fn case(
563        match_: Option<Expression>,
564        when: Vec<(Expression, Expression)>,
565        else_: Option<Expression>,
566    ) -> Expression {
567        Expression::CaseExpression(CaseExpression {
568            match_: match_.map(Box::new),
569            when,
570            else_: else_.map(Box::new),
571        })
572    }
573}
574
575impl ParentExpression for CaseExpression {
576    fn get_children(&self) -> Vec<&Expression> {
577        let mut children = Vec::new();
578        if let Some(match_) = &self.match_ {
579            children.push(match_.as_ref());
580        }
581        for (when, then) in &self.when {
582            children.push(when);
583            children.push(then);
584        }
585        if let Some(else_) = &self.else_ {
586            children.push(else_);
587        }
588        children
589    }
590}
591
592#[derive(Debug, Clone, PartialEq, Hash, Eq)]
593pub struct ObjectExpression {
594    pub elements: BTreeMap<Arc<str>, Expression>,
595}
596
597impl ObjectExpression {
598    pub fn object_from_vec(elements: Vec<(Arc<str>, Expression)>) -> Expression {
599        let mut map = BTreeMap::new();
600        for (key, value) in elements {
601            map.insert(key, value);
602        }
603        Expression::ObjectExpression(ObjectExpression { elements: map })
604    }
605
606    pub fn object(elements: BTreeMap<Arc<str>, Expression>) -> Expression {
607        Expression::ObjectExpression(ObjectExpression { elements })
608    }
609}
610
611impl ParentExpression for ObjectExpression {
612    fn get_children(&self) -> Vec<&Expression> {
613        let keys: Vec<_> = self.elements.values().clone().collect();
614
615        keys
616    }
617}
618
619#[derive(Debug, Clone, PartialEq, Hash, Eq)]
620pub struct ListExpression {
621    pub elements: Vec<Expression>,
622}
623
624impl ListExpression {
625    pub fn list(elements: Vec<Expression>) -> Expression {
626        Expression::ListExpression(ListExpression { elements })
627    }
628}
629
630impl ParentExpression for ListExpression {
631    fn get_children(&self) -> Vec<&Expression> {
632        let mut children = Vec::new();
633        for element in &self.elements {
634            children.push(element);
635        }
636
637        children
638    }
639}
640
641#[derive(Debug, Clone, PartialEq, Hash, Eq)]
642pub struct IteratorExpression {
643    pub item_identifier: Arc<str>,
644    pub list_expression: Box<Expression>,
645    pub filter: Option<Box<Expression>>,
646    pub map_expression: Option<Box<Expression>>,
647}
648
649impl IteratorExpression {
650    pub fn map(
651        item_identifier: Arc<str>,
652        list_expression: Expression,
653        map_expression: Expression,
654    ) -> Expression {
655        Expression::IteratorExpression(IteratorExpression {
656            item_identifier,
657            list_expression: Box::new(list_expression),
658            filter: None,
659            map_expression: Some(Box::new(map_expression)),
660        })
661    }
662
663    pub fn map_with_filter(
664        item_identifier: Arc<str>,
665        list_expression: Expression,
666        map_expression: Expression,
667        filter: Expression,
668    ) -> Expression {
669        Expression::IteratorExpression(IteratorExpression {
670            item_identifier,
671            list_expression: Box::new(list_expression),
672            filter: Some(Box::new(filter)),
673            map_expression: Some(Box::new(map_expression)),
674        })
675    }
676
677    pub fn iterator(item_identifier: Arc<str>, list_expression: Expression) -> Expression {
678        Expression::IteratorExpression(IteratorExpression {
679            item_identifier,
680            list_expression: Box::new(list_expression),
681            filter: None,
682            map_expression: None,
683        })
684    }
685
686    pub fn iterator_with_filter(
687        item_identifier: Arc<str>,
688        list_expression: Expression,
689        filter: Expression,
690    ) -> Expression {
691        Expression::IteratorExpression(IteratorExpression {
692            item_identifier,
693            list_expression: Box::new(list_expression),
694            filter: Some(Box::new(filter)),
695            map_expression: None,
696        })
697    }
698}
699
700impl ParentExpression for IteratorExpression {
701    fn get_children(&self) -> Vec<&Expression> {
702        let mut children = Vec::new();
703        children.push(&*self.list_expression);
704        if let Some(filter) = &self.filter {
705            children.push(filter);
706        }
707        children
708    }
709}