1use std::collections::HashMap;
17use std::collections::hash_map::Entry;
18use std::sync::{Arc, LazyLock, RwLock};
19
20use datafusion::catalog::TableFunction;
21use datafusion_expr::expr_rewriter::FunctionRewrite;
22use datafusion_expr::{AggregateUDF, WindowUDF};
23
24use crate::admin::AdminFunction;
25use crate::aggrs::aggr_wrapper::StateMergeHelper;
26use crate::aggrs::approximate::ApproximateFunction;
27use crate::aggrs::count_hash::CountHash;
28use crate::aggrs::extremum::Extremum;
29use crate::aggrs::vector::VectorFunction as VectorAggrFunction;
30use crate::function::{Function, FunctionRef};
31use crate::function_factory::ScalarFunctionFactory;
32#[cfg(feature = "ai_functions")]
33use crate::scalars::ai;
34use crate::scalars::anomaly::AnomalyFunction;
35use crate::scalars::avg_calc::AvgCalcFunction;
36use crate::scalars::date::DateFunction;
37use crate::scalars::expression::ExpressionFunction;
38use crate::scalars::hll_count::HllCalcFunction;
39use crate::scalars::ip::IpFunctions;
40use crate::scalars::json::JsonFunction;
41use crate::scalars::matches::MatchesFunction;
42use crate::scalars::matches_term::MatchesTermFunction;
43use crate::scalars::math::MathFunction;
44use crate::scalars::primary_key::DecodePrimaryKeyFunction;
45use crate::scalars::string::register_string_functions;
46use crate::scalars::timestamp::TimestampFunction;
47use crate::scalars::uddsketch_calc::UddSketchCalcFunction;
48use crate::scalars::uddsketch_rank::UddSketchRankFunction;
49use crate::scalars::vector::VectorFunction as VectorScalarFunction;
50use crate::scalars::welford_stddev::WelfordStddevFunction;
51use crate::system::SystemFunction;
52
53#[derive(Default)]
54pub struct FunctionRegistry {
55 functions: RwLock<HashMap<String, ScalarFunctionFactory>>,
56 aggregate_functions: RwLock<HashMap<String, AggregateUDF>>,
57 table_functions: RwLock<HashMap<String, Arc<TableFunction>>>,
58 function_rewrites: RwLock<Vec<Arc<dyn FunctionRewrite + Send + Sync>>>,
59 window_functions: RwLock<HashMap<String, WindowUDF>>,
60}
61
62#[derive(Debug, Clone, Copy, PartialEq, Eq)]
64pub enum FunctionRegistrationResult {
65 Registered,
67 AlreadyExists,
69}
70
71impl FunctionRegistry {
72 pub fn register(&self, func: impl Into<ScalarFunctionFactory>) {
81 let func = func.into();
82 let _ = self
83 .functions
84 .write()
85 .unwrap()
86 .insert(func.name().to_string(), func);
87 }
88
89 pub fn register_if_absent(
98 &self,
99 func: impl Into<ScalarFunctionFactory>,
100 ) -> FunctionRegistrationResult {
101 let func = func.into();
102 let mut functions = self.functions.write().unwrap();
103 match functions.entry(func.name().to_string()) {
104 Entry::Occupied(_) => FunctionRegistrationResult::AlreadyExists,
105 Entry::Vacant(entry) => {
106 entry.insert(func);
107 FunctionRegistrationResult::Registered
108 }
109 }
110 }
111
112 pub fn register_scalar(&self, func: impl Function + 'static) {
114 let func = Arc::new(func) as FunctionRef;
115
116 for alias in func.aliases() {
117 let func: ScalarFunctionFactory = func.clone().into();
118 let alias = ScalarFunctionFactory {
119 name: alias.clone(),
120 ..func
121 };
122 self.register(alias);
123 }
124
125 self.register(func)
126 }
127
128 pub fn register_aggr(&self, func: AggregateUDF) {
130 let _ = self
131 .aggregate_functions
132 .write()
133 .unwrap()
134 .insert(func.name().to_string(), func);
135 }
136
137 pub fn register_table_function(&self, func: TableFunction) {
139 let _ = self
140 .table_functions
141 .write()
142 .unwrap()
143 .insert(func.name().to_string(), Arc::new(func));
144 }
145
146 pub fn register_function_rewrite(&self, func: impl FunctionRewrite + Send + Sync + 'static) {
148 self.function_rewrites.write().unwrap().push(Arc::new(func));
149 }
150
151 pub fn register_window(&self, func: WindowUDF) {
153 let _ = self
154 .window_functions
155 .write()
156 .unwrap()
157 .insert(func.name().to_string(), func);
158 }
159
160 pub fn get_function(&self, name: &str) -> Option<ScalarFunctionFactory> {
161 self.functions.read().unwrap().get(name).cloned()
162 }
163
164 pub fn scalar_functions(&self) -> Vec<ScalarFunctionFactory> {
166 self.functions.read().unwrap().values().cloned().collect()
167 }
168
169 pub fn aggregate_functions(&self) -> Vec<AggregateUDF> {
171 self.aggregate_functions
172 .read()
173 .unwrap()
174 .values()
175 .cloned()
176 .collect()
177 }
178
179 pub fn table_functions(&self) -> Vec<Arc<TableFunction>> {
180 self.table_functions
181 .read()
182 .unwrap()
183 .values()
184 .cloned()
185 .collect()
186 }
187
188 pub fn window_functions(&self) -> Vec<WindowUDF> {
190 self.window_functions
191 .read()
192 .unwrap()
193 .values()
194 .cloned()
195 .collect()
196 }
197
198 pub fn get_aggr_func(&self, name: &str) -> Option<AggregateUDF> {
200 self.aggregate_functions.read().unwrap().get(name).cloned()
201 }
202
203 pub fn is_aggr_func_exist(&self, name: &str) -> bool {
205 self.aggregate_functions.read().unwrap().contains_key(name)
206 }
207
208 pub fn function_rewrites(&self) -> Vec<Arc<dyn FunctionRewrite + Send + Sync>> {
210 self.function_rewrites.read().unwrap().clone()
211 }
212}
213
214pub static FUNCTION_REGISTRY: LazyLock<Arc<FunctionRegistry>> = LazyLock::new(|| {
215 let function_registry = FunctionRegistry::default();
216
217 MathFunction::register(&function_registry);
219 TimestampFunction::register(&function_registry);
220 DateFunction::register(&function_registry);
221 ExpressionFunction::register(&function_registry);
222 AvgCalcFunction::register(&function_registry);
223 UddSketchCalcFunction::register(&function_registry);
224 UddSketchRankFunction::register(&function_registry);
225 HllCalcFunction::register(&function_registry);
226 WelfordStddevFunction::register(&function_registry);
227 DecodePrimaryKeyFunction::register(&function_registry);
228
229 MatchesFunction::register(&function_registry);
231 MatchesTermFunction::register(&function_registry);
232 #[cfg(feature = "ai_functions")]
233 ai::register(&function_registry);
234
235 SystemFunction::register(&function_registry);
237 AdminFunction::register(&function_registry);
238
239 JsonFunction::register(&function_registry);
241
242 register_string_functions(&function_registry);
244
245 VectorScalarFunction::register(&function_registry);
247 VectorAggrFunction::register(&function_registry);
248
249 #[cfg(feature = "geo")]
251 crate::scalars::geo::GeoFunctions::register(&function_registry);
252 #[cfg(feature = "geo")]
253 crate::aggrs::geo::GeoFunction::register(&function_registry);
254
255 IpFunctions::register(&function_registry);
257
258 ApproximateFunction::register(&function_registry);
260
261 CountHash::register(&function_registry);
263
264 Extremum::register(&function_registry);
266
267 StateMergeHelper::register(&function_registry);
269
270 AnomalyFunction::register(&function_registry);
272
273 Arc::new(function_registry)
274});
275
276static ADMIN_FUNCTION_REGISTRY: LazyLock<FunctionRegistry> = LazyLock::new(|| {
277 let registry = FunctionRegistry::default();
278 AdminFunction::register_admin_only(®istry);
279 registry
280});
281
282pub fn get_admin_function(name: &str) -> Option<ScalarFunctionFactory> {
284 ADMIN_FUNCTION_REGISTRY.get_function(name)
285}
286
287pub fn register_admin_function(
304 func: impl Into<ScalarFunctionFactory>,
305) -> FunctionRegistrationResult {
306 register_admin_function_in(&ADMIN_FUNCTION_REGISTRY, &FUNCTION_REGISTRY, func)
307}
308
309fn register_admin_function_in(
326 admin_registry: &FunctionRegistry,
327 normal_registry: &FunctionRegistry,
328 func: impl Into<ScalarFunctionFactory>,
329) -> FunctionRegistrationResult {
330 let func = func.into();
331 let mut admin_functions = admin_registry.functions.write().unwrap();
332 let normal_functions = normal_registry.functions.read().unwrap();
338 if normal_functions.contains_key(func.name()) {
339 drop(normal_functions);
340 return FunctionRegistrationResult::AlreadyExists;
341 }
342 let result = match admin_functions.entry(func.name().to_string()) {
343 Entry::Occupied(_) => FunctionRegistrationResult::AlreadyExists,
344 Entry::Vacant(entry) => {
345 entry.insert(func);
346 FunctionRegistrationResult::Registered
347 }
348 };
349 drop(normal_functions);
352 result
353}
354
355#[cfg(test)]
356mod tests {
357 use std::sync::{Arc, Barrier};
358 use std::thread;
359
360 use super::*;
361 use crate::scalars::test::TestAndFunction;
362 use crate::scalars::udf::create_udf;
363
364 fn named_factory(name: &str) -> ScalarFunctionFactory {
368 ScalarFunctionFactory {
369 name: name.to_string(),
370 factory: Arc::new(|_ctx| create_udf(Arc::new(TestAndFunction::default()))),
371 }
372 }
373
374 #[test]
375 fn test_function_registry() {
376 let registry = FunctionRegistry::default();
377
378 assert!(registry.get_function("test_and").is_none());
379 assert!(registry.scalar_functions().is_empty());
380 registry.register_scalar(TestAndFunction::default());
381 let _ = registry.get_function("test_and").unwrap();
382 assert_eq!(1, registry.scalar_functions().len());
383 }
384
385 #[test]
386 fn test_uddsketch_rank_registered() {
387 assert!(FUNCTION_REGISTRY.get_function("uddsketch_rank").is_some());
388 }
389
390 #[test]
391 fn test_ai_registration_matches_feature() {
392 for name in ["ai_match", "ai_choose", "ai_score"] {
393 assert_eq!(
394 FUNCTION_REGISTRY.get_function(name).is_some(),
395 cfg!(feature = "ai_functions"),
396 "{name}"
397 );
398 }
399 for name in ["jev", "jev_choice", "jev_score"] {
400 assert!(FUNCTION_REGISTRY.get_function(name).is_none(), "{name}");
401 }
402 }
403
404 #[test]
405 fn test_register_if_absent_registers_new_function() {
406 let registry = FunctionRegistry::default();
407 let name = "pr3_register_if_absent_new";
408 let factory = named_factory(name);
409
410 assert_eq!(
411 registry.register_if_absent(factory.clone()),
412 FunctionRegistrationResult::Registered
413 );
414 let registered = registry
415 .get_function(name)
416 .expect("function should be registered");
417 assert!(Arc::ptr_eq(®istered.factory, &factory.factory));
418 }
419
420 #[test]
421 fn test_register_if_absent_first_registration_wins() {
422 let registry = FunctionRegistry::default();
423 let name = "pr3_register_if_absent_duplicate";
424 let first = named_factory(name);
425 let second = named_factory(name);
426
427 assert_eq!(
428 registry.register_if_absent(first.clone()),
429 FunctionRegistrationResult::Registered
430 );
431 assert_eq!(
432 registry.register_if_absent(second.clone()),
433 FunctionRegistrationResult::AlreadyExists
434 );
435
436 let stored = registry
437 .get_function(name)
438 .expect("function should be registered");
439 assert!(Arc::ptr_eq(&stored.factory, &first.factory));
440 assert!(!Arc::ptr_eq(&stored.factory, &second.factory));
441 }
442
443 #[test]
444 fn test_register_replaces_existing_function() {
445 let registry = FunctionRegistry::default();
447 let name = "pr3_register_replaces";
448 let first = named_factory(name);
449 let second = named_factory(name);
450
451 registry.register(first.clone());
452 registry.register(second.clone());
453
454 let stored = registry
455 .get_function(name)
456 .expect("function should be registered");
457 assert!(Arc::ptr_eq(&stored.factory, &second.factory));
458 assert!(!Arc::ptr_eq(&stored.factory, &first.factory));
459 }
460
461 #[test]
462 fn test_concurrent_register_if_absent_same_name() {
463 const THREADS: usize = 8;
464 let registry = Arc::new(FunctionRegistry::default());
465 let name = "pr3_concurrent_same_name";
466 let barrier = Arc::new(Barrier::new(THREADS));
467
468 let handles: Vec<_> = (0..THREADS)
469 .map(|_| {
470 let registry = Arc::clone(®istry);
471 let barrier = Arc::clone(&barrier);
472 thread::spawn(move || {
473 let factory = named_factory(name);
474 barrier.wait();
477 let result = registry.register_if_absent(factory.clone());
478 (result, factory)
479 })
480 })
481 .collect();
482
483 let mut results: Vec<(FunctionRegistrationResult, ScalarFunctionFactory)> =
484 Vec::with_capacity(THREADS);
485 for handle in handles {
486 results.push(handle.join().expect("thread should not panic"));
487 }
488
489 let registered = results
490 .iter()
491 .filter(|(result, _)| *result == FunctionRegistrationResult::Registered)
492 .count();
493 let already_exists = results
494 .iter()
495 .filter(|(result, _)| *result == FunctionRegistrationResult::AlreadyExists)
496 .count();
497 assert_eq!(registered, 1);
498 assert_eq!(already_exists, THREADS - 1);
499
500 let winner = results
501 .iter()
502 .find(|(result, _)| *result == FunctionRegistrationResult::Registered)
503 .map(|(_, factory)| factory)
504 .expect("exactly one registration must win");
505
506 let stored = registry
507 .get_function(name)
508 .expect("function should be registered");
509 assert!(
510 Arc::ptr_eq(&stored.factory, &winner.factory),
511 "the stored factory must be the factory of the winning registration"
512 );
513 }
514
515 #[test]
516 fn test_register_admin_function_first_wins() {
517 let name = "pr3_admin_runtime_register";
519 let first = named_factory(name);
520 let second = named_factory(name);
521
522 assert_eq!(
523 register_admin_function(first.clone()),
524 FunctionRegistrationResult::Registered
525 );
526 assert_eq!(
527 register_admin_function(second.clone()),
528 FunctionRegistrationResult::AlreadyExists
529 );
530
531 let stored = get_admin_function(name).expect("admin function should be queryable");
532 assert!(Arc::ptr_eq(&stored.factory, &first.factory));
533 assert!(!Arc::ptr_eq(&stored.factory, &second.factory));
534 }
535
536 #[test]
537 fn test_register_admin_function_duplicate_same_factory() {
538 let name = "pr3_admin_runtime_register_same_factory";
543 let factory = named_factory(name);
544
545 assert_eq!(
546 register_admin_function(factory.clone()),
547 FunctionRegistrationResult::Registered
548 );
549 assert_eq!(
550 register_admin_function(factory.clone()),
551 FunctionRegistrationResult::AlreadyExists
552 );
553
554 let stored = get_admin_function(name).expect("admin function should be queryable");
555 assert!(Arc::ptr_eq(&stored.factory, &factory.factory));
556 }
557
558 #[test]
559 fn test_register_admin_function_in_is_one_way_later_normal_register_allowed() {
560 let admin = FunctionRegistry::default();
565 let normal = FunctionRegistry::default();
566 let name = "pr3_admin_in_one_way";
567 let admin_factory = named_factory(name);
568 let normal_factory = named_factory(name);
569
570 assert_eq!(
571 register_admin_function_in(&admin, &normal, admin_factory.clone()),
572 FunctionRegistrationResult::Registered
573 );
574
575 normal.register(normal_factory.clone());
576
577 let stored_admin = admin
578 .get_function(name)
579 .expect("the ADMIN registration must be kept");
580 assert!(Arc::ptr_eq(&stored_admin.factory, &admin_factory.factory));
581 let stored_normal = normal
582 .get_function(name)
583 .expect("the later normal registration must succeed");
584 assert!(Arc::ptr_eq(&stored_normal.factory, &normal_factory.factory));
585 }
586
587 #[test]
588 fn test_register_admin_function_rejects_normal_registry_builtin_name() {
589 let factory = named_factory("flush_table");
597
598 assert_eq!(
599 register_admin_function(factory.clone()),
600 FunctionRegistrationResult::AlreadyExists
601 );
602 assert!(
603 get_admin_function("flush_table").is_none(),
604 "a normal-registry built-in must not be shadowed into the ADMIN registry"
605 );
606 assert!(
607 FUNCTION_REGISTRY.get_function("flush_table").is_some(),
608 "the normal-registry built-in must remain registered"
609 );
610 }
611
612 #[test]
613 fn test_builtin_admin_functions_remain_queryable() {
614 #[cfg(feature = "enterprise")]
617 {
618 assert!(get_admin_function("purge_table").is_some());
619 }
620 #[cfg(not(feature = "enterprise"))]
621 {
622 assert!(get_admin_function("purge_table").is_none());
623 }
624 }
625}