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