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