sql_fun_sqlast/sem/data_source/
rows_fun.rs1use sql_fun_core::IVec;
2
3use crate::{
4 sem::{
5 AliasSpec, AnalysisError, AnalysisProblem, ColumnCollection, DataSource, FromClause,
6 FullName, Nullable, ParseContext, SemScalarExpr, WithClause, analyze_scaler_expr,
7 data_source::AliasName, type_system::ArgumentBindingCollection,
8 },
9 syn::{ListOpt, Opt, ScanToken},
10};
11
12#[derive(Debug, Clone, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize)]
14pub struct DataSourceRowFunctions {
15 alias: AliasSpec,
16 functions: IVec<DataSourceRowsFromFunc>,
17}
18
19impl DataSourceRowFunctions {
20 pub(super) fn resolve_alias<'a>(
21 &self,
22 data_source: &'a DataSource,
23 name: &AliasName,
24 ) -> Option<(&'a DataSource, Nullable)> {
25 if self.alias.name() == name {
26 Some((data_source, false))
27 } else {
28 None
29 }
30 }
31
32 pub(super) fn new(functions: &IVec<DataSourceRowsFromFunc>, alias: &AliasSpec) -> Self {
33 Self {
34 functions: functions.clone(),
35 alias: alias.clone(),
36 }
37 }
38
39 #[must_use]
41 pub fn get_aliases(&self) -> Vec<AliasSpec> {
42 vec![self.alias.clone()]
43 }
44}
45
46#[derive(Debug, Clone, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize)]
48pub enum DataSourceRowsFromFunc {
49 FuncCall(FullName, Vec<SemScalarExpr>, ColumnCollection),
51 UndefinedFuncCall(FullName, Vec<SemScalarExpr>),
53}
54
55impl DataSourceRowsFromFunc {
56 pub fn analyze_func_call<TParseContext>(
58 mut context: TParseContext,
59 with_clause: &WithClause,
60 from_clause: &FromClause,
61 func_call: crate::syn::FuncCall,
62 tokens: &IVec<ScanToken>,
63 ) -> Result<(Self, TParseContext), AnalysisError>
64 where
65 TParseContext: ParseContext,
66 {
67 let fun_name = FullName::try_from(func_call.get_funcname())?;
68 let Some(args) = func_call.get_args().as_inner() else {
69 AnalysisError::raise_unexpected_none("func_call.args")?
70 };
71 let mut arg_exprs = Vec::new();
72 let mut arg_types = ArgumentBindingCollection::default();
73 for arg in args {
74 let (arg, new_context) =
75 analyze_scaler_expr(context, with_clause, from_clause, arg, tokens)?;
76 context = new_context;
77 arg_types.push(arg.get_type());
78 arg_exprs.push(arg);
79 }
80
81 if let Some(overloads) = context.get_function_by_name(&fun_name) {
82 let Some(overload) = overloads.resolve_overload(&mut context, &arg_types) else {
83 context.report_problem(AnalysisProblem::function_overload_resolution_failed(
84 &fun_name, &arg_types,
85 ))?;
86 return Ok((Self::UndefinedFuncCall(fun_name, arg_exprs), context));
87 };
88 let columns = overload.returning_table();
89 let resolved_fun_name = context.resolve_function_name_with_search_path(&fun_name);
90 Ok((
91 Self::FuncCall(resolved_fun_name, arg_exprs, columns),
92 context,
93 ))
94 } else {
95 context.report_problem(AnalysisProblem::table_function_not_found(&fun_name))?;
96 Ok((Self::UndefinedFuncCall(fun_name, arg_exprs), context))
97 }
98 }
99
100 pub fn analyze_node<TParseContext>(
102 context: TParseContext,
103 with_clause: &WithClause,
104 from_clause: &FromClause,
105 function: crate::syn::Node,
106 tokens: &IVec<ScanToken>,
107 ) -> Result<(Self, TParseContext), AnalysisError>
108 where
109 TParseContext: ParseContext,
110 {
111 if let Some(func_call) = function.as_func_call().as_inner() {
112 Self::analyze_func_call(context, with_clause, from_clause, func_call, tokens)
113 } else if let Some(_sqlvf) = function.as_sqlvalue_function().as_inner() {
114 todo!()
115 } else {
116 AnalysisError::raise_unexpected_input(
117 "RangeFunction.functions contains unexpected node",
118 )
119 }
120 }
121}