@@ -9,31 +9,53 @@ use super::boolean::BoolValue;
99
1010#[ derive( Clone ) ]
1111pub struct RangeValue {
12- pub start : Box < dyn Value > ,
13- pub end : Box < dyn Value > ,
12+ pub lower : Box < dyn Value > ,
13+ pub upper : Box < dyn Value > ,
1414 pub base_type : Box < dyn DataType > ,
15+ pub is_lower_bound_inclusive : bool ,
16+ pub is_upper_bound_inclusive : bool ,
1517}
1618
1719impl RangeValue {
18- pub fn new ( start : Box < dyn Value > , end : Box < dyn Value > , base_type : Box < dyn DataType > ) -> Self {
20+ pub fn new ( lower : Box < dyn Value > , upper : Box < dyn Value > , base_type : Box < dyn DataType > ) -> Self {
1921 RangeValue {
20- start ,
21- end ,
22+ lower ,
23+ upper ,
2224 base_type,
25+ is_lower_bound_inclusive : true ,
26+ is_upper_bound_inclusive : false ,
2327 }
2428 }
2529}
2630
2731impl Value for RangeValue {
2832 fn literal ( & self ) -> String {
29- format ! ( "{}..{}" , self . start. literal( ) , self . end. literal( ) )
33+ let lower_bound = if self . is_lower_bound_inclusive {
34+ '['
35+ } else {
36+ '('
37+ } ;
38+
39+ let upper_bound = if self . is_upper_bound_inclusive {
40+ ']'
41+ } else {
42+ ')'
43+ } ;
44+
45+ format ! (
46+ "{lower_bound}{}..{}{upper_bound}" ,
47+ self . lower. literal( ) ,
48+ self . upper. literal( )
49+ )
3050 }
3151
3252 fn equals ( & self , other : & Box < dyn Value > ) -> bool {
3353 if let Some ( other_range) = other. as_any ( ) . downcast_ref :: < RangeValue > ( ) {
3454 return self . base_type . equals ( & other_range. base_type )
35- && self . start . equals ( & other_range. start )
36- && self . end . equals ( & other_range. end ) ;
55+ && self . lower . equals ( & other_range. lower )
56+ && self . upper . equals ( & other_range. upper )
57+ && self . is_lower_bound_inclusive == other_range. is_lower_bound_inclusive
58+ && self . is_upper_bound_inclusive == other_range. is_upper_bound_inclusive ;
3759 }
3860 false
3961 }
@@ -43,50 +65,94 @@ impl Value for RangeValue {
4365 }
4466
4567 fn data_type ( & self ) -> Box < dyn DataType > {
46- Box :: new ( RangeType {
47- base : self . base_type . clone ( ) ,
48- } )
68+ Box :: new ( RangeType :: new ( self . base_type . clone ( ) ) )
4969 }
5070
5171 fn as_any ( & self ) -> & dyn Any {
5272 self
5373 }
5474
55- fn logical_or_op ( & self , other : & Box < dyn Value > ) -> Result < Box < dyn Value > , String > {
75+ fn logical_and_op ( & self , other : & Box < dyn Value > ) -> Result < Box < dyn Value > , String > {
5676 if let Some ( other_range) = other. as_any ( ) . downcast_ref :: < RangeValue > ( ) {
57- if !self . equals ( other) {
58- return Err ( "Overlap operator expect both Ranges to have same type" . to_string ( ) ) ;
77+ if !self . data_type ( ) . equals ( & other. data_type ( ) ) {
78+ return Err ( "Overlap operator expect both Ranges to have the same type" . to_string ( ) ) ;
5979 }
6080
61- let max_start = if self . start . compare ( & other_range. start ) . unwrap ( ) . is_ge ( ) {
62- & self . start
81+ let compare_lowers = self . lower . compare ( & other_range. lower ) . unwrap ( ) ;
82+ let max_lower = if ( self . is_lower_bound_inclusive
83+ == other_range. is_lower_bound_inclusive
84+ && compare_lowers. is_ge ( ) )
85+ || compare_lowers. is_gt ( )
86+ {
87+ & self . lower
6388 } else {
64- & other_range. start
89+ & other_range. lower
6590 } ;
6691
67- let max_end = if self . end . compare ( & other_range. end ) . unwrap ( ) . is_lt ( ) {
68- & self . end
92+ let compare_uppers = self . upper . compare ( & other_range. upper ) . unwrap ( ) ;
93+ let max_upper = if ( self . is_lower_bound_inclusive
94+ == other_range. is_lower_bound_inclusive
95+ && compare_uppers. is_le ( ) )
96+ || compare_uppers. is_lt ( )
97+ {
98+ & self . upper
6999 } else {
70- & other_range. end
100+ & other_range. upper
71101 } ;
72102
73- let is_overlap = max_end . compare ( max_start ) . unwrap ( ) . is_ge ( ) ;
74- return Ok ( Box :: new ( BoolValue { value : is_overlap } ) ) ;
103+ let is_overlap = max_upper . compare ( max_lower ) . unwrap ( ) . is_gt ( ) ;
104+ return Ok ( Box :: new ( BoolValue :: new ( is_overlap) ) ) ;
75105 }
76106 Err ( "Unexpected type to perform `Range Overlap &&` with" . to_string ( ) )
77107 }
78108
79109 fn contains_op ( & self , other : & Box < dyn Value > ) -> Result < Box < dyn Value > , String > {
80110 if let Some ( other_range) = other. as_any ( ) . downcast_ref :: < RangeValue > ( ) {
81- let is_in_range = other_range. start . compare ( & self . start ) . unwrap ( ) . is_ge ( )
82- && other_range. end . compare ( & self . end ) . unwrap ( ) . is_le ( ) ;
83- return Ok ( Box :: new ( BoolValue { value : is_in_range } ) ) ;
111+ let is_lower_in_range =
112+ // Current range has no lower boundraies
113+ if self . lower . is_null ( ) {
114+ true
115+ }
116+ // Current range has lower boundraies, but the other range hasn't
117+ else if other_range. lower . is_null ( ) {
118+ false
119+ } else {
120+ let compare_lowers = other_range. lower . compare ( & self . lower ) . unwrap ( ) ;
121+ if self . is_lower_bound_inclusive || ( self . is_upper_bound_inclusive == other_range. is_upper_bound_inclusive )
122+ { compare_lowers. is_ge ( ) } else { compare_lowers. is_gt ( ) }
123+ } ;
124+
125+ let is_range_contains = is_lower_in_range &&
126+ // Current range has no upper boundraies
127+ if self . upper . is_null ( ) {
128+ true
129+ }
130+ // Current range has upper boundraies, but the other range hasn't
131+ else if other_range. upper . is_null ( ) {
132+ false
133+ } else {
134+ let compare_uppers = other_range. upper . compare ( & self . upper ) . unwrap ( ) ;
135+ if self . is_upper_bound_inclusive || ( self . is_upper_bound_inclusive == other_range. is_upper_bound_inclusive )
136+ { compare_uppers. is_le ( ) } else { compare_uppers. is_lt ( ) }
137+ } ;
138+
139+ return Ok ( Box :: new ( BoolValue :: new ( is_range_contains) ) ) ;
84140 }
85141
86142 if self . base_type . equals ( & other. data_type ( ) ) {
87- let is_in_range = other. compare ( & self . start ) . unwrap ( ) . is_ge ( )
88- && other. compare ( & self . end ) . unwrap ( ) . is_le ( ) ;
89- return Ok ( Box :: new ( BoolValue { value : is_in_range } ) ) ;
143+ let is_lower_in = self . lower . is_null ( )
144+ || if self . is_lower_bound_inclusive {
145+ other. compare ( & self . lower ) . unwrap ( ) . is_ge ( )
146+ } else {
147+ other. compare ( & self . lower ) . unwrap ( ) . is_gt ( )
148+ } ;
149+ let is_upper_in = self . upper . is_null ( )
150+ || if self . is_upper_bound_inclusive {
151+ other. compare ( & self . upper ) . unwrap ( ) . is_le ( )
152+ } else {
153+ other. compare ( & self . upper ) . unwrap ( ) . is_lt ( )
154+ } ;
155+ return Ok ( Box :: new ( BoolValue :: new ( is_lower_in && is_upper_in) ) ) ;
90156 }
91157
92158 Err ( "Unexpected type to perform `Range contains @>` with" . to_string ( ) )
0 commit comments