uqa_sql/semantics/sets/
static_setness.rs1use super::validation::builtin_returns_set;
9use crate::ast::FunctionBinding;
10
11pub fn function_may_return_set_statically(
12 catalog: &dyn crate::routines::RoutineResolution,
13 name: &str,
14 binding: Option<&FunctionBinding>,
15) -> bool {
16 if binding.and_then(|binding| binding.dispatch).is_some()
17 || binding.is_some_and(FunctionBinding::is_polymorphic_builtin_syntax)
18 {
19 return false;
20 }
21 let identity = name.to_ascii_lowercase();
22 let builtin = crate::semantics::builtin_function_dispatch_name(&identity);
23 if builtin_returns_set(&builtin) || catalog.has_registered_table_function(&identity) {
24 return true;
25 }
26 if binding.is_some_and(|binding| binding.builtin) {
27 return false;
28 }
29 let overloads = match binding {
30 Some(binding) => catalog.lookup_bound_sql_functions_by_binding(binding),
31 None => catalog
32 .lookup_visible_sql_functions_for_analysis(name)
33 .ok()
34 .flatten(),
35 };
36 let Some(overloads) = overloads else {
37 return false;
38 };
39 if let Some(binding) = binding {
40 return overloads.iter().any(|function| {
41 !function.def.is_procedure
42 && crate::routines::routine_signature_types(&function.def) == binding.argument_types
43 && function.def.returns_set()
44 });
45 }
46 overloads
47 .iter()
48 .any(|function| !function.def.is_procedure && function.def.returns_set())
49}