common_function/
function_registry.rs1use 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::vector::VectorFunction as VectorAggrFunction;
29use crate::function::{Function, FunctionRef};
30use crate::function_factory::ScalarFunctionFactory;
31use crate::scalars::anomaly::AnomalyFunction;
32use crate::scalars::date::DateFunction;
33use crate::scalars::expression::ExpressionFunction;
34use crate::scalars::hll_count::HllCalcFunction;
35use crate::scalars::ip::IpFunctions;
36use crate::scalars::json::JsonFunction;
37use crate::scalars::matches::MatchesFunction;
38use crate::scalars::matches_term::MatchesTermFunction;
39use crate::scalars::math::MathFunction;
40use crate::scalars::primary_key::DecodePrimaryKeyFunction;
41use crate::scalars::string::register_string_functions;
42use crate::scalars::timestamp::TimestampFunction;
43use crate::scalars::uddsketch_calc::UddSketchCalcFunction;
44use crate::scalars::uddsketch_rank::UddSketchRankFunction;
45use crate::scalars::vector::VectorFunction as VectorScalarFunction;
46use crate::scalars::welford_stddev::WelfordStddevFunction;
47use crate::system::SystemFunction;
48
49#[derive(Default)]
50pub struct FunctionRegistry {
51 functions: RwLock<HashMap<String, ScalarFunctionFactory>>,
52 aggregate_functions: RwLock<HashMap<String, AggregateUDF>>,
53 table_functions: RwLock<HashMap<String, Arc<TableFunction>>>,
54 function_rewrites: RwLock<Vec<Arc<dyn FunctionRewrite + Send + Sync>>>,
55 window_functions: RwLock<HashMap<String, WindowUDF>>,
56}
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq)]
60pub enum FunctionRegistrationResult {
61 Registered,
63 AlreadyExists,
65}
66
67impl FunctionRegistry {
68 pub fn register(&self, func: impl Into<ScalarFunctionFactory>) {
77 let func = func.into();
78 let _ = self
79 .functions
80 .write()
81 .unwrap()
82 .insert(func.name().to_string(), func);
83 }
84
85 pub fn register_if_absent(
94 &self,
95 func: impl Into<ScalarFunctionFactory>,
96 ) -> FunctionRegistrationResult {
97 let func = func.into();
98 let mut functions = self.functions.write().unwrap();
99 match functions.entry(func.name().to_string()) {
100 Entry::Occupied(_) => FunctionRegistrationResult::AlreadyExists,
101 Entry::Vacant(entry) => {
102 entry.insert(func);
103 FunctionRegistrationResult::Registered
104 }
105 }
106 }
107
108 pub fn register_scalar(&self, func: impl Function + 'static) {
110 let func = Arc::new(func) as FunctionRef;
111
112 for alias in func.aliases() {
113 let func: ScalarFunctionFactory = func.clone().into();
114 let alias = ScalarFunctionFactory {
115 name: alias.clone(),
116 ..func
117 };
118 self.register(alias);
119 }
120
121 self.register(func)
122 }
123
124 pub fn register_aggr(&self, func: AggregateUDF) {
126 let _ = self
127 .aggregate_functions
128 .write()
129 .unwrap()
130 .insert(func.name().to_string(), func);
131 }
132
133 pub fn register_table_function(&self, func: TableFunction) {
135 let _ = self
136 .table_functions
137 .write()
138 .unwrap()
139 .insert(func.name().to_string(), Arc::new(func));
140 }
141
142 pub fn register_function_rewrite(&self, func: impl FunctionRewrite + Send + Sync + 'static) {
144 self.function_rewrites.write().unwrap().push(Arc::new(func));
145 }
146
147 pub fn register_window(&self, func: WindowUDF) {
149 let _ = self
150 .window_functions
151 .write()
152 .unwrap()
153 .insert(func.name().to_string(), func);
154 }
155
156 pub fn get_function(&self, name: &str) -> Option<ScalarFunctionFactory> {
157 self.functions.read().unwrap().get(name).cloned()
158 }
159
160 pub fn scalar_functions(&self) -> Vec<ScalarFunctionFactory> {
162 self.functions.read().unwrap().values().cloned().collect()
163 }
164
165 pub fn aggregate_functions(&self) -> Vec<AggregateUDF> {
167 self.aggregate_functions
168 .read()
169 .unwrap()
170 .values()
171 .cloned()
172 .collect()
173 }
174
175 pub fn table_functions(&self) -> Vec<Arc<TableFunction>> {
176 self.table_functions
177 .read()
178 .unwrap()
179 .values()
180 .cloned()
181 .collect()
182 }
183
184 pub fn window_functions(&self) -> Vec<WindowUDF> {
186 self.window_functions
187 .read()
188 .unwrap()
189 .values()
190 .cloned()
191 .collect()
192 }
193
194 pub fn get_aggr_func(&self, name: &str) -> Option<AggregateUDF> {
196 self.aggregate_functions.read().unwrap().get(name).cloned()
197 }
198
199 pub fn is_aggr_func_exist(&self, name: &str) -> bool {
201 self.aggregate_functions.read().unwrap().contains_key(name)
202 }
203
204 pub fn function_rewrites(&self) -> Vec<Arc<dyn FunctionRewrite + Send + Sync>> {
206 self.function_rewrites.read().unwrap().clone()
207 }
208}
209
210pub static FUNCTION_REGISTRY: LazyLock<Arc<FunctionRegistry>> = LazyLock::new(|| {
211 let function_registry = FunctionRegistry::default();
212
213 MathFunction::register(&function_registry);
215 TimestampFunction::register(&function_registry);
216 DateFunction::register(&function_registry);
217 ExpressionFunction::register(&function_registry);
218 UddSketchCalcFunction::register(&function_registry);
219 UddSketchRankFunction::register(&function_registry);
220 HllCalcFunction::register(&function_registry);
221 WelfordStddevFunction::register(&function_registry);
222 DecodePrimaryKeyFunction::register(&function_registry);
223
224 MatchesFunction::register(&function_registry);
226 MatchesTermFunction::register(&function_registry);
227
228 SystemFunction::register(&function_registry);
230 AdminFunction::register(&function_registry);
231
232 JsonFunction::register(&function_registry);
234
235 register_string_functions(&function_registry);
237
238 VectorScalarFunction::register(&function_registry);
240 VectorAggrFunction::register(&function_registry);
241
242 #[cfg(feature = "geo")]
244 crate::scalars::geo::GeoFunctions::register(&function_registry);
245 #[cfg(feature = "geo")]
246 crate::aggrs::geo::GeoFunction::register(&function_registry);
247
248 IpFunctions::register(&function_registry);
250
251 ApproximateFunction::register(&function_registry);
253
254 CountHash::register(&function_registry);
256
257 StateMergeHelper::register(&function_registry);
259
260 AnomalyFunction::register(&function_registry);
262
263 Arc::new(function_registry)
264});
265
266static ADMIN_FUNCTION_REGISTRY: LazyLock<FunctionRegistry> = LazyLock::new(|| {
267 let registry = FunctionRegistry::default();
268 AdminFunction::register_admin_only(®istry);
269 registry
270});
271
272pub fn get_admin_function(name: &str) -> Option<ScalarFunctionFactory> {
274 ADMIN_FUNCTION_REGISTRY.get_function(name)
275}
276
277pub fn register_admin_function(
294 func: impl Into<ScalarFunctionFactory>,
295) -> FunctionRegistrationResult {
296 register_admin_function_in(&ADMIN_FUNCTION_REGISTRY, &FUNCTION_REGISTRY, func)
297}
298
299fn register_admin_function_in(
316 admin_registry: &FunctionRegistry,
317 normal_registry: &FunctionRegistry,
318 func: impl Into<ScalarFunctionFactory>,
319) -> FunctionRegistrationResult {
320 let func = func.into();
321 let mut admin_functions = admin_registry.functions.write().unwrap();
322 let normal_functions = normal_registry.functions.read().unwrap();
328 if normal_functions.contains_key(func.name()) {
329 drop(normal_functions);
330 return FunctionRegistrationResult::AlreadyExists;
331 }
332 let result = match admin_functions.entry(func.name().to_string()) {
333 Entry::Occupied(_) => FunctionRegistrationResult::AlreadyExists,
334 Entry::Vacant(entry) => {
335 entry.insert(func);
336 FunctionRegistrationResult::Registered
337 }
338 };
339 drop(normal_functions);
342 result
343}
344
345#[cfg(test)]
346mod tests {
347 use std::sync::{Arc, Barrier};
348 use std::thread;
349
350 use super::*;
351 use crate::scalars::test::TestAndFunction;
352 use crate::scalars::udf::create_udf;
353
354 fn named_factory(name: &str) -> ScalarFunctionFactory {
358 ScalarFunctionFactory {
359 name: name.to_string(),
360 factory: Arc::new(|_ctx| create_udf(Arc::new(TestAndFunction::default()))),
361 }
362 }
363
364 #[test]
365 fn test_function_registry() {
366 let registry = FunctionRegistry::default();
367
368 assert!(registry.get_function("test_and").is_none());
369 assert!(registry.scalar_functions().is_empty());
370 registry.register_scalar(TestAndFunction::default());
371 let _ = registry.get_function("test_and").unwrap();
372 assert_eq!(1, registry.scalar_functions().len());
373 }
374
375 #[test]
376 fn test_uddsketch_rank_registered() {
377 assert!(FUNCTION_REGISTRY.get_function("uddsketch_rank").is_some());
378 }
379
380 #[test]
381 fn test_register_if_absent_registers_new_function() {
382 let registry = FunctionRegistry::default();
383 let name = "pr3_register_if_absent_new";
384 let factory = named_factory(name);
385
386 assert_eq!(
387 registry.register_if_absent(factory.clone()),
388 FunctionRegistrationResult::Registered
389 );
390 let registered = registry
391 .get_function(name)
392 .expect("function should be registered");
393 assert!(Arc::ptr_eq(®istered.factory, &factory.factory));
394 }
395
396 #[test]
397 fn test_register_if_absent_first_registration_wins() {
398 let registry = FunctionRegistry::default();
399 let name = "pr3_register_if_absent_duplicate";
400 let first = named_factory(name);
401 let second = named_factory(name);
402
403 assert_eq!(
404 registry.register_if_absent(first.clone()),
405 FunctionRegistrationResult::Registered
406 );
407 assert_eq!(
408 registry.register_if_absent(second.clone()),
409 FunctionRegistrationResult::AlreadyExists
410 );
411
412 let stored = registry
413 .get_function(name)
414 .expect("function should be registered");
415 assert!(Arc::ptr_eq(&stored.factory, &first.factory));
416 assert!(!Arc::ptr_eq(&stored.factory, &second.factory));
417 }
418
419 #[test]
420 fn test_register_replaces_existing_function() {
421 let registry = FunctionRegistry::default();
423 let name = "pr3_register_replaces";
424 let first = named_factory(name);
425 let second = named_factory(name);
426
427 registry.register(first.clone());
428 registry.register(second.clone());
429
430 let stored = registry
431 .get_function(name)
432 .expect("function should be registered");
433 assert!(Arc::ptr_eq(&stored.factory, &second.factory));
434 assert!(!Arc::ptr_eq(&stored.factory, &first.factory));
435 }
436
437 #[test]
438 fn test_concurrent_register_if_absent_same_name() {
439 const THREADS: usize = 8;
440 let registry = Arc::new(FunctionRegistry::default());
441 let name = "pr3_concurrent_same_name";
442 let barrier = Arc::new(Barrier::new(THREADS));
443
444 let handles: Vec<_> = (0..THREADS)
445 .map(|_| {
446 let registry = Arc::clone(®istry);
447 let barrier = Arc::clone(&barrier);
448 thread::spawn(move || {
449 let factory = named_factory(name);
450 barrier.wait();
453 let result = registry.register_if_absent(factory.clone());
454 (result, factory)
455 })
456 })
457 .collect();
458
459 let mut results: Vec<(FunctionRegistrationResult, ScalarFunctionFactory)> =
460 Vec::with_capacity(THREADS);
461 for handle in handles {
462 results.push(handle.join().expect("thread should not panic"));
463 }
464
465 let registered = results
466 .iter()
467 .filter(|(result, _)| *result == FunctionRegistrationResult::Registered)
468 .count();
469 let already_exists = results
470 .iter()
471 .filter(|(result, _)| *result == FunctionRegistrationResult::AlreadyExists)
472 .count();
473 assert_eq!(registered, 1);
474 assert_eq!(already_exists, THREADS - 1);
475
476 let winner = results
477 .iter()
478 .find(|(result, _)| *result == FunctionRegistrationResult::Registered)
479 .map(|(_, factory)| factory)
480 .expect("exactly one registration must win");
481
482 let stored = registry
483 .get_function(name)
484 .expect("function should be registered");
485 assert!(
486 Arc::ptr_eq(&stored.factory, &winner.factory),
487 "the stored factory must be the factory of the winning registration"
488 );
489 }
490
491 #[test]
492 fn test_register_admin_function_first_wins() {
493 let name = "pr3_admin_runtime_register";
495 let first = named_factory(name);
496 let second = named_factory(name);
497
498 assert_eq!(
499 register_admin_function(first.clone()),
500 FunctionRegistrationResult::Registered
501 );
502 assert_eq!(
503 register_admin_function(second.clone()),
504 FunctionRegistrationResult::AlreadyExists
505 );
506
507 let stored = get_admin_function(name).expect("admin function should be queryable");
508 assert!(Arc::ptr_eq(&stored.factory, &first.factory));
509 assert!(!Arc::ptr_eq(&stored.factory, &second.factory));
510 }
511
512 #[test]
513 fn test_register_admin_function_duplicate_same_factory() {
514 let name = "pr3_admin_runtime_register_same_factory";
519 let factory = named_factory(name);
520
521 assert_eq!(
522 register_admin_function(factory.clone()),
523 FunctionRegistrationResult::Registered
524 );
525 assert_eq!(
526 register_admin_function(factory.clone()),
527 FunctionRegistrationResult::AlreadyExists
528 );
529
530 let stored = get_admin_function(name).expect("admin function should be queryable");
531 assert!(Arc::ptr_eq(&stored.factory, &factory.factory));
532 }
533
534 #[test]
535 fn test_register_admin_function_in_is_one_way_later_normal_register_allowed() {
536 let admin = FunctionRegistry::default();
541 let normal = FunctionRegistry::default();
542 let name = "pr3_admin_in_one_way";
543 let admin_factory = named_factory(name);
544 let normal_factory = named_factory(name);
545
546 assert_eq!(
547 register_admin_function_in(&admin, &normal, admin_factory.clone()),
548 FunctionRegistrationResult::Registered
549 );
550
551 normal.register(normal_factory.clone());
552
553 let stored_admin = admin
554 .get_function(name)
555 .expect("the ADMIN registration must be kept");
556 assert!(Arc::ptr_eq(&stored_admin.factory, &admin_factory.factory));
557 let stored_normal = normal
558 .get_function(name)
559 .expect("the later normal registration must succeed");
560 assert!(Arc::ptr_eq(&stored_normal.factory, &normal_factory.factory));
561 }
562
563 #[test]
564 fn test_register_admin_function_rejects_normal_registry_builtin_name() {
565 let factory = named_factory("flush_table");
573
574 assert_eq!(
575 register_admin_function(factory.clone()),
576 FunctionRegistrationResult::AlreadyExists
577 );
578 assert!(
579 get_admin_function("flush_table").is_none(),
580 "a normal-registry built-in must not be shadowed into the ADMIN registry"
581 );
582 assert!(
583 FUNCTION_REGISTRY.get_function("flush_table").is_some(),
584 "the normal-registry built-in must remain registered"
585 );
586 }
587
588 #[test]
589 fn test_builtin_admin_functions_remain_queryable() {
590 #[cfg(feature = "enterprise")]
593 {
594 assert!(get_admin_function("purge_table").is_some());
595 }
596 #[cfg(not(feature = "enterprise"))]
597 {
598 assert!(get_admin_function("purge_table").is_none());
599 }
600 }
601}