gitql_ast/
expression.rs

1use std::any::Any;
2
3use dyn_clone::DynClone;
4
5use super::types::array::ArrayType;
6use super::types::boolean::BoolType;
7use super::types::integer::IntType;
8use super::types::null::NullType;
9use super::types::text::TextType;
10use super::types::DataType;
11
12use crate::interval::Interval;
13use crate::operator::ArithmeticOperator;
14use crate::operator::BinaryBitwiseOperator;
15use crate::operator::BinaryLogicalOperator;
16use crate::operator::ComparisonOperator;
17use crate::operator::GroupComparisonOperator;
18use crate::operator::PrefixUnaryOperator;
19use crate::types::float::FloatType;
20use crate::types::interval::IntervalType;
21
22#[derive(PartialEq)]
23pub enum ExprKind {
24    Assignment,
25    String,
26    Symbol,
27    Array,
28    GlobalVariable,
29    Number,
30    Boolean,
31    Interval,
32    PrefixUnary,
33    Index,
34    Slice,
35    Arithmetic,
36    Comparison,
37    GroupComparison,
38    Contains,
39    ContainedBy,
40    Like,
41    Regex,
42    Glob,
43    Logical,
44    Bitwise,
45    Call,
46    BenchmarkCall,
47    Between,
48    Case,
49    In,
50    IsNull,
51    Null,
52    Cast,
53    Grouping,
54    MemberAccess,
55}
56
57dyn_clone::clone_trait_object!(Expr);
58
59pub trait Expr: DynClone {
60    fn kind(&self) -> ExprKind;
61    fn expr_type(&self) -> Box<dyn DataType>;
62    fn as_any(&self) -> &dyn Any;
63}
64
65impl dyn Expr {
66    pub fn is_const(&self) -> bool {
67        matches!(
68            self.kind(),
69            ExprKind::Number | ExprKind::Boolean | ExprKind::String | ExprKind::Null
70        )
71    }
72}
73
74#[derive(Clone)]
75pub struct AssignmentExpr {
76    pub symbol: String,
77    pub value: Box<dyn Expr>,
78}
79
80impl Expr for AssignmentExpr {
81    fn kind(&self) -> ExprKind {
82        ExprKind::Assignment
83    }
84
85    fn expr_type(&self) -> Box<dyn DataType> {
86        self.value.expr_type()
87    }
88
89    fn as_any(&self) -> &dyn Any {
90        self
91    }
92}
93
94#[derive(Clone)]
95pub struct StringExpr {
96    pub value: String,
97}
98
99impl Expr for StringExpr {
100    fn kind(&self) -> ExprKind {
101        ExprKind::String
102    }
103
104    fn expr_type(&self) -> Box<dyn DataType> {
105        Box::new(TextType)
106    }
107
108    fn as_any(&self) -> &dyn Any {
109        self
110    }
111}
112
113#[derive(PartialEq, Clone)]
114pub enum SymbolFlag {
115    AggregationReference,
116    WindowReference,
117    None,
118}
119
120#[derive(Clone)]
121pub struct SymbolExpr {
122    pub value: String,
123    pub expr_type: Box<dyn DataType>,
124    pub flag: SymbolFlag,
125}
126
127impl Expr for SymbolExpr {
128    fn kind(&self) -> ExprKind {
129        ExprKind::Symbol
130    }
131
132    fn expr_type(&self) -> Box<dyn DataType> {
133        self.expr_type.clone()
134    }
135
136    fn as_any(&self) -> &dyn Any {
137        self
138    }
139}
140
141#[derive(Clone)]
142pub struct ArrayExpr {
143    pub values: Vec<Box<dyn Expr>>,
144    pub element_type: Box<dyn DataType>,
145}
146
147impl Expr for ArrayExpr {
148    fn kind(&self) -> ExprKind {
149        ExprKind::Array
150    }
151
152    fn expr_type(&self) -> Box<dyn DataType> {
153        Box::new(ArrayType::new(self.element_type.clone()))
154    }
155
156    fn as_any(&self) -> &dyn Any {
157        self
158    }
159}
160
161#[derive(Clone)]
162pub struct GlobalVariableExpr {
163    pub name: String,
164    pub result_type: Box<dyn DataType>,
165}
166
167impl Expr for GlobalVariableExpr {
168    fn kind(&self) -> ExprKind {
169        ExprKind::GlobalVariable
170    }
171
172    fn expr_type(&self) -> Box<dyn DataType> {
173        self.result_type.clone()
174    }
175
176    fn as_any(&self) -> &dyn Any {
177        self
178    }
179}
180
181#[derive(Clone, PartialEq)]
182pub enum Number {
183    Int(i64),
184    Float(f64),
185}
186
187#[derive(Clone)]
188pub struct NumberExpr {
189    pub value: Number,
190}
191
192impl Expr for NumberExpr {
193    fn kind(&self) -> ExprKind {
194        ExprKind::Number
195    }
196
197    fn expr_type(&self) -> Box<dyn DataType> {
198        match self.value {
199            Number::Int(_) => Box::new(IntType),
200            Number::Float(_) => Box::new(FloatType),
201        }
202    }
203
204    fn as_any(&self) -> &dyn Any {
205        self
206    }
207}
208
209#[derive(Clone)]
210pub struct IntervalExpr {
211    pub interval: Interval,
212}
213
214impl IntervalExpr {
215    pub fn new(interval: Interval) -> Self {
216        IntervalExpr { interval }
217    }
218}
219
220impl Expr for IntervalExpr {
221    fn kind(&self) -> ExprKind {
222        ExprKind::Interval
223    }
224
225    fn expr_type(&self) -> Box<dyn DataType> {
226        Box::new(IntervalType)
227    }
228
229    fn as_any(&self) -> &dyn Any {
230        self
231    }
232}
233
234#[derive(Clone)]
235pub struct BooleanExpr {
236    pub is_true: bool,
237}
238
239impl Expr for BooleanExpr {
240    fn kind(&self) -> ExprKind {
241        ExprKind::Boolean
242    }
243
244    fn expr_type(&self) -> Box<dyn DataType> {
245        Box::new(BoolType)
246    }
247
248    fn as_any(&self) -> &dyn Any {
249        self
250    }
251}
252
253#[derive(Clone)]
254pub struct UnaryExpr {
255    pub right: Box<dyn Expr>,
256    pub operator: PrefixUnaryOperator,
257    pub result_type: Box<dyn DataType>,
258}
259
260impl Expr for UnaryExpr {
261    fn kind(&self) -> ExprKind {
262        ExprKind::PrefixUnary
263    }
264
265    fn expr_type(&self) -> Box<dyn DataType> {
266        self.result_type.clone()
267    }
268
269    fn as_any(&self) -> &dyn Any {
270        self
271    }
272}
273
274#[derive(Clone)]
275pub struct IndexExpr {
276    pub collection: Box<dyn Expr>,
277    pub element_type: Box<dyn DataType>,
278    pub index: Box<dyn Expr>,
279    pub result_type: Box<dyn DataType>,
280}
281
282impl Expr for IndexExpr {
283    fn kind(&self) -> ExprKind {
284        ExprKind::Index
285    }
286
287    fn expr_type(&self) -> Box<dyn DataType> {
288        self.result_type.clone()
289    }
290
291    fn as_any(&self) -> &dyn Any {
292        self
293    }
294}
295
296#[derive(Clone)]
297pub struct SliceExpr {
298    pub collection: Box<dyn Expr>,
299    pub start: Option<Box<dyn Expr>>,
300    pub end: Option<Box<dyn Expr>>,
301    pub result_type: Box<dyn DataType>,
302}
303
304impl Expr for SliceExpr {
305    fn kind(&self) -> ExprKind {
306        ExprKind::Slice
307    }
308
309    fn expr_type(&self) -> Box<dyn DataType> {
310        self.result_type.clone()
311    }
312
313    fn as_any(&self) -> &dyn Any {
314        self
315    }
316}
317
318#[derive(Clone)]
319pub struct ArithmeticExpr {
320    pub left: Box<dyn Expr>,
321    pub operator: ArithmeticOperator,
322    pub right: Box<dyn Expr>,
323    pub result_type: Box<dyn DataType>,
324}
325
326impl Expr for ArithmeticExpr {
327    fn kind(&self) -> ExprKind {
328        ExprKind::Arithmetic
329    }
330
331    fn expr_type(&self) -> Box<dyn DataType> {
332        self.result_type.clone()
333    }
334
335    fn as_any(&self) -> &dyn Any {
336        self
337    }
338}
339
340#[derive(Clone)]
341pub struct ComparisonExpr {
342    pub left: Box<dyn Expr>,
343    pub operator: ComparisonOperator,
344    pub right: Box<dyn Expr>,
345}
346
347impl Expr for ComparisonExpr {
348    fn kind(&self) -> ExprKind {
349        ExprKind::Comparison
350    }
351
352    fn expr_type(&self) -> Box<dyn DataType> {
353        if self.operator == ComparisonOperator::NullSafeEqual {
354            Box::new(IntType)
355        } else {
356            Box::new(BoolType)
357        }
358    }
359
360    fn as_any(&self) -> &dyn Any {
361        self
362    }
363}
364
365#[derive(Clone)]
366pub struct GroupComparisonExpr {
367    pub left: Box<dyn Expr>,
368    pub comparison_operator: ComparisonOperator,
369    pub group_operator: GroupComparisonOperator,
370    pub right: Box<dyn Expr>,
371}
372
373impl Expr for GroupComparisonExpr {
374    fn kind(&self) -> ExprKind {
375        ExprKind::GroupComparison
376    }
377
378    fn expr_type(&self) -> Box<dyn DataType> {
379        if self.comparison_operator == ComparisonOperator::NullSafeEqual {
380            Box::new(IntType)
381        } else {
382            Box::new(BoolType)
383        }
384    }
385
386    fn as_any(&self) -> &dyn Any {
387        self
388    }
389}
390
391#[derive(Clone)]
392pub struct ContainsExpr {
393    pub left: Box<dyn Expr>,
394    pub right: Box<dyn Expr>,
395}
396
397impl Expr for ContainsExpr {
398    fn kind(&self) -> ExprKind {
399        ExprKind::Contains
400    }
401
402    fn expr_type(&self) -> Box<dyn DataType> {
403        Box::new(BoolType)
404    }
405
406    fn as_any(&self) -> &dyn Any {
407        self
408    }
409}
410
411#[derive(Clone)]
412pub struct ContainedByExpr {
413    pub left: Box<dyn Expr>,
414    pub right: Box<dyn Expr>,
415}
416
417impl Expr for ContainedByExpr {
418    fn kind(&self) -> ExprKind {
419        ExprKind::ContainedBy
420    }
421
422    fn expr_type(&self) -> Box<dyn DataType> {
423        Box::new(BoolType)
424    }
425
426    fn as_any(&self) -> &dyn Any {
427        self
428    }
429}
430
431#[derive(Clone)]
432pub struct LikeExpr {
433    pub input: Box<dyn Expr>,
434    pub pattern: Box<dyn Expr>,
435}
436
437impl Expr for LikeExpr {
438    fn kind(&self) -> ExprKind {
439        ExprKind::Like
440    }
441
442    fn expr_type(&self) -> Box<dyn DataType> {
443        Box::new(BoolType)
444    }
445
446    fn as_any(&self) -> &dyn Any {
447        self
448    }
449}
450
451#[derive(Clone)]
452pub struct RegexExpr {
453    pub input: Box<dyn Expr>,
454    pub pattern: Box<dyn Expr>,
455}
456
457impl Expr for RegexExpr {
458    fn kind(&self) -> ExprKind {
459        ExprKind::Regex
460    }
461
462    fn expr_type(&self) -> Box<dyn DataType> {
463        Box::new(BoolType)
464    }
465
466    fn as_any(&self) -> &dyn Any {
467        self
468    }
469}
470
471#[derive(Clone)]
472pub struct GlobExpr {
473    pub input: Box<dyn Expr>,
474    pub pattern: Box<dyn Expr>,
475}
476
477impl Expr for GlobExpr {
478    fn kind(&self) -> ExprKind {
479        ExprKind::Glob
480    }
481
482    fn expr_type(&self) -> Box<dyn DataType> {
483        Box::new(BoolType)
484    }
485
486    fn as_any(&self) -> &dyn Any {
487        self
488    }
489}
490
491#[derive(Clone)]
492pub struct LogicalExpr {
493    pub left: Box<dyn Expr>,
494    pub operator: BinaryLogicalOperator,
495    pub right: Box<dyn Expr>,
496}
497
498impl Expr for LogicalExpr {
499    fn kind(&self) -> ExprKind {
500        ExprKind::Logical
501    }
502
503    fn expr_type(&self) -> Box<dyn DataType> {
504        let lhs_type = self.left.expr_type();
505        let rhs_type = &self.right.expr_type();
506        match self.operator {
507            BinaryLogicalOperator::Or => lhs_type.logical_or_op_result_type(rhs_type),
508            BinaryLogicalOperator::And => lhs_type.logical_and_op_result_type(rhs_type),
509            BinaryLogicalOperator::Xor => lhs_type.logical_xor_op_result_type(rhs_type),
510        }
511    }
512
513    fn as_any(&self) -> &dyn Any {
514        self
515    }
516}
517
518#[derive(Clone)]
519pub struct BitwiseExpr {
520    pub left: Box<dyn Expr>,
521    pub operator: BinaryBitwiseOperator,
522    pub right: Box<dyn Expr>,
523    pub result_type: Box<dyn DataType>,
524}
525
526impl Expr for BitwiseExpr {
527    fn kind(&self) -> ExprKind {
528        ExprKind::Bitwise
529    }
530
531    fn expr_type(&self) -> Box<dyn DataType> {
532        self.result_type.clone()
533    }
534
535    fn as_any(&self) -> &dyn Any {
536        self
537    }
538}
539
540#[derive(Clone)]
541pub struct CallExpr {
542    pub function_name: String,
543    pub arguments: Vec<Box<dyn Expr>>,
544    pub return_type: Box<dyn DataType>,
545}
546
547impl Expr for CallExpr {
548    fn kind(&self) -> ExprKind {
549        ExprKind::Call
550    }
551
552    fn expr_type(&self) -> Box<dyn DataType> {
553        self.return_type.clone()
554    }
555
556    fn as_any(&self) -> &dyn Any {
557        self
558    }
559}
560
561#[derive(Clone)]
562pub struct BenchmarkCallExpr {
563    pub expression: Box<dyn Expr>,
564    pub count: Box<dyn Expr>,
565}
566
567impl Expr for BenchmarkCallExpr {
568    fn kind(&self) -> ExprKind {
569        ExprKind::BenchmarkCall
570    }
571
572    fn expr_type(&self) -> Box<dyn DataType> {
573        Box::new(IntType)
574    }
575
576    fn as_any(&self) -> &dyn Any {
577        self
578    }
579}
580
581/// ASYMMETRIC is default. ASYMMETRIC is noise, it's current behavior.
582/// If b <= c, then SYMMETRIC and ASYMMETRIC work the same way.
583/// If b > c, then SYMMETRIC in effect reverses the operands.
584#[derive(PartialEq, Clone)]
585pub enum BetweenKind {
586    Symmetric,
587    Asymmetric,
588}
589
590#[derive(Clone)]
591pub struct BetweenExpr {
592    pub value: Box<dyn Expr>,
593    pub range_start: Box<dyn Expr>,
594    pub range_end: Box<dyn Expr>,
595    pub kind: BetweenKind,
596}
597
598impl Expr for BetweenExpr {
599    fn kind(&self) -> ExprKind {
600        ExprKind::Between
601    }
602
603    fn expr_type(&self) -> Box<dyn DataType> {
604        Box::new(BoolType)
605    }
606
607    fn as_any(&self) -> &dyn Any {
608        self
609    }
610}
611
612#[derive(Clone)]
613pub struct CaseExpr {
614    pub conditions: Vec<Box<dyn Expr>>,
615    pub values: Vec<Box<dyn Expr>>,
616    pub default_value: Option<Box<dyn Expr>>,
617    pub values_type: Box<dyn DataType>,
618}
619
620impl Expr for CaseExpr {
621    fn kind(&self) -> ExprKind {
622        ExprKind::Case
623    }
624
625    fn expr_type(&self) -> Box<dyn DataType> {
626        self.values_type.clone()
627    }
628
629    fn as_any(&self) -> &dyn Any {
630        self
631    }
632}
633
634#[derive(Clone)]
635pub struct InExpr {
636    pub argument: Box<dyn Expr>,
637    pub values: Vec<Box<dyn Expr>>,
638    pub values_type: Box<dyn DataType>,
639    pub has_not_keyword: bool,
640}
641
642impl Expr for InExpr {
643    fn kind(&self) -> ExprKind {
644        ExprKind::In
645    }
646
647    fn expr_type(&self) -> Box<dyn DataType> {
648        self.values_type.clone()
649    }
650
651    fn as_any(&self) -> &dyn Any {
652        self
653    }
654}
655
656#[derive(Clone)]
657pub struct IsNullExpr {
658    pub argument: Box<dyn Expr>,
659    pub has_not: bool,
660}
661
662impl Expr for IsNullExpr {
663    fn kind(&self) -> ExprKind {
664        ExprKind::IsNull
665    }
666
667    fn expr_type(&self) -> Box<dyn DataType> {
668        Box::new(BoolType)
669    }
670
671    fn as_any(&self) -> &dyn Any {
672        self
673    }
674}
675
676#[derive(Clone)]
677pub struct NullExpr;
678
679impl Expr for NullExpr {
680    fn kind(&self) -> ExprKind {
681        ExprKind::Null
682    }
683
684    fn expr_type(&self) -> Box<dyn DataType> {
685        Box::new(NullType)
686    }
687
688    fn as_any(&self) -> &dyn Any {
689        self
690    }
691}
692
693#[derive(Clone)]
694pub struct CastExpr {
695    pub value: Box<dyn Expr>,
696    pub result_type: Box<dyn DataType>,
697}
698
699impl Expr for CastExpr {
700    fn kind(&self) -> ExprKind {
701        ExprKind::Cast
702    }
703
704    fn expr_type(&self) -> Box<dyn DataType> {
705        self.result_type.clone()
706    }
707
708    fn as_any(&self) -> &dyn Any {
709        self
710    }
711}
712
713#[derive(Clone)]
714pub struct GroupExpr {
715    pub expr: Box<dyn Expr>,
716}
717
718impl Expr for GroupExpr {
719    fn kind(&self) -> ExprKind {
720        ExprKind::Grouping
721    }
722
723    fn expr_type(&self) -> Box<dyn DataType> {
724        self.expr.expr_type().clone()
725    }
726
727    fn as_any(&self) -> &dyn Any {
728        self
729    }
730}
731
732#[derive(Clone)]
733pub struct MemberAccessExpr {
734    pub composite: Box<dyn Expr>,
735    pub member_name: String,
736    pub member_type: Box<dyn DataType>,
737}
738
739impl Expr for MemberAccessExpr {
740    fn kind(&self) -> ExprKind {
741        ExprKind::MemberAccess
742    }
743
744    fn expr_type(&self) -> Box<dyn DataType> {
745        self.member_type.clone()
746    }
747
748    fn as_any(&self) -> &dyn Any {
749        self
750    }
751}