sql_cli/sql/generators/
prime_generators.rs1use super::{create_single_column_table, create_two_column_table, TableGenerator};
2use crate::data::datatable::{DataColumn, DataTable, DataValue};
3use anyhow::Result;
4use std::sync::Arc;
5
6pub struct GeneratePrimes;
8
9impl TableGenerator for GeneratePrimes {
10 fn name(&self) -> &str {
11 "GENERATE_PRIMES"
12 }
13
14 fn columns(&self) -> Vec<DataColumn> {
15 vec![DataColumn::new("prime")]
16 }
17
18 fn generate(&self, args: Vec<DataValue>) -> Result<Arc<DataTable>> {
19 if args.len() != 1 {
20 return Err(anyhow::anyhow!(
21 "GENERATE_PRIMES expects 1 argument (limit)"
22 ));
23 }
24
25 let limit = match &args[0] {
26 DataValue::Integer(n) => *n as usize,
27 DataValue::Float(f) => *f as usize,
28 _ => return Err(anyhow::anyhow!("GENERATE_PRIMES limit must be a number")),
29 };
30
31 let primes = sieve_of_eratosthenes(limit);
32 let values: Vec<DataValue> = primes
33 .into_iter()
34 .map(|p| DataValue::Integer(p as i64))
35 .collect();
36
37 Ok(create_single_column_table("primes", "prime", values))
38 }
39
40 fn description(&self) -> &str {
41 "Generate all prime numbers up to a given limit"
42 }
43
44 fn arg_count(&self) -> usize {
45 1
46 }
47}
48
49pub struct PrimeFactors;
51
52impl TableGenerator for PrimeFactors {
53 fn name(&self) -> &str {
54 "PRIME_FACTORS"
55 }
56
57 fn columns(&self) -> Vec<DataColumn> {
58 vec![DataColumn::new("factor"), DataColumn::new("power")]
59 }
60
61 fn generate(&self, args: Vec<DataValue>) -> Result<Arc<DataTable>> {
62 if args.len() != 1 {
63 return Err(anyhow::anyhow!("PRIME_FACTORS expects 1 argument (number)"));
64 }
65
66 let number = match &args[0] {
67 DataValue::Integer(n) => *n as u64,
68 DataValue::Float(f) => *f as u64,
69 _ => return Err(anyhow::anyhow!("PRIME_FACTORS argument must be a number")),
70 };
71
72 let factors = factorize(number);
73 let rows: Vec<(DataValue, DataValue)> = factors
74 .into_iter()
75 .map(|(factor, power)| {
76 (
77 DataValue::Integer(factor as i64),
78 DataValue::Integer(power as i64),
79 )
80 })
81 .collect();
82
83 Ok(create_two_column_table("factors", "factor", "power", rows))
84 }
85
86 fn description(&self) -> &str {
87 "Generate prime factorization of a number as (factor, power) pairs"
88 }
89
90 fn arg_count(&self) -> usize {
91 1
92 }
93}
94
95pub struct Fibonacci;
97
98impl TableGenerator for Fibonacci {
99 fn name(&self) -> &str {
100 "FIBONACCI"
101 }
102
103 fn columns(&self) -> Vec<DataColumn> {
104 vec![DataColumn::new("n"), DataColumn::new("value")]
105 }
106
107 fn generate(&self, args: Vec<DataValue>) -> Result<Arc<DataTable>> {
108 if args.len() != 1 {
109 return Err(anyhow::anyhow!("FIBONACCI expects 1 argument (count)"));
110 }
111
112 let count = match &args[0] {
113 DataValue::Integer(n) => *n as usize,
114 DataValue::Float(f) => *f as usize,
115 _ => return Err(anyhow::anyhow!("FIBONACCI count must be a number")),
116 };
117
118 let mut rows = Vec::new();
119 let mut a: u64 = 0;
120 let mut b: u64 = 1;
121
122 for i in 0..count {
123 rows.push((DataValue::Integer(i as i64), DataValue::Integer(a as i64)));
124
125 if i > 0 {
126 let next = a.saturating_add(b);
127 a = b;
128 b = next;
129 } else {
130 a = 1;
131 }
132 }
133
134 Ok(create_two_column_table("fibonacci", "n", "value", rows))
135 }
136
137 fn description(&self) -> &str {
138 "Generate Fibonacci sequence up to n terms"
139 }
140
141 fn arg_count(&self) -> usize {
142 1
143 }
144}
145
146fn sieve_of_eratosthenes(limit: usize) -> Vec<usize> {
148 if limit < 2 {
149 return vec![];
150 }
151
152 let mut is_prime = vec![true; limit + 1];
153 is_prime[0] = false;
154 is_prime[1] = false;
155
156 for i in 2..=((limit as f64).sqrt() as usize) {
157 if is_prime[i] {
158 for j in ((i * i)..=limit).step_by(i) {
159 is_prime[j] = false;
160 }
161 }
162 }
163
164 is_prime
165 .into_iter()
166 .enumerate()
167 .filter_map(|(num, prime)| if prime { Some(num) } else { None })
168 .collect()
169}
170
171fn factorize(mut n: u64) -> Vec<(u64, u32)> {
173 if n <= 1 {
174 return vec![];
175 }
176
177 let mut factors = Vec::new();
178
179 let mut power = 0;
181 while n % 2 == 0 {
182 power += 1;
183 n /= 2;
184 }
185 if power > 0 {
186 factors.push((2, power));
187 }
188
189 let mut i = 3;
191 while i * i <= n {
192 power = 0;
193 while n % i == 0 {
194 power += 1;
195 n /= i;
196 }
197 if power > 0 {
198 factors.push((i, power));
199 }
200 i += 2;
201 }
202
203 if n > 1 {
205 factors.push((n, 1));
206 }
207
208 factors
209}
210
211#[cfg(test)]
212mod tests {
213 use super::*;
214
215 #[test]
216 fn test_sieve_of_eratosthenes() {
217 assert_eq!(sieve_of_eratosthenes(10), vec![2, 3, 5, 7]);
218 assert_eq!(
219 sieve_of_eratosthenes(30),
220 vec![2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
221 );
222 }
223
224 #[test]
225 fn test_factorize() {
226 assert_eq!(factorize(12), vec![(2, 2), (3, 1)]);
227 assert_eq!(factorize(1260), vec![(2, 2), (3, 2), (5, 1), (7, 1)]);
228 assert_eq!(factorize(17), vec![(17, 1)]);
229 }
230}