sql_fun_sqlast/sem/scalar_expr/
column_ref.rs1mod cte_column_ref;
2mod invalid_column_ref;
3mod subquery_column_ref;
4mod table_column_ref;
5mod table_func_col_ref;
6mod view_column_ref;
7
8use sql_fun_core::IVec;
9
10pub use self::{
11 cte_column_ref::CteColumnRef,
12 invalid_column_ref::{
13 UndefinedAliasColumnRef, UnknownSourceColumnRef, UnknownTableFuncColumnRef,
14 },
15 subquery_column_ref::SubQueryColumnRef,
16 table_column_ref::TableColumnRef,
17 table_func_col_ref::TableFunctionColumnRef,
18 view_column_ref::ViewColumnRef,
19};
20
21use crate::{
22 sem::{
23 AnalysisError, AnalysisProblem, ColumnDefinition, ColumnName, FromClause, ParseContext,
24 SemScalarExpr, TypeReference, WithClause,
25 data_source::AliasName,
26 scalar_expr::{AnalyzeScalarExpr, SemScalarExprNode},
27 },
28 syn::{ListOpt, ScanToken},
29};
30
31trait ColumnReference {
32 fn get_type(&self) -> Option<TypeReference>;
33 fn is_not_null(&self) -> Option<bool>;
34 fn get_column_def(&self) -> &Option<ColumnDefinition>;
35 fn get_column_name(&self) -> &ColumnName;
36}
37
38#[derive(Debug, Clone, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize)]
40pub enum ColumnReferenceExpr {
41 CteColumn(CteColumnRef),
43 TableColumn(TableColumnRef),
45 ViewColumn(ViewColumnRef),
47 TableFuncColumn(TableFunctionColumnRef),
49 SubQueryColumn(SubQueryColumnRef),
51
52 UndefinedAlias(UndefinedAliasColumnRef),
54 UndefinedTableOrView(UnknownSourceColumnRef),
56 UndefinedFunction(UnknownTableFuncColumnRef),
58 UndefinedColumn(ColumnName),
60 AmbiguousColumnRef(ColumnName),
62}
63
64impl SemScalarExprNode for ColumnReferenceExpr {
65 fn get_type(&self) -> Option<TypeReference> {
66 self.get_type()
67 }
68
69 fn is_not_null(&self) -> Option<bool> {
70 self.is_not_null()
71 }
72}
73
74impl ColumnReferenceExpr {
75 #[must_use]
77 pub fn get_type(&self) -> Option<TypeReference> {
78 match self {
79 Self::CteColumn(r) => r.get_type(),
80 Self::TableColumn(r) => r.get_type(),
81 Self::ViewColumn(r) => r.get_type(),
82 Self::TableFuncColumn(r) => r.get_type(),
83 Self::SubQueryColumn(r) => r.get_type(),
84 Self::UndefinedAlias(r) => r.get_type(),
85 Self::UndefinedTableOrView(r) => r.get_type(),
86 Self::UndefinedFunction(r) => r.get_type(),
87 Self::UndefinedColumn(_) => None,
88 Self::AmbiguousColumnRef(_) => None,
89 }
90 }
91
92 #[must_use]
94 pub fn is_not_null(&self) -> Option<bool> {
95 match self {
96 Self::CteColumn(r) => r.is_not_null(),
97 Self::TableColumn(r) => r.is_not_null(),
98 Self::ViewColumn(r) => r.is_not_null(),
99 Self::TableFuncColumn(r) => r.is_not_null(),
100 Self::SubQueryColumn(r) => r.is_not_null(),
101 Self::UndefinedAlias(r) => r.is_not_null(),
102 Self::UndefinedTableOrView(r) => r.is_not_null(),
103 Self::UndefinedFunction(r) => r.is_not_null(),
104 Self::UndefinedColumn(_) => None,
105 Self::AmbiguousColumnRef(_) => None,
106 }
107 }
108
109 #[must_use]
111 pub fn get_column_def(&self) -> &Option<ColumnDefinition> {
112 match self {
113 Self::CteColumn(r) => r.get_column_def(),
114 Self::TableColumn(r) => r.get_column_def(),
115 Self::ViewColumn(r) => r.get_column_def(),
116 Self::TableFuncColumn(r) => r.get_column_def(),
117 Self::SubQueryColumn(r) => r.get_column_def(),
118 Self::UndefinedAlias(r) => r.get_column_def(),
119 Self::UndefinedTableOrView(r) => r.get_column_def(),
120 Self::UndefinedFunction(r) => r.get_column_def(),
121 Self::UndefinedColumn(_) => &None,
122 Self::AmbiguousColumnRef(_) => &None,
123 }
124 }
125
126 #[must_use]
128 pub fn get_column_name(&self) -> &ColumnName {
129 match self {
130 Self::CteColumn(r) => r.get_column_name(),
131 Self::TableColumn(r) => r.get_column_name(),
132 Self::ViewColumn(r) => r.get_column_name(),
133 Self::TableFuncColumn(r) => r.get_column_name(),
134 Self::SubQueryColumn(r) => r.get_column_name(),
135 Self::UndefinedAlias(r) => r.get_column_name(),
136 Self::UndefinedTableOrView(r) => r.get_column_name(),
137 Self::UndefinedFunction(r) => r.get_column_name(),
138 Self::UndefinedColumn(c) => c,
139 Self::AmbiguousColumnRef(c) => c,
140 }
141 }
142
143 pub fn undefined_column_with_report<TParseContext>(
145 context: &mut TParseContext,
146 column: &ColumnName,
147 ) -> Result<SemScalarExpr, AnalysisError>
148 where
149 TParseContext: ParseContext,
150 {
151 context.report_problem(AnalysisProblem::column_not_found_in_source(column))?;
152 Ok(SemScalarExpr::ColumnRef(Self::UndefinedColumn(
153 column.clone(),
154 )))
155 }
156
157 pub fn ambiguous_column_with_report<TParseContext>(
159 context: &mut TParseContext,
160 column: &ColumnName,
161 ) -> Result<SemScalarExpr, AnalysisError>
162 where
163 TParseContext: ParseContext,
164 {
165 context.report_problem(AnalysisProblem::ambiguous_column(column))?;
166 Ok(SemScalarExpr::ColumnRef(Self::AmbiguousColumnRef(
167 column.clone(),
168 )))
169 }
170
171 fn source_ref<TParseContext>(
172 mut context: TParseContext,
173 with_clause: &WithClause,
174 from_clause: &FromClause,
175 alias: &AliasName,
176 column: &ColumnName,
177 ) -> Result<(SemScalarExpr, TParseContext), AnalysisError>
178 where
179 TParseContext: ParseContext,
180 {
181 let Some((from_def, nullability)) = from_clause.resolve_alias(alias) else {
182 let scalar_expr =
183 UndefinedAliasColumnRef::new_with_report(&mut context, alias, column)?;
184 return Ok((scalar_expr, context));
185 };
186 from_def.create_column_ref(context, with_clause, alias, column, nullability)
187 }
188}
189
190impl<TParseContext> AnalyzeScalarExpr<TParseContext, crate::syn::ColumnRef> for ColumnReferenceExpr
191where
192 TParseContext: ParseContext,
193{
194 fn analyze_scalar_expr(
195 mut context: TParseContext,
196 with_clause: &WithClause,
197 from_clause: &FromClause,
198 syn: crate::syn::ColumnRef,
199 _tokens: &IVec<ScanToken>,
200 ) -> Result<(SemScalarExpr, TParseContext), AnalysisError> {
201 let Some(fields) = syn.get_fields().map(|v| v.as_string()) else {
202 AnalysisError::raise_unexpected_none("column_ref.fields")?
203 };
204
205 let fields: Vec<String> = fields.iter().map(crate::syn::String::get_sval).collect();
206 if fields.len() > 2 {
207 AnalysisError::raise_unexpected_input(&format!(
208 "unexpected len column_ref.fields {}",
209 fields.len()
210 ))?;
211 }
212
213 if fields.len() == 1 {
214 let column = ColumnName::from(fields[0].clone());
215
216 let Ok(find_alias_result) =
217 from_clause.find_alias_for_column(&column, &context, with_clause)
218 else {
219 let scalar_expr =
220 ColumnReferenceExpr::ambiguous_column_with_report(&mut context, &column)?;
221 return Ok((scalar_expr, context));
222 };
223 let Some(alias) = find_alias_result else {
224 let scalar_expr =
225 ColumnReferenceExpr::undefined_column_with_report(&mut context, &column)?;
226 return Ok((scalar_expr, context));
227 };
228 Self::source_ref(context, with_clause, from_clause, alias.name(), &column)
229 } else if fields.len() == 2 {
230 let alias = &fields[0];
231 let column = ColumnName::from(fields[1].clone());
232 Self::source_ref(
233 context,
234 with_clause,
235 from_clause,
236 &AliasName::from(alias.as_str()),
237 &column,
238 )
239 } else {
240 unreachable!()
241 }
242 }
243}