gitql_ast/types/
base.rs

1use std::any::Any;
2use std::fmt;
3
4use dyn_clone::DynClone;
5
6use crate::expression::Expr;
7
8use super::any::AnyType;
9use super::array::ArrayType;
10use super::boolean::BoolType;
11use super::composite::CompositeType;
12use super::date::DateType;
13use super::datetime::DateTimeType;
14use super::float::FloatType;
15use super::integer::IntType;
16use super::interval::IntervalType;
17use super::null::NullType;
18use super::optional::OptionType;
19use super::range::RangeType;
20use super::text::TextType;
21use super::time::TimeType;
22use super::undefined::UndefType;
23use super::varargs::VarargsType;
24use super::variant::VariantType;
25
26dyn_clone::clone_trait_object!(DataType);
27
28/// The in memory representation of the Data type in the GitQL query engine
29pub trait DataType: DynClone {
30    /// Return the literal representation for this [`DataType`]
31    fn literal(&self) -> String;
32
33    /// Return if other [`DataType`] is equal or not to current Type
34    #[allow(unused_variables)]
35    #[allow(clippy::borrowed_box)]
36    fn equals(&self, other: &Box<dyn DataType>) -> bool {
37        false
38    }
39
40    /// Return the current value as dynamic [`Any`]
41    fn as_any(&self) -> &dyn Any;
42
43    /// Return a list of types that it's possible to perform `+` operator with
44    /// between current DataType and any one of them
45    fn can_perform_add_op_with(&self) -> Vec<Box<dyn DataType>> {
46        vec![]
47    }
48
49    /// Return the expected type after perform `=` operator between current type and argument type
50    ///
51    /// Note that you don't need to check again that the argument type is possible to perform operator with
52    #[allow(unused_variables)]
53    #[allow(clippy::borrowed_box)]
54    fn add_op_result_type(&self, other: &Box<dyn DataType>) -> Box<dyn DataType> {
55        Box::new(NullType)
56    }
57
58    /// Return a list of types that it's possible to perform `-` operator with
59    /// between current DataType and any one of them
60    #[allow(unused_variables)]
61    #[allow(clippy::borrowed_box)]
62    fn can_perform_sub_op_with(&self) -> Vec<Box<dyn DataType>> {
63        vec![]
64    }
65
66    /// Return the expected type after perform `-` operator between current type and argument type
67    ///
68    /// Note that you don't need to check again that the argument type is possible to perform operator with
69    #[allow(unused_variables)]
70    #[allow(clippy::borrowed_box)]
71    fn sub_op_result_type(&self, other: &Box<dyn DataType>) -> Box<dyn DataType> {
72        Box::new(NullType)
73    }
74
75    /// Return a list of types that it's possible to perform `*` operator with
76    /// between current DataType and any one of them
77    fn can_perform_mul_op_with(&self) -> Vec<Box<dyn DataType>> {
78        vec![]
79    }
80
81    /// Return the expected type after perform `*` operator between current type and argument type
82    ///
83    /// Note that you don't need to check again that the argument type is possible to perform operator with
84    #[allow(unused_variables)]
85    #[allow(clippy::borrowed_box)]
86    fn mul_op_result_type(&self, other: &Box<dyn DataType>) -> Box<dyn DataType> {
87        Box::new(NullType)
88    }
89
90    /// Return a list of types that it's possible to perform `/` operator with
91    /// between current DataType and any one of them
92    fn can_perform_div_op_with(&self) -> Vec<Box<dyn DataType>> {
93        vec![]
94    }
95
96    /// Return the expected type after perform `/` operator between current type and argument type
97    ///
98    /// Note that you don't need to check again that the argument type is possible to perform operator with
99    #[allow(unused_variables)]
100    #[allow(clippy::borrowed_box)]
101    fn div_op_result_type(&self, other: &Box<dyn DataType>) -> Box<dyn DataType> {
102        Box::new(NullType)
103    }
104
105    /// Return a list of types that it's possible to perform `%` operator with
106    /// between current DataType and any one of them
107    fn can_perform_rem_op_with(&self) -> Vec<Box<dyn DataType>> {
108        vec![]
109    }
110
111    /// Return the expected type after perform `&` operator between current type and argument type
112    ///
113    /// Note that you don't need to check again that the argument type is possible to perform operator with
114    #[allow(unused_variables)]
115    #[allow(clippy::borrowed_box)]
116    fn rem_op_result_type(&self, other: &Box<dyn DataType>) -> Box<dyn DataType> {
117        Box::new(NullType)
118    }
119
120    /// Return a list of types that it's possible to perform `^` operator with
121    /// between current DataType and any one of them
122    fn can_perform_caret_op_with(&self) -> Vec<Box<dyn DataType>> {
123        vec![]
124    }
125
126    /// Return the expected type after perform `^` operator between current type and argument type
127    ///
128    /// Note that you don't need to check again that the argument type is possible to perform operator with
129    #[allow(unused_variables)]
130    #[allow(clippy::borrowed_box)]
131    fn caret_op_result_type(&self, other: &Box<dyn DataType>) -> Box<dyn DataType> {
132        Box::new(NullType)
133    }
134
135    /// Return a list of types that it's possible to perform `|` operator with
136    /// between current DataType and any one of them
137    fn can_perform_or_op_with(&self) -> Vec<Box<dyn DataType>> {
138        vec![]
139    }
140
141    /// Return the expected type after perform `|` operator between current type and argument type
142    ///
143    /// Note that you don't need to check again that the argument type is possible to perform operator with
144    #[allow(unused_variables)]
145    #[allow(clippy::borrowed_box)]
146    fn or_op_result_type(&self, other: &Box<dyn DataType>) -> Box<dyn DataType> {
147        Box::new(NullType)
148    }
149
150    /// Return a list of types that it's possible to perform `&` operator with
151    /// between current DataType and any one of them
152    fn can_perform_and_op_with(&self) -> Vec<Box<dyn DataType>> {
153        vec![]
154    }
155
156    /// Return the expected type after perform `&` operator between current type and argument type
157    ///
158    /// Note that you don't need to check again that the argument type is possible to perform operator with
159    #[allow(unused_variables)]
160    #[allow(clippy::borrowed_box)]
161    fn and_op_result_type(&self, other: &Box<dyn DataType>) -> Box<dyn DataType> {
162        Box::new(NullType)
163    }
164
165    /// Return a list of types that it's possible to perform `#` operator with
166    /// between current DataType and any one of them
167    fn can_perform_xor_op_with(&self) -> Vec<Box<dyn DataType>> {
168        vec![]
169    }
170
171    /// Return the expected type after perform `#` operator between current type and argument type
172    ///
173    /// Note that you don't need to check again that the argument type is possible to perform operator with
174    #[allow(unused_variables)]
175    #[allow(clippy::borrowed_box)]
176    fn xor_op_result_type(&self, other: &Box<dyn DataType>) -> Box<dyn DataType> {
177        Box::new(NullType)
178    }
179
180    /// Return a list of types that it's possible to perform `<<` operator with
181    /// between current DataType and any one of them
182    fn can_perform_shl_op_with(&self) -> Vec<Box<dyn DataType>> {
183        vec![]
184    }
185
186    /// Return the expected type after perform `<<` operator between current type and argument type
187    ///
188    /// Note that you don't need to check again that the argument type is possible to perform operator with
189    #[allow(unused_variables)]
190    #[allow(clippy::borrowed_box)]
191    fn shl_op_result_type(&self, other: &Box<dyn DataType>) -> Box<dyn DataType> {
192        Box::new(NullType)
193    }
194
195    /// Return a list of types that it's possible to perform `>>` operator with
196    /// between current DataType and any one of them
197    fn can_perform_shr_op_with(&self) -> Vec<Box<dyn DataType>> {
198        vec![]
199    }
200
201    /// Return the expected type after perform `>>` operator between current type and argument type
202    ///
203    /// Note that you don't need to check again that the argument type is possible to perform operator with
204    #[allow(unused_variables)]
205    #[allow(clippy::borrowed_box)]
206    fn shr_op_result_type(&self, other: &Box<dyn DataType>) -> Box<dyn DataType> {
207        Box::new(NullType)
208    }
209
210    /// Return a list of types that it's possible to perform `||` or  `OR` operator with
211    /// between current DataType and any one of them
212    fn can_perform_logical_or_op_with(&self) -> Vec<Box<dyn DataType>> {
213        vec![]
214    }
215
216    /// Return the expected type after perform `||` or `OR` operator between current type and argument type
217    ///
218    /// Note that you don't need to check again that the argument type is possible to perform operator with
219    #[allow(unused_variables)]
220    #[allow(clippy::borrowed_box)]
221    fn logical_or_op_result_type(&self, other: &Box<dyn DataType>) -> Box<dyn DataType> {
222        Box::new(NullType)
223    }
224
225    /// Return a list of types that it's possible to perform `&&` or `AND` operator with
226    /// between current DataType and any one of them
227    fn can_perform_logical_and_op_with(&self) -> Vec<Box<dyn DataType>> {
228        vec![]
229    }
230
231    /// Return the expected type after perform `&&` or `AND` operator between current type and argument type
232    ///
233    /// Note that you don't need to check again that the argument type is possible to perform operator with
234    #[allow(unused_variables)]
235    #[allow(clippy::borrowed_box)]
236    fn logical_and_op_result_type(&self, other: &Box<dyn DataType>) -> Box<dyn DataType> {
237        Box::new(NullType)
238    }
239
240    /// Return a list of types that it's possible to perform `XOR' operator with
241    /// between current DataType and any one of them
242    fn can_perform_logical_xor_op_with(&self) -> Vec<Box<dyn DataType>> {
243        vec![]
244    }
245
246    /// Return the expected type after perform 'XOR' operator between current type and argument type
247    ///
248    /// Note that you don't need to check again that the argument type is possible to perform operator with
249    #[allow(unused_variables)]
250    #[allow(clippy::borrowed_box)]
251    fn logical_xor_op_result_type(&self, other: &Box<dyn DataType>) -> Box<dyn DataType> {
252        Box::new(NullType)
253    }
254
255    /// Return a list of types that it's possible to perform `[I]' operator with
256    /// between current DataType and any one of them
257    fn can_perform_index_op_with(&self) -> Vec<Box<dyn DataType>> {
258        vec![]
259    }
260
261    /// Return the expected type after perform '[]' operator on current type
262    ///
263    /// * `other` - The index type
264    ///
265    /// Note that you don't need to check again that the argument type is possible to perform operator with
266    #[allow(unused_variables)]
267    #[allow(clippy::borrowed_box)]
268    fn index_op_result_type(&self, other: &Box<dyn DataType>) -> Box<dyn DataType> {
269        Box::new(NullType)
270    }
271
272    /// Return true if this type support Slice operator with
273    fn can_perform_slice_op(&self) -> bool {
274        false
275    }
276
277    /// Return a list of types that it's possible to perform `[S : E]' operator with
278    /// between current DataType and any one of them
279    fn can_perform_slice_op_with(&self) -> Vec<Box<dyn DataType>> {
280        vec![]
281    }
282
283    /// Return a list of types that it's possible to perform `=' operator with
284    /// between current DataType and any one of them
285    ///
286    /// No need to define the result type, it always BoolType
287    fn can_perform_eq_op_with(&self) -> Vec<Box<dyn DataType>> {
288        vec![]
289    }
290
291    /// Return a list of types that it's possible to perform `= [ALL|ANY|SOME]' operator with
292    /// between current DataType and any one of them
293    ///
294    /// No need to define the result type, it always BoolType
295    #[allow(unused_variables)]
296    fn can_perform_group_eq_op_with(&self) -> Vec<Box<dyn DataType>> {
297        vec![]
298    }
299
300    /// Return a list of types that it's possible to perform `!=' or `<>` operator with
301    /// between current DataType and any one of them
302    ///
303    /// No need to define the result type, it always BoolType
304    fn can_perform_bang_eq_op_with(&self) -> Vec<Box<dyn DataType>> {
305        vec![]
306    }
307
308    /// Return a list of types that it's possible to perform `!= [ALL|ANY|SOME]' operator with
309    /// between current DataType and any one of them
310    ///
311    /// No need to define the result type, it always BoolType
312    #[allow(unused_variables)]
313    fn can_perform_group_bang_eq_op_with(&self) -> Vec<Box<dyn DataType>> {
314        vec![]
315    }
316
317    /// Return a list of types that it's possible to perform `<=>' operator with
318    /// between current DataType and any one of them
319    ///
320    /// No need to define the result type, it always IntType
321    fn can_perform_null_safe_eq_op_with(&self) -> Vec<Box<dyn DataType>> {
322        vec![]
323    }
324
325    /// Return a list of types that it's possible to perform `<=> [ALL|ANY|SOME]' operator with
326    /// between current DataType and any one of them
327    ///
328    /// No need to define the result type, it always IntType
329    #[allow(unused_variables)]
330    fn can_perform_group_null_safe_eq_op_with(&self) -> Vec<Box<dyn DataType>> {
331        vec![]
332    }
333
334    /// Return a list of types that it's possible to perform `>' operator with
335    /// between current DataType and any one of them
336    ///
337    /// No need to define the result type, it always BoolType
338    fn can_perform_gt_op_with(&self) -> Vec<Box<dyn DataType>> {
339        vec![]
340    }
341
342    /// Return a list of types that it's possible to perform `> [ALL|ANY|SOME]' operator with
343    /// between current DataType and any one of them
344    ///
345    /// No need to define the result type, it always BoolType
346    #[allow(unused_variables)]
347    fn can_perform_group_gt_op_with(&self) -> Vec<Box<dyn DataType>> {
348        vec![]
349    }
350
351    /// Return a list of types that it's possible to perform `>=' operator with
352    /// between current DataType and any one of them
353    ///
354    /// No need to define the result type, it always BoolType
355    fn can_perform_gte_op_with(&self) -> Vec<Box<dyn DataType>> {
356        vec![]
357    }
358
359    /// Return a list of types that it's possible to perform `>= [ALL|ANY|SOME]' operator with
360    /// between current DataType and any one of them
361    ///
362    /// No need to define the result type, it always BoolType
363    #[allow(unused_variables)]
364    fn can_perform_group_gte_op_with(&self) -> Vec<Box<dyn DataType>> {
365        vec![]
366    }
367
368    /// Return a list of types that it's possible to perform `<' operator with
369    /// between current DataType and any one of them
370    ///
371    /// No need to define the result type, it always BoolType
372    fn can_perform_lt_op_with(&self) -> Vec<Box<dyn DataType>> {
373        vec![]
374    }
375
376    /// Return a list of types that it's possible to perform `< [ALL|ANY|SOME]' operator with
377    /// between current DataType and any one of them
378    ///
379    /// No need to define the result type, it always BoolType
380    #[allow(unused_variables)]
381    fn can_perform_group_lt_op_with(&self) -> Vec<Box<dyn DataType>> {
382        vec![]
383    }
384
385    /// Return a list of types that it's possible to perform `=<' operator with
386    /// between current DataType and any one of them
387    ///
388    /// No need to define the result type, it always BoolType
389    fn can_perform_lte_op_with(&self) -> Vec<Box<dyn DataType>> {
390        vec![]
391    }
392
393    /// Return a list of types that it's possible to perform `<= [ALL|ANY|SOME]' operator with
394    /// between current DataType and any one of them
395    ///
396    /// No need to define the result type, it always BoolType
397    #[allow(unused_variables)]
398    fn can_perform_group_lte_op_with(&self) -> Vec<Box<dyn DataType>> {
399        vec![]
400    }
401
402    /// Return a list of types that it's possible to perform unary `NOT' operator with
403    /// between current DataType and any one of them
404    fn can_perform_not_op(&self) -> bool {
405        false
406    }
407
408    /// Return the expected type after perform unary `NOT' operator on current type
409    ///
410    /// Note that you don't need to check again that the argument type is possible to perform operator with
411    fn not_op_result_type(&self) -> Box<dyn DataType> {
412        Box::new(NullType)
413    }
414
415    /// Return a list of types that it's possible to perform unary `-' operator with
416    /// between current DataType and any one of them
417    fn can_perform_neg_op(&self) -> bool {
418        false
419    }
420
421    /// Return the expected type after perform unary `-' operator on current type
422    ///
423    /// Note that you don't need to check again that the argument type is possible to perform operator with
424    fn neg_op_result_type(&self) -> Box<dyn DataType> {
425        Box::new(NullType)
426    }
427
428    /// Return a list of types that it's possible to perform unary `!' operator with
429    /// between current DataType and any one of them
430    fn can_perform_bang_op(&self) -> bool {
431        false
432    }
433
434    /// Return the expected type after perform unary `!' operator on current type
435    ///
436    /// Note that you don't need to check again that the argument type is possible to perform operator with
437    fn bang_op_result_type(&self) -> Box<dyn DataType> {
438        Box::new(NullType)
439    }
440
441    /// Return a list of types that it's possible to perform unary `@>' operator with
442    /// between current DataType and any one of them
443    ///
444    /// No need to define the result type, it always BoolType
445    fn can_perform_contains_op_with(&self) -> Vec<Box<dyn DataType>> {
446        vec![]
447    }
448
449    /// Return true if this Expression can be casted to the current type without any evaluation
450    ///
451    /// For example casting Text with specific format to Date or Time
452    ///
453    /// The result type is equal to the current type
454    #[allow(unused_variables)]
455    #[allow(clippy::borrowed_box)]
456    fn has_implicit_cast_from(&self, expr: &Box<dyn Expr>) -> bool {
457        false
458    }
459
460    /// Return a list of types that it's possible to perform `Cast' operator to
461    ///
462    /// For example casting column with float value to integer or verse versa
463    ///
464    /// The result type is equal to the current type
465    fn can_perform_explicit_cast_op_to(&self) -> Vec<Box<dyn DataType>> {
466        vec![]
467    }
468
469    /// Return a list of types that it's possible to perform unary `LIKE' operator with
470    /// between current DataType and any one of them
471    ///
472    /// No need to define the result type, it always BoolType
473    fn can_perform_like_op_with(&self) -> Vec<Box<dyn DataType>> {
474        vec![]
475    }
476
477    /// Return a list of types that it's possible to perform unary `GLOB' operator with
478    /// between current DataType and any one of them
479    ///
480    /// No need to define the result type, it always BoolType
481    fn can_perform_glob_op_with(&self) -> Vec<Box<dyn DataType>> {
482        vec![]
483    }
484
485    /// Return a list of types that it's possible to perform unary `REGEXP' operator with
486    /// between current DataType and any one of them
487    ///
488    /// No need to define the result type, it always BoolType
489    fn can_perform_regexp_op_with(&self) -> Vec<Box<dyn DataType>> {
490        vec![]
491    }
492}
493
494impl dyn DataType {
495    /// Return true if this type is [`AnyType`]
496    pub fn is_any(&self) -> bool {
497        self.as_any().downcast_ref::<AnyType>().is_some()
498    }
499
500    /// Return true if this type is [`TextType`]
501    pub fn is_text(&self) -> bool {
502        self.as_any().downcast_ref::<TextType>().is_some()
503    }
504
505    /// Return true if this type is [`IntType`]
506    pub fn is_int(&self) -> bool {
507        self.as_any().downcast_ref::<IntType>().is_some()
508    }
509
510    /// Return true if this type is [`FloatType`]
511    pub fn is_float(&self) -> bool {
512        self.as_any().downcast_ref::<FloatType>().is_some()
513    }
514
515    /// Return true if this type is [`IntType`] or [`FloatType`]
516    pub fn is_number(&self) -> bool {
517        self.is_int() || self.is_float()
518    }
519
520    /// Return true if this type is [`BoolType`]
521    pub fn is_bool(&self) -> bool {
522        self.as_any().downcast_ref::<BoolType>().is_some()
523    }
524
525    /// Return true if this type is [`DateType`]
526    pub fn is_date(&self) -> bool {
527        self.as_any().downcast_ref::<DateType>().is_some()
528    }
529
530    /// Return true if this type is [`TimeType`]
531    pub fn is_time(&self) -> bool {
532        self.as_any().downcast_ref::<TimeType>().is_some()
533    }
534
535    /// Return true if this type is [`DateTimeType`]
536    pub fn is_date_time(&self) -> bool {
537        self.as_any().downcast_ref::<DateTimeType>().is_some()
538    }
539
540    /// Return true if this type is [`IntervalType`]
541    pub fn is_interval(&self) -> bool {
542        self.as_any().downcast_ref::<IntervalType>().is_some()
543    }
544
545    /// Return true if this type is [`ArrayType`]
546    pub fn is_array(&self) -> bool {
547        self.as_any().downcast_ref::<ArrayType>().is_some()
548    }
549
550    /// Return true if this type is [`RangeType`]
551    pub fn is_range(&self) -> bool {
552        self.as_any().downcast_ref::<RangeType>().is_some()
553    }
554
555    /// Return true if this type is [`VariantType`]
556    pub fn is_variant(&self) -> bool {
557        self.as_any().downcast_ref::<VariantType>().is_some()
558    }
559
560    /// Return true if this type is [`VariantType`]
561    /// and applying the matcher function is return true on one of the variants
562    pub fn is_variant_with(&self, matcher: fn(&Box<dyn DataType>) -> bool) -> bool {
563        if let Some(variant_type) = self.as_any().downcast_ref::<VariantType>() {
564            for variant in variant_type.variants.iter() {
565                if matcher(variant) {
566                    return true;
567                }
568            }
569        }
570        false
571    }
572
573    /// Return true if this type is [`VariantType`] and contain specific type as one of it variants
574    #[allow(clippy::borrowed_box)]
575    pub fn is_variant_contains(&self, other: &Box<dyn DataType>) -> bool {
576        if let Some(variant_type) = self.as_any().downcast_ref::<VariantType>() {
577            return variant_type.variants.contains(other);
578        }
579        false
580    }
581
582    /// Return true if this type is [`OptionType`]
583    pub fn is_optional(&self) -> bool {
584        self.as_any().downcast_ref::<OptionType>().is_some()
585    }
586
587    /// Return true if this type is [`VarargsType`]
588    pub fn is_varargs(&self) -> bool {
589        self.as_any().downcast_ref::<VarargsType>().is_some()
590    }
591
592    /// Return true if this type is [`CompositeType`]
593    pub fn is_composite(&self) -> bool {
594        self.as_any().downcast_ref::<CompositeType>().is_some()
595    }
596
597    /// Return true if this type is [`UndefType`]
598    pub fn is_undefined(&self) -> bool {
599        self.as_any().downcast_ref::<UndefType>().is_some()
600    }
601
602    /// Return true if this type is [`NullType`]
603    pub fn is_null(&self) -> bool {
604        self.as_any().downcast_ref::<NullType>().is_some()
605    }
606}
607
608impl fmt::Display for Box<dyn DataType> {
609    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
610        write!(f, "{}", self.literal())
611    }
612}
613
614impl PartialEq for Box<dyn DataType> {
615    fn eq(&self, other: &Self) -> bool {
616        self.equals(other)
617    }
618}