gitql_ast/types/
base.rs

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