uqa_sql/routines/lifecycle/
lookup.rs1use super::RoutineRegistry;
10use crate::{
11 ast::FunctionBinding,
12 routines::{routine_signature_types, SQLUserFunction},
13};
14use std::{collections::BTreeSet, sync::Arc};
15
16pub fn lookup_sql_functions_by_keys(
17 registry: &RoutineRegistry,
18 keys: impl IntoIterator<Item = String>,
19) -> Option<Vec<Arc<SQLUserFunction>>> {
20 let mut visible = Vec::new();
21 let mut seen = BTreeSet::new();
22 for key in keys {
23 let Some(overloads) = registry.get(&key) else {
24 continue;
25 };
26 for function in overloads {
27 let identity = (
28 routine_signature_types(&function.def),
29 function.def.is_procedure,
30 );
31 if seen.insert(identity) {
32 visible.push(function.clone());
33 }
34 }
35 }
36 (!visible.is_empty()).then_some(visible)
37}
38
39pub fn lookup_bound_sql_functions_by_binding(
40 registry: &RoutineRegistry,
41 binding: &FunctionBinding,
42) -> Option<Vec<Arc<SQLUserFunction>>> {
43 let Some(object_id) = binding.object_id else {
44 return lookup_sql_functions_by_keys(registry, std::iter::once(binding.name.clone()));
45 };
46 let matches = registry
47 .values()
48 .flat_map(|overloads| overloads.iter())
49 .filter(|function| function.def.object_id == Some(object_id))
50 .cloned()
51 .collect::<Vec<_>>();
52 (!matches.is_empty()).then_some(matches)
53}
54
55pub fn lookup_sql_routine_candidates_by_keys(
57 registry: &RoutineRegistry,
58 keys: impl IntoIterator<Item = String>,
59) -> Option<Vec<Arc<SQLUserFunction>>> {
60 let candidates = keys
61 .into_iter()
62 .filter_map(|key| registry.get(&key))
63 .flat_map(|overloads| overloads.iter().cloned())
64 .collect::<Vec<_>>();
65 (!candidates.is_empty()).then_some(candidates)
66}
67
68pub fn lookup_bound_sql_routine_candidates_by_binding(
69 registry: &RoutineRegistry,
70 binding: &FunctionBinding,
71) -> Option<Vec<Arc<SQLUserFunction>>> {
72 if binding.object_id.is_some() {
73 lookup_bound_sql_functions_by_binding(registry, binding)
74 } else {
75 lookup_sql_routine_candidates_by_keys(registry, std::iter::once(binding.name.clone()))
76 }
77}