Skip to main content

sql_fun_sqlast/sem/
data_source.rs

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
37/// source nullability type
38pub type Nullable = bool;
39
40/// from / join sources
41#[derive(Debug, Clone, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize)]
42pub enum DataSource {
43    /// from CTE defined set
44    CteQuery(CteDataSource),
45    /// from a table
46    Table(TableDataSource),
47    /// from a view
48    View(ViewDataSource),
49    /// join expression
50    JoinExpr(Box<JoinExprDataSource>),
51    /// sub-query
52    SubQuery(Box<SubQueryDataSource>),
53    /// table function
54    CallTableFunc(TableFunctionDataSource),
55    /// table function as source but not found
56    UndefinedTableFunc(UndefinedTableFuncDataSource),
57    /// ROWS clause
58    RowFunctions(DataSourceRowFunctions),
59    /// range table sampling
60    RangeTableSample(), // todo modeling
61    /// view or table or CTE not found
62    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                // DataSource::Unknown ready report_problem in from_clause analysis
100                ColumnReferenceExpr::unknown_source_ref(context, alias, column)
101            }
102            // resolve_alias not returns this variants
103            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    /// get alias name for data sources
145    #[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    /// resolve alias name to data source
153    #[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    /// list alias name for column name
176    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}