1use crate::data::datatable::DataValue;
2use crate::sql::functions::{ArgCount, FunctionCategory, FunctionSignature, SqlFunction};
3use anyhow::{anyhow, Result};
4use num_bigint::BigInt;
5use num_traits::{One, Signed, Zero};
6
7pub struct BigIntFunction;
9
10impl SqlFunction for BigIntFunction {
11 fn signature(&self) -> FunctionSignature {
12 FunctionSignature {
13 name: "BIGINT",
14 category: FunctionCategory::BigNumber,
15 arg_count: ArgCount::Fixed(1),
16 description: "Convert value to arbitrary precision integer",
17 returns: "String representation of big integer",
18 examples: vec![
19 "SELECT BIGINT('123456789012345678901234567890')",
20 "SELECT BIGINT(2) ^ BIGINT(100) -- 2^100",
21 ],
22 }
23 }
24
25 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
26 if args.len() != 1 {
27 return Err(anyhow!("BIGINT expects 1 argument"));
28 }
29
30 match &args[0] {
31 DataValue::String(s) => {
32 match s.parse::<BigInt>() {
33 Ok(_) => Ok(DataValue::String(s.clone())), Err(_) => Err(anyhow!("Invalid big integer format: {}", s)),
35 }
36 }
37 DataValue::Integer(n) => Ok(DataValue::String(n.to_string())),
38 DataValue::Float(f) => Ok(DataValue::String((*f as i64).to_string())),
39 DataValue::Null => Ok(DataValue::Null),
40 _ => Err(anyhow!("BIGINT expects numeric or string input")),
41 }
42 }
43}
44
45pub struct BigAddFunction;
47
48impl SqlFunction for BigAddFunction {
49 fn signature(&self) -> FunctionSignature {
50 FunctionSignature {
51 name: "BIGADD",
52 category: FunctionCategory::BigNumber,
53 arg_count: ArgCount::Fixed(2),
54 description: "Add two arbitrary precision integers",
55 returns: "String representation of sum",
56 examples: vec![
57 "SELECT BIGADD('999999999999999999999', '1')",
58 "SELECT BIGADD('123456789012345678901234567890', '987654321098765432109876543210')",
59 ],
60 }
61 }
62
63 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
64 if args.len() != 2 {
65 return Err(anyhow!("BIGADD expects 2 arguments"));
66 }
67
68 let a = parse_bigint(&args[0])?;
69 let b = parse_bigint(&args[1])?;
70
71 Ok(DataValue::String((a + b).to_string()))
72 }
73}
74
75pub struct BigMulFunction;
77
78impl SqlFunction for BigMulFunction {
79 fn signature(&self) -> FunctionSignature {
80 FunctionSignature {
81 name: "BIGMUL",
82 category: FunctionCategory::BigNumber,
83 arg_count: ArgCount::Fixed(2),
84 description: "Multiply two arbitrary precision integers",
85 returns: "String representation of product",
86 examples: vec![
87 "SELECT BIGMUL('999999999999999999999', '999999999999999999999')",
88 "SELECT BIGMUL('123456789', '987654321')",
89 ],
90 }
91 }
92
93 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
94 if args.len() != 2 {
95 return Err(anyhow!("BIGMUL expects 2 arguments"));
96 }
97
98 let a = parse_bigint(&args[0])?;
99 let b = parse_bigint(&args[1])?;
100
101 Ok(DataValue::String((a * b).to_string()))
102 }
103}
104
105pub struct BigPowFunction;
107
108impl SqlFunction for BigPowFunction {
109 fn signature(&self) -> FunctionSignature {
110 FunctionSignature {
111 name: "BIGPOW",
112 category: FunctionCategory::BigNumber,
113 arg_count: ArgCount::Fixed(2),
114 description: "Raise big integer to a power (base^exponent)",
115 returns: "String representation of result",
116 examples: vec![
117 "SELECT BIGPOW('2', 100) -- 2^100",
118 "SELECT BIGPOW('10', 50) -- 10^50",
119 "SELECT BIGPOW('99', 99) -- 99^99",
120 ],
121 }
122 }
123
124 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
125 if args.len() != 2 {
126 return Err(anyhow!("BIGPOW expects 2 arguments"));
127 }
128
129 let base = parse_bigint(&args[0])?;
130 let exp = match &args[1] {
131 DataValue::Integer(n) => *n as u32,
132 DataValue::String(s) => s
133 .parse::<u32>()
134 .map_err(|_| anyhow!("Exponent must be a non-negative integer"))?,
135 _ => return Err(anyhow!("Exponent must be a non-negative integer")),
136 };
137
138 let result = base.pow(exp);
139 Ok(DataValue::String(result.to_string()))
140 }
141}
142
143pub struct BigFactorialFunction;
145
146impl SqlFunction for BigFactorialFunction {
147 fn signature(&self) -> FunctionSignature {
148 FunctionSignature {
149 name: "BIGFACT",
150 category: FunctionCategory::BigNumber,
151 arg_count: ArgCount::Fixed(1),
152 description: "Calculate factorial of a number (n!)",
153 returns: "String representation of factorial",
154 examples: vec![
155 "SELECT BIGFACT(50) -- 50!",
156 "SELECT BIGFACT(100) -- 100!",
157 "SELECT LENGTH(BIGFACT(1000)) -- How many digits in 1000!",
158 ],
159 }
160 }
161
162 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
163 if args.len() != 1 {
164 return Err(anyhow!("BIGFACT expects 1 argument"));
165 }
166
167 let n = match &args[0] {
168 DataValue::Integer(n) => *n as u32,
169 DataValue::String(s) => s
170 .parse::<u32>()
171 .map_err(|_| anyhow!("Factorial input must be a non-negative integer"))?,
172 _ => return Err(anyhow!("Factorial input must be a non-negative integer")),
173 };
174
175 if n > 10000 {
176 return Err(anyhow!("Factorial input too large (max 10000)"));
177 }
178
179 let mut result = BigInt::one();
180 for i in 2..=n {
181 result *= i;
182 }
183
184 Ok(DataValue::String(result.to_string()))
185 }
186}
187
188pub struct ToBinaryFunction;
190
191impl SqlFunction for ToBinaryFunction {
192 fn signature(&self) -> FunctionSignature {
193 FunctionSignature {
194 name: "TO_BINARY",
195 category: FunctionCategory::BigNumber,
196 arg_count: ArgCount::Fixed(1),
197 description: "Convert number to binary string representation",
198 returns: "Binary string (e.g., '1010' for 10)",
199 examples: vec![
200 "SELECT TO_BINARY(42) -- '101010'",
201 "SELECT TO_BINARY('255') -- '11111111'",
202 "SELECT TO_BINARY(BIGPOW('2', 100)) -- Binary of 2^100",
203 ],
204 }
205 }
206
207 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
208 if args.len() != 1 {
209 return Err(anyhow!("TO_BINARY expects 1 argument"));
210 }
211
212 let num = parse_bigint(&args[0])?;
213 if num.sign() == num_bigint::Sign::Minus {
214 return Ok(DataValue::String(format!("-{}", num.abs().to_str_radix(2))));
217 }
218
219 Ok(DataValue::String(num.to_str_radix(2)))
220 }
221}
222
223pub struct FromBinaryFunction;
225
226impl SqlFunction for FromBinaryFunction {
227 fn signature(&self) -> FunctionSignature {
228 FunctionSignature {
229 name: "FROM_BINARY",
230 category: FunctionCategory::BigNumber,
231 arg_count: ArgCount::Fixed(1),
232 description: "Convert binary string to decimal number",
233 returns: "Decimal string representation",
234 examples: vec![
235 "SELECT FROM_BINARY('101010') -- '42'",
236 "SELECT FROM_BINARY('11111111') -- '255'",
237 "SELECT FROM_BINARY('1' || REPEAT('0', 100)) -- 2^100",
238 ],
239 }
240 }
241
242 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
243 if args.len() != 1 {
244 return Err(anyhow!("FROM_BINARY expects 1 argument"));
245 }
246
247 let binary_str = match &args[0] {
248 DataValue::String(s) => s,
249 _ => return Err(anyhow!("FROM_BINARY expects a string argument")),
250 };
251
252 let clean_binary: String = binary_str
254 .chars()
255 .filter(|c| *c == '0' || *c == '1')
256 .collect();
257
258 if clean_binary.is_empty() {
259 return Err(anyhow!("Invalid binary string"));
260 }
261
262 match BigInt::parse_bytes(clean_binary.as_bytes(), 2) {
263 Some(num) => Ok(DataValue::String(num.to_string())),
264 None => Err(anyhow!("Invalid binary string: {}", binary_str)),
265 }
266 }
267}
268
269pub struct ToHexFunction;
271
272impl SqlFunction for ToHexFunction {
273 fn signature(&self) -> FunctionSignature {
274 FunctionSignature {
275 name: "TO_HEX",
276 category: FunctionCategory::BigNumber,
277 arg_count: ArgCount::Fixed(1),
278 description: "Convert number to hexadecimal string",
279 returns: "Hexadecimal string (e.g., '2A' for 42)",
280 examples: vec![
281 "SELECT TO_HEX(255) -- 'ff'",
282 "SELECT TO_HEX(BIGPOW('16', 10)) -- '10000000000'",
283 ],
284 }
285 }
286
287 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
288 if args.len() != 1 {
289 return Err(anyhow!("TO_HEX expects 1 argument"));
290 }
291
292 let num = parse_bigint(&args[0])?;
293 if num.sign() == num_bigint::Sign::Minus {
294 return Ok(DataValue::String(format!(
295 "-{}",
296 num.abs().to_str_radix(16)
297 )));
298 }
299
300 Ok(DataValue::String(num.to_str_radix(16)))
301 }
302}
303
304pub struct FromHexFunction;
306
307impl SqlFunction for FromHexFunction {
308 fn signature(&self) -> FunctionSignature {
309 FunctionSignature {
310 name: "FROM_HEX",
311 category: FunctionCategory::BigNumber,
312 arg_count: ArgCount::Fixed(1),
313 description: "Convert hexadecimal string to decimal",
314 returns: "Decimal string representation",
315 examples: vec![
316 "SELECT FROM_HEX('FF') -- '255'",
317 "SELECT FROM_HEX('DEADBEEF') -- '3735928559'",
318 ],
319 }
320 }
321
322 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
323 if args.len() != 1 {
324 return Err(anyhow!("FROM_HEX expects 1 argument"));
325 }
326
327 let hex_str = match &args[0] {
328 DataValue::String(s) => s,
329 _ => return Err(anyhow!("FROM_HEX expects a string argument")),
330 };
331
332 let clean_hex = hex_str
334 .trim()
335 .trim_start_matches("0x")
336 .trim_start_matches("0X");
337
338 match BigInt::parse_bytes(clean_hex.as_bytes(), 16) {
339 Some(num) => Ok(DataValue::String(num.to_string())),
340 None => Err(anyhow!("Invalid hexadecimal string: {}", hex_str)),
341 }
342 }
343}
344
345pub struct BitAndFunction;
347
348impl SqlFunction for BitAndFunction {
349 fn signature(&self) -> FunctionSignature {
350 FunctionSignature {
351 name: "BITAND",
352 category: FunctionCategory::BigNumber,
353 arg_count: ArgCount::Fixed(2),
354 description: "Bitwise AND of two integers",
355 returns: "Result of bitwise AND",
356 examples: vec![
357 "SELECT BITAND(12, 10) -- 8 (1100 & 1010 = 1000)",
358 "SELECT TO_BINARY(BITAND(255, 15)) -- '1111'",
359 ],
360 }
361 }
362
363 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
364 if args.len() != 2 {
365 return Err(anyhow!("BITAND expects 2 arguments"));
366 }
367
368 let a = parse_bigint(&args[0])?;
369 let b = parse_bigint(&args[1])?;
370
371 Ok(DataValue::String((a & b).to_string()))
372 }
373}
374
375pub struct BitOrFunction;
377
378impl SqlFunction for BitOrFunction {
379 fn signature(&self) -> FunctionSignature {
380 FunctionSignature {
381 name: "BITOR",
382 category: FunctionCategory::BigNumber,
383 arg_count: ArgCount::Fixed(2),
384 description: "Bitwise OR of two integers",
385 returns: "Result of bitwise OR",
386 examples: vec![
387 "SELECT BITOR(12, 10) -- 14 (1100 | 1010 = 1110)",
388 "SELECT TO_BINARY(BITOR(8, 4)) -- '1100'",
389 ],
390 }
391 }
392
393 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
394 if args.len() != 2 {
395 return Err(anyhow!("BITOR expects 2 arguments"));
396 }
397
398 let a = parse_bigint(&args[0])?;
399 let b = parse_bigint(&args[1])?;
400
401 Ok(DataValue::String((a | b).to_string()))
402 }
403}
404
405pub struct BitXorFunction;
407
408impl SqlFunction for BitXorFunction {
409 fn signature(&self) -> FunctionSignature {
410 FunctionSignature {
411 name: "BITXOR",
412 category: FunctionCategory::BigNumber,
413 arg_count: ArgCount::Fixed(2),
414 description: "Bitwise XOR of two integers",
415 returns: "Result of bitwise XOR",
416 examples: vec![
417 "SELECT BITXOR(12, 10) -- 6 (1100 ^ 1010 = 0110)",
418 "SELECT TO_BINARY(BITXOR(255, 170)) -- '01010101'",
419 ],
420 }
421 }
422
423 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
424 if args.len() != 2 {
425 return Err(anyhow!("BITXOR expects 2 arguments"));
426 }
427
428 let a = parse_bigint(&args[0])?;
429 let b = parse_bigint(&args[1])?;
430
431 Ok(DataValue::String((a ^ b).to_string()))
432 }
433}
434
435pub struct BitShiftFunction;
437
438impl SqlFunction for BitShiftFunction {
439 fn signature(&self) -> FunctionSignature {
440 FunctionSignature {
441 name: "BITSHIFT",
442 category: FunctionCategory::BigNumber,
443 arg_count: ArgCount::Fixed(2),
444 description: "Bit shift: left for positive shift, right for negative",
445 returns: "Result of bit shift",
446 examples: vec![
447 "SELECT BITSHIFT(1, 10) -- 1024 (1 << 10)",
448 "SELECT BITSHIFT(1024, -10) -- 1 (1024 >> 10)",
449 "SELECT TO_BINARY(BITSHIFT(1, 100)) -- 1 followed by 100 zeros",
450 ],
451 }
452 }
453
454 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
455 if args.len() != 2 {
456 return Err(anyhow!("BITSHIFT expects 2 arguments"));
457 }
458
459 let num = parse_bigint(&args[0])?;
460 let shift = match &args[1] {
461 DataValue::Integer(n) => *n,
462 DataValue::String(s) => s
463 .parse::<i64>()
464 .map_err(|_| anyhow!("Shift amount must be an integer"))?,
465 _ => return Err(anyhow!("Shift amount must be an integer")),
466 };
467
468 let result = if shift >= 0 {
469 num << (shift as usize)
470 } else {
471 num >> ((-shift) as usize)
472 };
473
474 Ok(DataValue::String(result.to_string()))
475 }
476}
477
478fn parse_bigint(value: &DataValue) -> Result<BigInt> {
480 match value {
481 DataValue::String(s) => s
482 .parse::<BigInt>()
483 .map_err(|_| anyhow!("Invalid big integer format: {}", s)),
484 DataValue::Integer(n) => Ok(BigInt::from(*n)),
485 DataValue::Float(f) => Ok(BigInt::from(*f as i64)),
486 DataValue::Null => Ok(BigInt::zero()),
487 _ => Err(anyhow!("Expected numeric or string value for big integer")),
488 }
489}