1mod alias;
2mod analyze;
3mod cte;
4mod join_expr;
5mod join_kind;
6mod rows_fun;
7mod sub_query;
8mod table;
9mod table_fun;
10mod undefined;
11mod view;
12
13use sql_fun_core::IVec;
14
15pub use self::{
16 alias::{AliasName, AliasSpec},
17 cte::CteDataSource,
18 join_expr::JoinExprDataSource,
19 join_kind::JoinKind,
20 rows_fun::{DataSourceRowFunctions, DataSourceRowsFromFunc},
21 sub_query::SubQueryDataSource,
22 table::TableDataSource,
23 table_fun::TableFunctionDataSource,
24 undefined::UndefinedTableFuncDataSource,
25 view::ViewDataSource,
26};
27
28use crate::{
29 sem::{
30 AnalysisError, ColumnName, FromClause, FullName, ParseContext, SemScalarExpr, WithClause,
31 analyze_scaler_expr, scalar_expr::ColumnReferenceExpr,
32 type_system::ArgumentBindingCollection,
33 },
34 syn::{ListOpt, ScanToken},
35};
36
37pub type Nullable = bool;
39
40#[derive(Debug, Clone, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize)]
42pub enum DataSource {
43 CteQuery(CteDataSource),
45 Table(TableDataSource),
47 View(ViewDataSource),
49 JoinExpr(Box<JoinExprDataSource>),
51 SubQuery(Box<SubQueryDataSource>),
53 CallTableFunc(TableFunctionDataSource),
55 UndefinedTableFunc(UndefinedTableFuncDataSource),
57 RowFunctions(DataSourceRowFunctions),
59 RangeTableSample(), Unknown(String, AliasSpec),
63}
64
65impl DataSource {
66 pub(super) fn create_column_ref<TParseContext>(
67 &self,
68 mut context: TParseContext,
69 with_clause: &WithClause,
70 alias: &AliasName,
71 column: &ColumnName,
72 nullability: bool,
73 ) -> Result<(SemScalarExpr, TParseContext), AnalysisError>
74 where
75 TParseContext: ParseContext,
76 {
77 match self {
78 Self::CteQuery(cteds) => {
79 let column_ref =
80 cteds.create_column_ref(&mut context, with_clause, column, nullability)?;
81 Ok((SemScalarExpr::ColumnRef(column_ref), context))
82 }
83 Self::Table(tableds) => {
84 let column_ref = tableds.create_column_ref(&mut context, column, nullability)?;
85 Ok((SemScalarExpr::ColumnRef(column_ref), context))
86 }
87 Self::View(viewds) => ColumnReferenceExpr::view_source_ref(
88 context,
89 alias,
90 column,
91 viewds.view_name(),
92 nullability,
93 ),
94 Self::SubQuery(subqds) => {
95 let column_ref = subqds.create_column_ref(&mut context, column, nullability)?;
96 Ok((SemScalarExpr::ColumnRef(column_ref), context))
97 }
98 Self::Unknown(_, _) => {
99 ColumnReferenceExpr::unknown_source_ref(context, alias, column)
101 }
102 Self::JoinExpr(_) => unreachable!(),
104 Self::CallTableFunc(ds) => ColumnReferenceExpr::function_source_ref(
105 context,
106 alias,
107 column,
108 ds.function(),
109 ds.arguments(),
110 nullability,
111 ),
112 Self::UndefinedTableFunc(_ds) => {
113 ColumnReferenceExpr::unknown_function_source_ref(context, alias, column)
114 }
115 Self::RangeTableSample() => todo!(),
116 Self::RowFunctions(_) => todo!(),
117 }
118 }
119
120 #[track_caller]
121 fn unknown(name: &str, alias: &AliasSpec) -> Self {
122 #[cfg(test)]
123 panic!("unknown datasource {name}, alias {alias:?}");
124
125 #[cfg(not(test))]
126 Self::Unknown(name.to_string(), alias.clone())
127 }
128
129 fn push_alias_names(&self, names: &mut Vec<AliasSpec>) {
130 match self {
131 Self::CteQuery(d) => d.push_alias_names(names),
132 Self::Table(d) => d.push_alias_names(names),
133 Self::View(d) => d.push_alias_names(names),
134 Self::JoinExpr(d) => d.push_alias_names(names),
135 Self::SubQuery(d) => d.push_alias_names(names),
136 Self::CallTableFunc(d) => d.push_alias_names(names),
137 Self::UndefinedTableFunc(d) => d.push_alias_names(names),
138 Self::RowFunctions(_data_source_row_functions) => todo!(),
139 Self::RangeTableSample() => todo!(),
140 Self::Unknown(_, _) => todo!(),
141 }
142 }
143
144 #[must_use]
146 pub fn get_aliases(&self) -> Vec<AliasSpec> {
147 let mut results = Vec::new();
148 self.push_alias_names(&mut results);
149 results
150 }
151
152 #[must_use]
154 pub fn resolve_alias(&self, name: &AliasName) -> Option<(&DataSource, Nullable)> {
155 match self {
156 Self::CteQuery(d) => d.resolve_alias(self, name),
157 Self::Table(d) => d.resolve_alias(self, name),
158 Self::View(d) => d.resolve_alias(self, name),
159 Self::JoinExpr(d) => d.resolve_alias(name),
160 Self::SubQuery(d) => d.resolve_alias(self, name),
161 Self::CallTableFunc(d) => d.resolve_alias(self, name),
162 Self::UndefinedTableFunc(d) => d.resolve_alias(self, name),
163 Self::RangeTableSample() => todo!(),
164 Self::Unknown(_, alias) => {
165 if alias.name() == name {
166 Some((self, false))
167 } else {
168 None
169 }
170 }
171 Self::RowFunctions(rf) => rf.resolve_alias(self, name),
172 }
173 }
174
175 pub fn get_aliases_for_column<TParseContext>(
177 &self,
178 column: &ColumnName,
179 context: &TParseContext,
180 with_clause: &WithClause,
181 ) -> Vec<AliasSpec>
182 where
183 TParseContext: ParseContext,
184 {
185 let mut result = Vec::new();
186 match self {
187 Self::CteQuery(d) => d.get_aliases_for_column(column, with_clause, &mut result),
188 Self::Table(d) => d.get_aliases_for_column(column, context, &mut result),
189 Self::View(d) => d.get_aliases_for_column(column, context, &mut result),
190 Self::JoinExpr(d) => {
191 d.get_aliases_for_column(column, context, with_clause, &mut result);
192 }
193 Self::SubQuery(d) => {
194 d.get_aliases_for_column(column, context, with_clause, &mut result);
195 }
196 Self::CallTableFunc(d) => {
197 d.get_aliases_for_column(column, context, with_clause, &mut result);
198 }
199 Self::UndefinedTableFunc(_) => {}
200 Self::RangeTableSample() => todo!(),
201 Self::Unknown(_, _) => todo!(),
202 Self::RowFunctions(_) => todo!(),
203 }
204 result
205 }
206
207 fn call_table_func<TParseContext>(
208 mut context: TParseContext,
209 with_clause: &WithClause,
210 from_clause: &FromClause,
211 call: crate::syn::FuncCall,
212 alias: Option<crate::syn::Alias>,
213 tokens: &IVec<ScanToken>,
214 ) -> Result<(DataSource, TParseContext), AnalysisError>
215 where
216 TParseContext: ParseContext,
217 {
218 let func_name = FullName::try_from(call.get_funcname())?;
219
220 let alias_name = if let Some(alias) = alias {
221 let (alias, new_context) = AliasSpec::analyze(context, &func_name, &alias)?;
222 context = new_context;
223 alias
224 } else {
225 AliasSpec::from_local_name(&func_name.local_name())
226 };
227
228 let mut arg_exprs = Vec::new();
229 let mut arg_types = ArgumentBindingCollection::default();
230 if let Some(args) = call.get_args().as_inner() {
231 for arg in args {
232 let (sarg, new_context) =
233 analyze_scaler_expr(context, with_clause, from_clause, arg, tokens)?;
234 context = new_context;
235 arg_types.push(sarg.get_type());
236 arg_exprs.push(sarg);
237 }
238 }
239
240 let ds = context.resolve_table_function(
241 &call,
242 func_name,
243 &alias_name,
244 arg_exprs.into(),
245 arg_types,
246 )?;
247
248 Ok((ds, context))
249 }
250}