oxigdal_query/executor/join/
value.rs1#[derive(Debug, Clone, PartialEq)]
5pub enum JoinValue {
6 Null,
8 Boolean(bool),
10 Integer(i64),
12 Float(f64),
14 String(String),
16}
17
18impl JoinValue {
19 pub fn is_null(&self) -> bool {
21 matches!(self, JoinValue::Null)
22 }
23
24 pub fn to_hash_key(&self) -> String {
26 match self {
27 JoinValue::Null => "__NULL__".to_string(),
28 JoinValue::Boolean(b) => format!("b:{}", b),
29 JoinValue::Integer(i) => format!("i:{}", i),
30 JoinValue::Float(f) => format!("f:{:?}", f),
31 JoinValue::String(s) => format!("s:{}", s),
32 }
33 }
34
35 pub fn equals(&self, other: &JoinValue) -> Option<bool> {
37 if self.is_null() || other.is_null() {
38 return None; }
40
41 match (self, other) {
42 (JoinValue::Boolean(a), JoinValue::Boolean(b)) => Some(a == b),
43 (JoinValue::Integer(a), JoinValue::Integer(b)) => Some(a == b),
44 (JoinValue::Integer(a), JoinValue::Float(b)) => Some((*a as f64) == *b),
45 (JoinValue::Float(a), JoinValue::Integer(b)) => Some(*a == (*b as f64)),
46 (JoinValue::Float(a), JoinValue::Float(b)) => Some(a == b),
47 (JoinValue::String(a), JoinValue::String(b)) => Some(a == b),
48 _ => Some(false), }
50 }
51
52 pub fn compare(&self, other: &JoinValue) -> Option<std::cmp::Ordering> {
54 if self.is_null() || other.is_null() {
55 return None;
56 }
57
58 match (self, other) {
59 (JoinValue::Boolean(a), JoinValue::Boolean(b)) => Some(a.cmp(b)),
60 (JoinValue::Integer(a), JoinValue::Integer(b)) => Some(a.cmp(b)),
61 (JoinValue::Integer(a), JoinValue::Float(b)) => (*a as f64).partial_cmp(b),
62 (JoinValue::Float(a), JoinValue::Integer(b)) => a.partial_cmp(&(*b as f64)),
63 (JoinValue::Float(a), JoinValue::Float(b)) => a.partial_cmp(b),
64 (JoinValue::String(a), JoinValue::String(b)) => Some(a.cmp(b)),
65 _ => None, }
67 }
68
69 pub fn negate(&self) -> Option<JoinValue> {
71 match self {
72 JoinValue::Integer(i) => Some(JoinValue::Integer(-i)),
73 JoinValue::Float(f) => Some(JoinValue::Float(-f)),
74 _ => None,
75 }
76 }
77
78 pub fn not(&self) -> Option<JoinValue> {
80 match self {
81 JoinValue::Boolean(b) => Some(JoinValue::Boolean(!b)),
82 _ => None,
83 }
84 }
85
86 pub fn add(&self, other: &JoinValue) -> Option<JoinValue> {
88 match (self, other) {
89 (JoinValue::Integer(a), JoinValue::Integer(b)) => {
92 a.checked_add(*b).map(JoinValue::Integer)
93 }
94 (JoinValue::Integer(a), JoinValue::Float(b)) => Some(JoinValue::Float(*a as f64 + b)),
95 (JoinValue::Float(a), JoinValue::Integer(b)) => Some(JoinValue::Float(a + *b as f64)),
96 (JoinValue::Float(a), JoinValue::Float(b)) => Some(JoinValue::Float(a + b)),
97 (JoinValue::String(a), JoinValue::String(b)) => {
98 Some(JoinValue::String(format!("{}{}", a, b)))
99 }
100 _ => None,
101 }
102 }
103
104 pub fn subtract(&self, other: &JoinValue) -> Option<JoinValue> {
106 match (self, other) {
107 (JoinValue::Integer(a), JoinValue::Integer(b)) => {
108 a.checked_sub(*b).map(JoinValue::Integer)
109 }
110 (JoinValue::Integer(a), JoinValue::Float(b)) => Some(JoinValue::Float(*a as f64 - b)),
111 (JoinValue::Float(a), JoinValue::Integer(b)) => Some(JoinValue::Float(a - *b as f64)),
112 (JoinValue::Float(a), JoinValue::Float(b)) => Some(JoinValue::Float(a - b)),
113 _ => None,
114 }
115 }
116
117 pub fn multiply(&self, other: &JoinValue) -> Option<JoinValue> {
119 match (self, other) {
120 (JoinValue::Integer(a), JoinValue::Integer(b)) => {
121 a.checked_mul(*b).map(JoinValue::Integer)
122 }
123 (JoinValue::Integer(a), JoinValue::Float(b)) => Some(JoinValue::Float(*a as f64 * b)),
124 (JoinValue::Float(a), JoinValue::Integer(b)) => Some(JoinValue::Float(a * *b as f64)),
125 (JoinValue::Float(a), JoinValue::Float(b)) => Some(JoinValue::Float(a * b)),
126 _ => None,
127 }
128 }
129
130 pub fn divide(&self, other: &JoinValue) -> Option<JoinValue> {
132 match (self, other) {
133 (JoinValue::Integer(a), JoinValue::Integer(b)) if *b != 0 => {
134 Some(JoinValue::Integer(a / b))
135 }
136 (JoinValue::Integer(a), JoinValue::Float(b)) if *b != 0.0 => {
137 Some(JoinValue::Float(*a as f64 / b))
138 }
139 (JoinValue::Float(a), JoinValue::Integer(b)) if *b != 0 => {
140 Some(JoinValue::Float(a / *b as f64))
141 }
142 (JoinValue::Float(a), JoinValue::Float(b)) if *b != 0.0 => {
143 Some(JoinValue::Float(a / b))
144 }
145 _ => None,
146 }
147 }
148
149 pub fn modulo(&self, other: &JoinValue) -> Option<JoinValue> {
151 match (self, other) {
152 (JoinValue::Integer(a), JoinValue::Integer(b)) if *b != 0 => {
153 Some(JoinValue::Integer(a % b))
154 }
155 (JoinValue::Integer(a), JoinValue::Float(b)) if *b != 0.0 => {
156 Some(JoinValue::Float(*a as f64 % b))
157 }
158 (JoinValue::Float(a), JoinValue::Integer(b)) if *b != 0 => {
159 Some(JoinValue::Float(a % *b as f64))
160 }
161 (JoinValue::Float(a), JoinValue::Float(b)) if *b != 0.0 => {
162 Some(JoinValue::Float(a % b))
163 }
164 _ => None,
165 }
166 }
167
168 pub fn to_bool(&self) -> Option<bool> {
170 match self {
171 JoinValue::Boolean(b) => Some(*b),
172 JoinValue::Null => None,
173 _ => None,
174 }
175 }
176
177 pub fn matches_like(&self, pattern: &JoinValue) -> Option<bool> {
179 match (self, pattern) {
180 (JoinValue::String(s), JoinValue::String(p)) => Some(Self::like_match(s, p)),
181 _ => None,
182 }
183 }
184
185 pub fn matches_ilike(&self, pattern: &JoinValue) -> Option<bool> {
187 match (self, pattern) {
188 (JoinValue::String(s), JoinValue::String(p)) => {
189 Some(crate::executor::like::like_match(s, p, true))
190 }
191 _ => None,
192 }
193 }
194
195 pub fn like_match(text: &str, pattern: &str) -> bool {
197 crate::executor::like::like_match(text, pattern, false)
198 }
199}