sql_cli/sql/functions/
mod.rs

1use anyhow::{anyhow, Result};
2use std::collections::HashMap;
3use std::fmt;
4use std::sync::Arc;
5
6use crate::data::datatable::DataValue;
7
8pub mod astronomy;
9pub mod base_conversion;
10pub mod bigint;
11pub mod bitwise;
12pub mod bitwise_string;
13pub mod case_convert;
14pub mod chemistry;
15pub mod comparison;
16pub mod constants;
17pub mod convert;
18pub mod date_time;
19pub mod financial;
20pub mod format;
21pub mod format_number;
22pub mod geometry;
23pub mod group_num;
24pub mod hash;
25pub mod integer_limits;
26pub mod math;
27pub mod mathematics;
28pub mod number_words;
29pub mod particle_charges;
30pub mod physics;
31pub mod random;
32pub mod roman;
33pub mod solar_system;
34pub mod statistics;
35pub mod string_fun;
36pub mod string_methods;
37pub mod string_utils;
38pub mod text_processing;
39pub mod trigonometry;
40pub mod type_checking;
41pub mod utility;
42
43// Re-export MethodFunction trait
44pub use string_methods::MethodFunction;
45
46/// Category of SQL functions for organization and discovery
47#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
48pub enum FunctionCategory {
49    Constant,      // Mathematical and physical constants
50    Mathematical,  // Mathematical operations
51    Statistical,   // Statistical functions
52    Astronomical,  // Astronomical constants and calculations
53    Chemical,      // Chemical elements and properties
54    Date,          // Date/time operations
55    String,        // String manipulation
56    Aggregate,     // Aggregation functions
57    Conversion,    // Unit conversion functions
58    BigNumber,     // Arbitrary precision arithmetic
59    TableFunction, // Table-generating functions
60    Bitwise,       // Bitwise operations and binary visualization
61}
62
63impl fmt::Display for FunctionCategory {
64    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65        match self {
66            FunctionCategory::Constant => write!(f, "Constant"),
67            FunctionCategory::Mathematical => write!(f, "Mathematical"),
68            FunctionCategory::Statistical => write!(f, "Statistical"),
69            FunctionCategory::Astronomical => write!(f, "Astronomical"),
70            FunctionCategory::Chemical => write!(f, "Chemical"),
71            FunctionCategory::Date => write!(f, "Date"),
72            FunctionCategory::String => write!(f, "String"),
73            FunctionCategory::Aggregate => write!(f, "Aggregate"),
74            FunctionCategory::Conversion => write!(f, "Conversion"),
75            FunctionCategory::BigNumber => write!(f, "BigNumber"),
76            FunctionCategory::TableFunction => write!(f, "TableFunction"),
77            FunctionCategory::Bitwise => write!(f, "Bitwise"),
78        }
79    }
80}
81
82/// Describes the number of arguments a function accepts
83#[derive(Debug, Clone)]
84pub enum ArgCount {
85    /// Exactly n arguments
86    Fixed(usize),
87    /// Between min and max arguments (inclusive)
88    Range(usize, usize),
89    /// Any number of arguments
90    Variadic,
91}
92
93impl ArgCount {
94    #[must_use]
95    pub fn is_valid(&self, count: usize) -> bool {
96        match self {
97            ArgCount::Fixed(n) => count == *n,
98            ArgCount::Range(min, max) => count >= *min && count <= *max,
99            ArgCount::Variadic => true,
100        }
101    }
102
103    #[must_use]
104    pub fn description(&self) -> String {
105        match self {
106            ArgCount::Fixed(0) => "no arguments".to_string(),
107            ArgCount::Fixed(1) => "1 argument".to_string(),
108            ArgCount::Fixed(n) => format!("{n} arguments"),
109            ArgCount::Range(min, max) => format!("{min} to {max} arguments"),
110            ArgCount::Variadic => "any number of arguments".to_string(),
111        }
112    }
113}
114
115/// Signature of a SQL function including metadata
116#[derive(Debug, Clone)]
117pub struct FunctionSignature {
118    pub name: &'static str,
119    pub category: FunctionCategory,
120    pub arg_count: ArgCount,
121    pub description: &'static str,
122    pub returns: &'static str,
123    pub examples: Vec<&'static str>,
124}
125
126/// Trait that all SQL functions must implement
127pub trait SqlFunction: Send + Sync {
128    /// Get the function's signature and metadata
129    fn signature(&self) -> FunctionSignature;
130
131    /// Evaluate the function with the given arguments
132    fn evaluate(&self, args: &[DataValue]) -> Result<DataValue>;
133
134    /// Validate arguments before evaluation (default implementation checks count)
135    fn validate_args(&self, args: &[DataValue]) -> Result<()> {
136        let sig = self.signature();
137        if !sig.arg_count.is_valid(args.len()) {
138            return Err(anyhow!(
139                "{}() expects {}, got {}",
140                sig.name,
141                sig.arg_count.description(),
142                args.len()
143            ));
144        }
145        Ok(())
146    }
147}
148
149/// Registry for all SQL functions
150pub struct FunctionRegistry {
151    functions: HashMap<String, Box<dyn SqlFunction>>,
152    by_category: HashMap<FunctionCategory, Vec<String>>,
153    methods: HashMap<String, Arc<dyn MethodFunction>>,
154}
155
156impl FunctionRegistry {
157    /// Create a new registry with all built-in functions
158    #[must_use]
159    pub fn new() -> Self {
160        let mut registry = Self {
161            functions: HashMap::new(),
162            by_category: HashMap::new(),
163            methods: HashMap::new(),
164        };
165
166        // Register all built-in functions
167        registry.register_constants();
168        registry.register_astronomical_functions();
169        registry.register_chemical_functions();
170        registry.register_mathematical_functions();
171        registry.register_statistical_functions();
172        registry.register_geometry_functions();
173        registry.register_physics_functions();
174        registry.register_date_time_functions();
175        registry.register_string_methods();
176        registry.register_financial_functions();
177        registry.register_bigint_functions();
178        registry.register_conversion_functions();
179        registry.register_hash_functions();
180        registry.register_comparison_functions();
181        registry.register_aggregate_functions();
182        registry.register_random_functions();
183        registry.register_format_functions();
184        registry.register_type_checking_functions();
185        registry.register_utility_functions();
186        registry.register_bitwise_functions();
187
188        registry
189    }
190
191    /// Register a function in the registry
192    pub fn register(&mut self, func: Box<dyn SqlFunction>) {
193        let sig = func.signature();
194        let name = sig.name.to_uppercase();
195        let category = sig.category;
196
197        // Add to main registry
198        self.functions.insert(name.clone(), func);
199
200        // Add to category index
201        self.by_category.entry(category).or_default().push(name);
202    }
203
204    /// Get a function by name (case-insensitive)
205    #[must_use]
206    pub fn get(&self, name: &str) -> Option<&dyn SqlFunction> {
207        self.functions
208            .get(&name.to_uppercase())
209            .map(std::convert::AsRef::as_ref)
210    }
211
212    /// Check if a function exists
213    #[must_use]
214    pub fn contains(&self, name: &str) -> bool {
215        self.functions.contains_key(&name.to_uppercase())
216    }
217
218    /// Get all functions matching a prefix (for autocomplete)
219    #[must_use]
220    pub fn autocomplete(&self, prefix: &str) -> Vec<FunctionSignature> {
221        let prefix_upper = prefix.to_uppercase();
222        self.functions
223            .iter()
224            .filter(|(name, _)| name.starts_with(&prefix_upper))
225            .map(|(_, func)| func.signature())
226            .collect()
227    }
228
229    /// Get all functions in a category
230    #[must_use]
231    pub fn get_by_category(&self, category: FunctionCategory) -> Vec<FunctionSignature> {
232        self.by_category
233            .get(&category)
234            .map(|names| {
235                names
236                    .iter()
237                    .filter_map(|name| self.functions.get(name))
238                    .map(|func| func.signature())
239                    .collect()
240            })
241            .unwrap_or_default()
242    }
243
244    /// Get all available functions
245    #[must_use]
246    pub fn all_functions(&self) -> Vec<FunctionSignature> {
247        self.functions
248            .values()
249            .map(|func| func.signature())
250            .collect()
251    }
252
253    /// Register a method function
254    pub fn register_method(&mut self, method: Arc<dyn MethodFunction>) {
255        let method_name = method.method_name().to_uppercase();
256        self.methods.insert(method_name, method);
257    }
258
259    /// Get a method function by name
260    #[must_use]
261    pub fn get_method(&self, name: &str) -> Option<Arc<dyn MethodFunction>> {
262        // Try exact match first
263        if let Some(method) = self.methods.get(&name.to_uppercase()) {
264            return Some(Arc::clone(method));
265        }
266
267        // Try to find a method that handles this name
268        for method in self.methods.values() {
269            if method.handles_method(name) {
270                return Some(Arc::clone(method));
271            }
272        }
273
274        None
275    }
276
277    /// Check if a method exists
278    #[must_use]
279    pub fn has_method(&self, name: &str) -> bool {
280        self.get_method(name).is_some()
281    }
282
283    /// Generate markdown documentation for all functions
284    #[must_use]
285    pub fn generate_markdown_docs(&self) -> String {
286        use std::fmt::Write;
287        let mut doc = String::new();
288
289        writeln!(&mut doc, "# SQL CLI Function Reference\n").unwrap();
290        writeln!(
291            &mut doc,
292            "This document is auto-generated from the function registry.\n"
293        )
294        .unwrap();
295
296        // Get all categories in a deterministic order
297        let mut categories: Vec<FunctionCategory> = self.by_category.keys().copied().collect();
298        categories.sort_by_key(|c| format!("{c:?}"));
299
300        for category in categories {
301            let functions = self.get_by_category(category);
302            if functions.is_empty() {
303                continue;
304            }
305
306            writeln!(&mut doc, "## {category} Functions\n").unwrap();
307
308            // Sort functions by name for consistent output
309            let mut functions = functions;
310            functions.sort_by_key(|f| f.name);
311
312            for func in functions {
313                writeln!(&mut doc, "### {}()\n", func.name).unwrap();
314                writeln!(&mut doc, "**Description:** {}\n", func.description).unwrap();
315                writeln!(
316                    &mut doc,
317                    "**Arguments:** {}\n",
318                    func.arg_count.description()
319                )
320                .unwrap();
321                writeln!(&mut doc, "**Returns:** {}\n", func.returns).unwrap();
322
323                if !func.examples.is_empty() {
324                    writeln!(&mut doc, "**Examples:**").unwrap();
325                    writeln!(&mut doc, "```sql").unwrap();
326                    for example in &func.examples {
327                        writeln!(&mut doc, "{example}").unwrap();
328                    }
329                    writeln!(&mut doc, "```\n").unwrap();
330                }
331            }
332        }
333
334        doc
335    }
336
337    /// Generate help text for a specific function
338    #[must_use]
339    pub fn generate_function_help(&self, name: &str) -> Option<String> {
340        self.get(name).map(|func| {
341            let sig = func.signature();
342            let mut help = String::new();
343            use std::fmt::Write;
344
345            writeln!(&mut help, "Function: {}()", sig.name).unwrap();
346            writeln!(&mut help, "Category: {}", sig.category).unwrap();
347            writeln!(&mut help, "Description: {}", sig.description).unwrap();
348            writeln!(&mut help, "Arguments: {}", sig.arg_count.description()).unwrap();
349            writeln!(&mut help, "Returns: {}", sig.returns).unwrap();
350
351            if !sig.examples.is_empty() {
352                writeln!(&mut help, "\nExamples:").unwrap();
353                for example in &sig.examples {
354                    writeln!(&mut help, "  {example}").unwrap();
355                }
356            }
357
358            help
359        })
360    }
361
362    /// List all available functions with brief descriptions
363    #[must_use]
364    pub fn list_functions(&self) -> String {
365        use std::fmt::Write;
366        let mut list = String::new();
367
368        writeln!(&mut list, "Available SQL Functions:\n").unwrap();
369
370        let mut categories: Vec<FunctionCategory> = self.by_category.keys().copied().collect();
371        categories.sort_by_key(|c| format!("{c:?}"));
372
373        for category in categories {
374            let functions = self.get_by_category(category);
375            if functions.is_empty() {
376                continue;
377            }
378
379            writeln!(&mut list, "{category} Functions:").unwrap();
380
381            let mut functions = functions;
382            functions.sort_by_key(|f| f.name);
383
384            for func in functions {
385                writeln!(
386                    &mut list,
387                    "  {:20} - {}",
388                    format!("{}()", func.name),
389                    func.description
390                )
391                .unwrap();
392            }
393            writeln!(&mut list).unwrap();
394        }
395
396        list
397    }
398
399    /// Register constant functions
400    fn register_constants(&mut self) {
401        use constants::{
402            EFunction, HbarFunction, MassElectronFunction, MeFunction, PhiFunction, PiFunction,
403            TauFunction,
404        };
405
406        self.register(Box::new(PiFunction));
407        self.register(Box::new(EFunction));
408        self.register(Box::new(MeFunction)); // Mass of electron
409        self.register(Box::new(MassElectronFunction)); // Alias for ME
410        self.register(Box::new(TauFunction));
411        self.register(Box::new(PhiFunction));
412        self.register(Box::new(HbarFunction));
413    }
414
415    /// Register astronomical functions
416    fn register_astronomical_functions(&mut self) {
417        use astronomy::{
418            AuFunction, DistJupiterFunction, DistMarsFunction, DistMercuryFunction,
419            DistNeptuneFunction, DistSaturnFunction, DistUranusFunction, DistVenusFunction,
420            LightYearFunction, MassEarthFunction, MassJupiterFunction, MassMarsFunction,
421            MassMercuryFunction, MassMoonFunction, MassNeptuneFunction, MassSaturnFunction,
422            MassSunFunction, MassUranusFunction, MassVenusFunction, ParsecFunction,
423            RadiusEarthFunction, RadiusJupiterFunction, RadiusMarsFunction, RadiusMercuryFunction,
424            RadiusMoonFunction, RadiusNeptuneFunction, RadiusSaturnFunction, RadiusSunFunction,
425            RadiusUranusFunction, RadiusVenusFunction,
426        };
427
428        use solar_system::{
429            DensitySolarBodyFunction, DistanceSolarBodyFunction, EscapeVelocitySolarBodyFunction,
430            GravitySolarBodyFunction, MassSolarBodyFunction, MoonsSolarBodyFunction,
431            OrbitalPeriodSolarBodyFunction, RadiusSolarBodyFunction,
432            RotationPeriodSolarBodyFunction,
433        };
434
435        self.register(Box::new(MassEarthFunction));
436        self.register(Box::new(MassSunFunction));
437        self.register(Box::new(MassMoonFunction));
438        self.register(Box::new(AuFunction)); // Astronomical unit
439        self.register(Box::new(LightYearFunction));
440        self.register(Box::new(ParsecFunction));
441
442        // Planetary masses
443        self.register(Box::new(MassMercuryFunction));
444        self.register(Box::new(MassVenusFunction));
445        self.register(Box::new(MassMarsFunction));
446        self.register(Box::new(MassJupiterFunction));
447        self.register(Box::new(MassSaturnFunction));
448        self.register(Box::new(MassUranusFunction));
449        self.register(Box::new(MassNeptuneFunction));
450
451        // Solar body radius functions
452        self.register(Box::new(RadiusSunFunction));
453        self.register(Box::new(RadiusEarthFunction));
454        self.register(Box::new(RadiusMoonFunction));
455        self.register(Box::new(RadiusMercuryFunction));
456        self.register(Box::new(RadiusVenusFunction));
457        self.register(Box::new(RadiusMarsFunction));
458        self.register(Box::new(RadiusJupiterFunction));
459        self.register(Box::new(RadiusSaturnFunction));
460        self.register(Box::new(RadiusUranusFunction));
461        self.register(Box::new(RadiusNeptuneFunction));
462
463        // Planetary distances from the Sun
464        self.register(Box::new(DistMercuryFunction));
465        self.register(Box::new(DistVenusFunction));
466        self.register(Box::new(DistMarsFunction));
467        self.register(Box::new(DistJupiterFunction));
468        self.register(Box::new(DistSaturnFunction));
469        self.register(Box::new(DistUranusFunction));
470        self.register(Box::new(DistNeptuneFunction));
471
472        // Solar system lookup functions
473        self.register(Box::new(MassSolarBodyFunction));
474        self.register(Box::new(RadiusSolarBodyFunction));
475        self.register(Box::new(DistanceSolarBodyFunction));
476        self.register(Box::new(OrbitalPeriodSolarBodyFunction));
477        self.register(Box::new(GravitySolarBodyFunction));
478        self.register(Box::new(DensitySolarBodyFunction));
479        self.register(Box::new(EscapeVelocitySolarBodyFunction));
480        self.register(Box::new(RotationPeriodSolarBodyFunction));
481        self.register(Box::new(MoonsSolarBodyFunction));
482    }
483
484    /// Register chemical functions
485    fn register_chemical_functions(&mut self) {
486        use chemistry::{
487            AtomicMassFunction, AtomicNumberFunction, AvogadroFunction, MoleculeFormulaFunction,
488            NeutronsFunction,
489        };
490
491        self.register(Box::new(AvogadroFunction));
492        self.register(Box::new(AtomicMassFunction));
493        self.register(Box::new(AtomicNumberFunction));
494        self.register(Box::new(NeutronsFunction));
495        self.register(Box::new(MoleculeFormulaFunction));
496    }
497
498    /// Register string method functions
499    fn register_string_methods(&mut self) {
500        use case_convert::{
501            ToCamelCaseFunction, ToConstantCaseFunction, ToKebabCaseFunction, ToPascalCaseFunction,
502            ToSnakeCaseFunction,
503        };
504        use number_words::{ToOrdinal, ToOrdinalWords, ToWords};
505        use string_fun::{
506            InitCapFunction, MorseCodeFunction, PigLatinFunction, ProperFunction, ReverseFunction,
507            Rot13Function, ScrambleFunction, SoundexFunction,
508        };
509        use string_utils::{LPadFunction, RPadFunction, RepeatFunction};
510        use text_processing::{CleanText, ExtractWords, StripPunctuation, Tokenize, WordCount};
511
512        string_methods::register_string_methods(self);
513
514        // String utility functions
515        self.register(Box::new(RepeatFunction));
516        self.register(Box::new(LPadFunction));
517        self.register(Box::new(RPadFunction));
518
519        // Case conversion functions
520        self.register(Box::new(ToSnakeCaseFunction));
521        self.register(Box::new(ToCamelCaseFunction));
522        self.register(Box::new(ToPascalCaseFunction));
523        self.register(Box::new(ToKebabCaseFunction));
524        self.register(Box::new(ToConstantCaseFunction));
525
526        // String fun & transformation functions
527        self.register(Box::new(ReverseFunction));
528        self.register(Box::new(InitCapFunction));
529        self.register(Box::new(ProperFunction));
530        self.register(Box::new(Rot13Function));
531        self.register(Box::new(SoundexFunction));
532        self.register(Box::new(PigLatinFunction));
533        self.register(Box::new(MorseCodeFunction));
534        self.register(Box::new(ScrambleFunction));
535
536        // Number to words functions
537        self.register(Box::new(ToWords));
538        self.register(Box::new(ToOrdinal));
539        self.register(Box::new(ToOrdinalWords));
540
541        // Text processing functions
542        self.register(Box::new(StripPunctuation));
543        self.register(Box::new(Tokenize));
544        self.register(Box::new(CleanText));
545        self.register(Box::new(ExtractWords));
546        self.register(Box::new(WordCount));
547    }
548
549    /// Register geometry functions
550    fn register_geometry_functions(&mut self) {
551        use geometry::{
552            CircleAreaFunction, CircleCircumferenceFunction, Distance2DFunction,
553            PythagorasFunction, SphereSurfaceAreaFunction, SphereVolumeFunction,
554            TriangleAreaFunction,
555        };
556
557        self.register(Box::new(PythagorasFunction));
558        self.register(Box::new(CircleAreaFunction));
559        self.register(Box::new(CircleCircumferenceFunction));
560        self.register(Box::new(SphereVolumeFunction));
561        self.register(Box::new(SphereSurfaceAreaFunction));
562        self.register(Box::new(TriangleAreaFunction));
563        self.register(Box::new(Distance2DFunction));
564    }
565
566    /// Register hash functions
567    fn register_hash_functions(&mut self) {
568        use hash::{Md5Function, Sha1Function, Sha256Function, Sha512Function};
569
570        self.register(Box::new(Md5Function));
571        self.register(Box::new(Sha1Function));
572        self.register(Box::new(Sha256Function));
573        self.register(Box::new(Sha512Function));
574    }
575
576    /// Register comparison functions
577    fn register_comparison_functions(&mut self) {
578        comparison::register_comparison_functions(self);
579    }
580
581    /// Register mathematical functions
582    fn register_mathematical_functions(&mut self) {
583        use base_conversion::{
584            FromBase, FromBinary, FromHex, FromOctal, ToBase, ToBinary, ToHex, ToOctal,
585        };
586        use integer_limits::{
587            ByteMax, ByteMin, CharMax, CharMin, Int16Max, Int16Min, Int32Max, Int32Min, Int64Max,
588            Int64Min, Int8Max, Int8Min, IntMax, IntMin, LongMax, LongMin, ShortMax, ShortMin,
589            Uint16Max, Uint32Max, Uint8Max,
590        };
591        use mathematics::{
592            IsPrimeFunction, NextPrimeFunction, NthPrimeFunction, PrevPrimeFunction,
593            PrimeCountFunction, PrimeFunction, PrimePiFunction,
594        };
595        use trigonometry::{
596            AcosFunction, AsinFunction, Atan2Function, AtanFunction, CosFunction, CoshFunction,
597            CotFunction, SinFunction, SinhFunction, TanFunction, TanhFunction,
598        };
599
600        // Prime number functions
601        self.register(Box::new(PrimeFunction));
602        self.register(Box::new(NthPrimeFunction)); // Alias for PRIME
603        self.register(Box::new(IsPrimeFunction));
604        self.register(Box::new(PrimeCountFunction));
605        self.register(Box::new(PrimePiFunction)); // Alias for PRIME_COUNT
606        self.register(Box::new(NextPrimeFunction));
607        self.register(Box::new(PrevPrimeFunction));
608
609        // Trigonometric functions
610        self.register(Box::new(SinFunction));
611        self.register(Box::new(CosFunction));
612        self.register(Box::new(TanFunction));
613        self.register(Box::new(CotFunction));
614        self.register(Box::new(AsinFunction));
615        self.register(Box::new(AcosFunction));
616        self.register(Box::new(AtanFunction));
617        self.register(Box::new(Atan2Function));
618
619        // Hyperbolic functions
620        self.register(Box::new(SinhFunction));
621        self.register(Box::new(CoshFunction));
622        self.register(Box::new(TanhFunction));
623
624        // Base conversion functions
625        self.register(Box::new(ToBase));
626        self.register(Box::new(FromBase));
627        self.register(Box::new(ToBinary));
628        self.register(Box::new(FromBinary));
629        self.register(Box::new(ToHex));
630        self.register(Box::new(FromHex));
631        self.register(Box::new(ToOctal));
632        self.register(Box::new(FromOctal));
633
634        // Integer limit functions
635        self.register(Box::new(Int8Min));
636        self.register(Box::new(Int8Max));
637        self.register(Box::new(Uint8Max));
638        self.register(Box::new(Int16Min));
639        self.register(Box::new(Int16Max));
640        self.register(Box::new(Uint16Max));
641        self.register(Box::new(Int32Min));
642        self.register(Box::new(Int32Max));
643        self.register(Box::new(Uint32Max));
644        self.register(Box::new(Int64Min));
645        self.register(Box::new(Int64Max));
646
647        // Alias functions for common names
648        self.register(Box::new(ByteMin));
649        self.register(Box::new(ByteMax));
650        self.register(Box::new(CharMin));
651        self.register(Box::new(CharMax));
652        self.register(Box::new(ShortMin));
653        self.register(Box::new(ShortMax));
654        self.register(Box::new(IntMin));
655        self.register(Box::new(IntMax));
656        self.register(Box::new(LongMin));
657        self.register(Box::new(LongMax));
658
659        // General math functions
660        math::register_math_functions(self);
661    }
662
663    /// Register physics constants
664    fn register_physics_functions(&mut self) {
665        physics::register_physics_functions(self);
666
667        // Register particle charge functions
668        use particle_charges::{
669            ChargeDownQuarkFunction, ChargeElectronFunction, ChargeMuonFunction,
670            ChargeNeutronFunction, ChargePositronFunction, ChargeProtonFunction, ChargeTauFunction,
671            ChargeUpQuarkFunction,
672        };
673
674        self.register(Box::new(ChargeElectronFunction));
675        self.register(Box::new(ChargeProtonFunction));
676        self.register(Box::new(ChargeNeutronFunction));
677        self.register(Box::new(ChargeUpQuarkFunction));
678        self.register(Box::new(ChargeDownQuarkFunction));
679        self.register(Box::new(ChargePositronFunction));
680        self.register(Box::new(ChargeMuonFunction));
681        self.register(Box::new(ChargeTauFunction));
682    }
683
684    /// Register date/time functions
685    fn register_date_time_functions(&mut self) {
686        date_time::register_date_time_functions(self);
687    }
688
689    /// Register financial functions
690    fn register_financial_functions(&mut self) {
691        financial::register_financial_functions(self);
692    }
693
694    /// Register conversion functions
695    fn register_conversion_functions(&mut self) {
696        use convert::ConvertFunction;
697        use roman::{FromRoman, ToRoman};
698
699        self.register(Box::new(ConvertFunction));
700        self.register(Box::new(ToRoman));
701        self.register(Box::new(FromRoman));
702    }
703
704    /// Register statistical functions
705    fn register_statistical_functions(&mut self) {
706        use statistics::{
707            CorrelationFunction, KurtosisFunction, MedianFunction, ModeFunction,
708            PercentileFunction, SkewFunction, VarPopFunction, VarSampFunction, VarianceFunction,
709        };
710
711        self.register(Box::new(MedianFunction));
712        self.register(Box::new(PercentileFunction));
713        self.register(Box::new(ModeFunction));
714        self.register(Box::new(VarianceFunction));
715        self.register(Box::new(VarSampFunction));
716        self.register(Box::new(VarPopFunction));
717        self.register(Box::new(CorrelationFunction));
718        self.register(Box::new(SkewFunction));
719        self.register(Box::new(KurtosisFunction));
720    }
721
722    /// Register aggregate and analytic functions
723    fn register_aggregate_functions(&mut self) {
724        use group_num::GroupNumFunction;
725
726        // Register GROUP_NUM function
727        // Note: We create a new instance per query to ensure clean memoization
728        self.register(Box::new(GroupNumFunction::new()));
729    }
730
731    /// Register random number generation functions
732    fn register_random_functions(&mut self) {
733        use random::{RandIntFunction, RandRangeFunction, RandomFunction};
734
735        self.register(Box::new(RandomFunction));
736        self.register(Box::new(RandIntFunction));
737        self.register(Box::new(RandRangeFunction));
738    }
739
740    /// Register formatting functions
741    fn register_format_functions(&mut self) {
742        use format::{
743            CenterFunction, FormatDateFunction, FormatNumberFunction, LPadFunction, RPadFunction,
744        };
745        use format_number::{FormatCurrencyFunction, RenderNumberFunction};
746
747        self.register(Box::new(FormatNumberFunction));
748        self.register(Box::new(FormatDateFunction));
749        self.register(Box::new(LPadFunction));
750        self.register(Box::new(RPadFunction));
751        self.register(Box::new(CenterFunction));
752        self.register(Box::new(RenderNumberFunction));
753        self.register(Box::new(FormatCurrencyFunction));
754    }
755
756    /// Register type checking functions
757    fn register_type_checking_functions(&mut self) {
758        use type_checking::{
759            IsBoolFunction, IsDateFunction, IsFloatFunction, IsIntegerFunction, IsNotNullFunction,
760            IsNullFunction, IsNumericFunction,
761        };
762
763        self.register(Box::new(IsDateFunction));
764        self.register(Box::new(IsBoolFunction));
765        self.register(Box::new(IsNumericFunction));
766        self.register(Box::new(IsIntegerFunction));
767        self.register(Box::new(IsFloatFunction));
768        self.register(Box::new(IsNullFunction));
769        self.register(Box::new(IsNotNullFunction));
770    }
771
772    /// Register utility functions
773    fn register_utility_functions(&mut self) {
774        use utility::{
775            AsciiFunction, CharFunction, DecodeFunction, EncodeFunction, OrdFunction,
776            ToDecimalFunction, ToIntFunction, ToStringFunction, UnicodeFunction,
777        };
778
779        self.register(Box::new(AsciiFunction));
780        self.register(Box::new(OrdFunction));
781        self.register(Box::new(CharFunction));
782        self.register(Box::new(ToIntFunction));
783        self.register(Box::new(ToDecimalFunction));
784        self.register(Box::new(ToStringFunction));
785        self.register(Box::new(EncodeFunction));
786        self.register(Box::new(DecodeFunction));
787        self.register(Box::new(UnicodeFunction));
788    }
789
790    /// Register big integer and bit manipulation functions
791    fn register_bigint_functions(&mut self) {
792        use bigint::{
793            BigAddFunction, BigFactorialFunction, BigIntFunction, BigMulFunction, BigPowFunction,
794            BitAndFunction, BitOrFunction, BitShiftFunction, BitXorFunction, FromBinaryFunction,
795            FromHexFunction, ToBinaryFunction, ToHexFunction,
796        };
797
798        // Arbitrary precision arithmetic
799        self.register(Box::new(BigIntFunction));
800        self.register(Box::new(BigAddFunction));
801        self.register(Box::new(BigMulFunction));
802        self.register(Box::new(BigPowFunction));
803        self.register(Box::new(BigFactorialFunction));
804
805        // Bit manipulation
806        self.register(Box::new(BitAndFunction));
807        self.register(Box::new(BitOrFunction));
808        self.register(Box::new(BitXorFunction));
809        self.register(Box::new(BitShiftFunction));
810
811        // Base conversions
812        self.register(Box::new(ToBinaryFunction));
813        self.register(Box::new(FromBinaryFunction));
814        self.register(Box::new(ToHexFunction));
815        self.register(Box::new(FromHexFunction));
816    }
817
818    /// Register bitwise functions (additional bit operations not in bigint)
819    fn register_bitwise_functions(&mut self) {
820        bitwise::register_bitwise_functions(self);
821
822        // Register string-based bitwise operations
823        self.register(Box::new(bitwise_string::BitAndStr));
824        self.register(Box::new(bitwise_string::BitOrStr));
825        self.register(Box::new(bitwise_string::BitXorStr));
826        self.register(Box::new(bitwise_string::BitNotStr));
827        self.register(Box::new(bitwise_string::BitFlip));
828        self.register(Box::new(bitwise_string::BitCount));
829        self.register(Box::new(bitwise_string::BitRotateLeft));
830        self.register(Box::new(bitwise_string::BitRotateRight));
831        self.register(Box::new(bitwise_string::BitShiftLeft));
832        self.register(Box::new(bitwise_string::BitShiftRight));
833        self.register(Box::new(bitwise_string::HammingDistance));
834    }
835}
836
837impl Default for FunctionRegistry {
838    fn default() -> Self {
839        Self::new()
840    }
841}
842
843#[cfg(test)]
844mod tests {
845    use super::*;
846
847    #[test]
848    fn test_registry_creation() {
849        let registry = FunctionRegistry::new();
850
851        // Check that some known functions exist
852        assert!(registry.contains("PI"));
853        assert!(registry.contains("MASS_EARTH"));
854        assert!(registry.contains("ME"));
855    }
856
857    #[test]
858    fn test_case_insensitive_lookup() {
859        let registry = FunctionRegistry::new();
860
861        assert!(registry.get("pi").is_some());
862        assert!(registry.get("PI").is_some());
863        assert!(registry.get("Pi").is_some());
864    }
865
866    #[test]
867    fn test_autocomplete() {
868        let registry = FunctionRegistry::new();
869
870        let mass_functions = registry.autocomplete("MASS");
871        assert!(!mass_functions.is_empty());
872
873        // Should include MASS_EARTH, MASS_SUN, etc.
874        let names: Vec<&str> = mass_functions.iter().map(|sig| sig.name).collect();
875        assert!(names.contains(&"MASS_EARTH"));
876        assert!(names.contains(&"MASS_SUN"));
877    }
878}