1use crate::data::datatable::DataValue;
4use crate::sql::functions::{ArgCount, FunctionCategory, FunctionSignature, SqlFunction};
5use anyhow::{anyhow, Result};
6
7pub struct BitAndStr;
9
10impl SqlFunction for BitAndStr {
11 fn signature(&self) -> FunctionSignature {
12 FunctionSignature {
13 name: "BIT_AND_STR",
14 category: FunctionCategory::Bitwise,
15 arg_count: ArgCount::Fixed(2),
16 description: "Performs bitwise AND on two binary strings",
17 returns: "Binary string result",
18 examples: vec![
19 "SELECT BIT_AND_STR('1101', '1011')",
20 "SELECT BIT_AND_STR(TO_BINARY(13), TO_BINARY(11))",
21 ],
22 }
23 }
24
25 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
26 self.validate_args(args)?;
27
28 let a = args[0].to_string();
29 let b = args[1].to_string();
30
31 let max_len = a.len().max(b.len());
33 let a_padded = format!("{:0>width$}", a, width = max_len);
34 let b_padded = format!("{:0>width$}", b, width = max_len);
35
36 let result: String = a_padded
37 .chars()
38 .zip(b_padded.chars())
39 .map(|(c1, c2)| match (c1, c2) {
40 ('1', '1') => '1',
41 _ => '0',
42 })
43 .collect();
44
45 Ok(DataValue::String(result))
46 }
47}
48
49pub struct BitOrStr;
51
52impl SqlFunction for BitOrStr {
53 fn signature(&self) -> FunctionSignature {
54 FunctionSignature {
55 name: "BIT_OR_STR",
56 category: FunctionCategory::Bitwise,
57 arg_count: ArgCount::Fixed(2),
58 description: "Performs bitwise OR on two binary strings",
59 returns: "Binary string result",
60 examples: vec![
61 "SELECT BIT_OR_STR('1100', '1010')",
62 "SELECT BIT_OR_STR(TO_BINARY(12), TO_BINARY(10))",
63 ],
64 }
65 }
66
67 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
68 self.validate_args(args)?;
69
70 let a = args[0].to_string();
71 let b = args[1].to_string();
72
73 let max_len = a.len().max(b.len());
74 let a_padded = format!("{:0>width$}", a, width = max_len);
75 let b_padded = format!("{:0>width$}", b, width = max_len);
76
77 let result: String = a_padded
78 .chars()
79 .zip(b_padded.chars())
80 .map(|(c1, c2)| match (c1, c2) {
81 ('0', '0') => '0',
82 _ => '1',
83 })
84 .collect();
85
86 Ok(DataValue::String(result))
87 }
88}
89
90pub struct BitXorStr;
92
93impl SqlFunction for BitXorStr {
94 fn signature(&self) -> FunctionSignature {
95 FunctionSignature {
96 name: "BIT_XOR_STR",
97 category: FunctionCategory::Bitwise,
98 arg_count: ArgCount::Fixed(2),
99 description: "Performs bitwise XOR on two binary strings",
100 returns: "Binary string result",
101 examples: vec![
102 "SELECT BIT_XOR_STR('1100', '1010')",
103 "SELECT BIT_XOR_STR(TO_BINARY(12), TO_BINARY(10))",
104 ],
105 }
106 }
107
108 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
109 self.validate_args(args)?;
110
111 let a = args[0].to_string();
112 let b = args[1].to_string();
113
114 let max_len = a.len().max(b.len());
115 let a_padded = format!("{:0>width$}", a, width = max_len);
116 let b_padded = format!("{:0>width$}", b, width = max_len);
117
118 let result: String = a_padded
119 .chars()
120 .zip(b_padded.chars())
121 .map(|(c1, c2)| if c1 == c2 { '0' } else { '1' })
122 .collect();
123
124 Ok(DataValue::String(result))
125 }
126}
127
128pub struct BitNotStr;
130
131impl SqlFunction for BitNotStr {
132 fn signature(&self) -> FunctionSignature {
133 FunctionSignature {
134 name: "BIT_NOT_STR",
135 category: FunctionCategory::Bitwise,
136 arg_count: ArgCount::Fixed(1),
137 description: "Performs bitwise NOT on a binary string",
138 returns: "Binary string with bits flipped",
139 examples: vec![
140 "SELECT BIT_NOT_STR('1100')",
141 "SELECT BIT_NOT_STR(TO_BINARY(12))",
142 ],
143 }
144 }
145
146 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
147 self.validate_args(args)?;
148
149 let input = args[0].to_string();
150
151 let result: String = input
152 .chars()
153 .map(|c| if c == '0' { '1' } else { '0' })
154 .collect();
155
156 Ok(DataValue::String(result))
157 }
158}
159
160pub struct BitFlip;
162
163impl SqlFunction for BitFlip {
164 fn signature(&self) -> FunctionSignature {
165 FunctionSignature {
166 name: "BIT_FLIP",
167 category: FunctionCategory::Bitwise,
168 arg_count: ArgCount::Fixed(1),
169 description: "Flips all bits in a binary string (alias for BIT_NOT_STR)",
170 returns: "Binary string with bits flipped",
171 examples: vec!["SELECT BIT_FLIP('11011010')"],
172 }
173 }
174
175 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
176 BitNotStr.evaluate(args)
177 }
178}
179
180pub struct BitCount;
182
183impl SqlFunction for BitCount {
184 fn signature(&self) -> FunctionSignature {
185 FunctionSignature {
186 name: "BIT_COUNT",
187 category: FunctionCategory::Bitwise,
188 arg_count: ArgCount::Fixed(1),
189 description: "Counts the number of 1 bits in a binary string",
190 returns: "Integer count of 1 bits",
191 examples: vec![
192 "SELECT BIT_COUNT('11011010')",
193 "SELECT BIT_COUNT(TO_BINARY(218))",
194 ],
195 }
196 }
197
198 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
199 self.validate_args(args)?;
200
201 let input = args[0].to_string();
202 let count = input.chars().filter(|&c| c == '1').count() as i64;
203 Ok(DataValue::Integer(count))
204 }
205}
206
207pub struct BitRotateLeft;
209
210impl SqlFunction for BitRotateLeft {
211 fn signature(&self) -> FunctionSignature {
212 FunctionSignature {
213 name: "BIT_ROTATE_LEFT",
214 category: FunctionCategory::Bitwise,
215 arg_count: ArgCount::Fixed(2),
216 description: "Rotates a binary string left by N positions",
217 returns: "Rotated binary string",
218 examples: vec![
219 "SELECT BIT_ROTATE_LEFT('11011010', 2)",
220 "SELECT BIT_ROTATE_LEFT(TO_BINARY(218), 3)",
221 ],
222 }
223 }
224
225 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
226 self.validate_args(args)?;
227
228 let input = args[0].to_string();
229 let positions = match &args[1] {
230 DataValue::Integer(n) => *n as usize,
231 DataValue::Float(f) => *f as usize,
232 _ => return Err(anyhow!("Second argument must be a number")),
233 };
234
235 if input.is_empty() {
236 return Ok(DataValue::String(String::new()));
237 }
238
239 let effective_positions = positions % input.len();
240 let result = format!(
241 "{}{}",
242 &input[effective_positions..],
243 &input[..effective_positions]
244 );
245
246 Ok(DataValue::String(result))
247 }
248}
249
250pub struct BitRotateRight;
252
253impl SqlFunction for BitRotateRight {
254 fn signature(&self) -> FunctionSignature {
255 FunctionSignature {
256 name: "BIT_ROTATE_RIGHT",
257 category: FunctionCategory::Bitwise,
258 arg_count: ArgCount::Fixed(2),
259 description: "Rotates a binary string right by N positions",
260 returns: "Rotated binary string",
261 examples: vec![
262 "SELECT BIT_ROTATE_RIGHT('11011010', 2)",
263 "SELECT BIT_ROTATE_RIGHT(TO_BINARY(218), 3)",
264 ],
265 }
266 }
267
268 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
269 self.validate_args(args)?;
270
271 let input = args[0].to_string();
272 let positions = match &args[1] {
273 DataValue::Integer(n) => *n as usize,
274 DataValue::Float(f) => *f as usize,
275 _ => return Err(anyhow!("Second argument must be a number")),
276 };
277
278 if input.is_empty() {
279 return Ok(DataValue::String(String::new()));
280 }
281
282 let effective_positions = positions % input.len();
283 let split_point = input.len() - effective_positions;
284 let result = format!("{}{}", &input[split_point..], &input[..split_point]);
285
286 Ok(DataValue::String(result))
287 }
288}
289
290pub struct BitShiftLeft;
292
293impl SqlFunction for BitShiftLeft {
294 fn signature(&self) -> FunctionSignature {
295 FunctionSignature {
296 name: "BIT_SHIFT_LEFT",
297 category: FunctionCategory::Bitwise,
298 arg_count: ArgCount::Fixed(2),
299 description: "Shifts a binary string left by N positions, filling with zeros",
300 returns: "Shifted binary string",
301 examples: vec![
302 "SELECT BIT_SHIFT_LEFT('11011010', 2)",
303 "SELECT BIT_SHIFT_LEFT(TO_BINARY(218), 3)",
304 ],
305 }
306 }
307
308 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
309 self.validate_args(args)?;
310
311 let input = args[0].to_string();
312 let positions = match &args[1] {
313 DataValue::Integer(n) => *n as usize,
314 DataValue::Float(f) => *f as usize,
315 _ => return Err(anyhow!("Second argument must be a number")),
316 };
317
318 if positions >= input.len() {
319 return Ok(DataValue::String("0".repeat(input.len())));
320 }
321
322 let result = format!("{}{}", &input[positions..], "0".repeat(positions));
323
324 Ok(DataValue::String(result))
325 }
326}
327
328pub struct BitShiftRight;
330
331impl SqlFunction for BitShiftRight {
332 fn signature(&self) -> FunctionSignature {
333 FunctionSignature {
334 name: "BIT_SHIFT_RIGHT",
335 category: FunctionCategory::Bitwise,
336 arg_count: ArgCount::Fixed(2),
337 description: "Shifts a binary string right by N positions, filling with zeros",
338 returns: "Shifted binary string",
339 examples: vec![
340 "SELECT BIT_SHIFT_RIGHT('11011010', 2)",
341 "SELECT BIT_SHIFT_RIGHT(TO_BINARY(218), 3)",
342 ],
343 }
344 }
345
346 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
347 self.validate_args(args)?;
348
349 let input = args[0].to_string();
350 let positions = match &args[1] {
351 DataValue::Integer(n) => *n as usize,
352 DataValue::Float(f) => *f as usize,
353 _ => return Err(anyhow!("Second argument must be a number")),
354 };
355
356 if positions >= input.len() {
357 return Ok(DataValue::String("0".repeat(input.len())));
358 }
359
360 let result = format!(
361 "{}{}",
362 "0".repeat(positions),
363 &input[..input.len() - positions]
364 );
365
366 Ok(DataValue::String(result))
367 }
368}
369
370pub struct HammingDistance;
372
373impl SqlFunction for HammingDistance {
374 fn signature(&self) -> FunctionSignature {
375 FunctionSignature {
376 name: "HAMMING_DISTANCE",
377 category: FunctionCategory::Bitwise,
378 arg_count: ArgCount::Fixed(2),
379 description: "Counts the number of differing bits between two binary strings",
380 returns: "Integer count of different bits",
381 examples: vec![
382 "SELECT HAMMING_DISTANCE('1101', '1011')",
383 "SELECT HAMMING_DISTANCE(TO_BINARY(13), TO_BINARY(11))",
384 ],
385 }
386 }
387
388 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
389 self.validate_args(args)?;
390
391 let a = args[0].to_string();
392 let b = args[1].to_string();
393
394 let max_len = a.len().max(b.len());
395 let a_padded = format!("{:0>width$}", a, width = max_len);
396 let b_padded = format!("{:0>width$}", b, width = max_len);
397
398 let distance = a_padded
399 .chars()
400 .zip(b_padded.chars())
401 .filter(|(c1, c2)| c1 != c2)
402 .count() as i64;
403
404 Ok(DataValue::Integer(distance))
405 }
406}