1mod cast_info;
2mod seq_info;
3mod table_info;
4mod type_info;
5mod view_info;
6
7use std::{
8 io::{Read, Seek},
9 path::Path,
10};
11
12pub use self::{
13 cast_info::CastInfoRead,
14 seq_info::{SequenceInfoRead, SequenceInfoWrite},
15 table_info::{TableInfoRead, TableInfoWrite},
16 type_info::{TypeInfoRead, TypeInfoWrite},
17 view_info::{ViewInfoRead, ViewInfoWrite},
18};
19
20use crate::{
21 StringSpan,
22 sem::{
23 AliasSpec, AnalysisError, AnalysisProblem, Comment, CreateCompositType, CreateDomain,
24 CreateEnum, CreateExtension, CreateFunction, CreateIndex, CreateSchema, CreateSequence,
25 CreateTable, DataSource, FullName, FunctionOverloadCollection, OperatorDefinition,
26 OperatorName, SchemaName, SemScalarExpr, TableName, TypeDefinition, TypeReference,
27 VariableSet, ViewLike, ViewName,
28 search_path::{expand_search_path, expand_search_path_inst},
29 type_system::ArgumentBindingCollection,
30 },
31};
32use sql_fun_core::{IVec, SqlFunArgs};
33
34pub trait SourceAccessService: std::fmt::Debug {
36 fn get_source_span(
38 &self,
39 _config_args: &SqlFunArgs,
40 source_path: &Path,
41 span: StringSpan,
42 ) -> Result<String, AnalysisError> {
43 let source_path = if source_path.is_absolute() {
44 source_path
45 } else {
46 source_path
48 };
49
50 if !source_path.exists() {
51 AnalysisError::file_not_found(source_path)?;
52 AnalysisError::never()
53 };
54
55 let mut file = std::fs::File::open(source_path)?;
56 file.seek(span.seek_pos())?;
57 let mut source_span = file.take(span.len() as u64);
58 let mut buf = String::default();
59 let result_len = source_span.read_to_string(&mut buf)?;
60 if result_len != span.len() {
61 Err(AnalysisError::unexpected_eof())
62 } else {
63 Ok(buf)
64 }
65 }
66}
67
68#[derive(Debug, Default)]
70pub struct DefaultSourceAccessService {}
71
72impl SourceAccessService for DefaultSourceAccessService {}
73
74pub trait IndexInfoRead {
76 fn get_index(&self, index_name: &str) -> Option<&CreateIndex>;
78}
79
80pub trait FunctionInfoRead {
82 fn get_function_impl(&self, name: &FullName) -> Option<FunctionOverloadCollection>;
84}
85
86pub trait FunctionInfoWrite
88where
89 Self: Sized,
90{
91 fn apply_create_function_impl(
93 self,
94 name: &FullName,
95 create_function: &CreateFunction,
96 ) -> Result<Self, AnalysisError>;
97}
98
99pub trait OperatorInfoRead {
101 fn get_operator_op(
107 &self,
108 name: &OperatorName,
109 has_left: bool,
110 has_right: bool,
111 ) -> Option<&OperatorDefinition>;
112}
113
114pub trait SearchPathRead {
116 fn set_search_path(&mut self, search_path: Vec<SchemaName>);
118
119 fn get_search_path(&self) -> &[SchemaName];
121
122 fn get_default_schema(&self) -> Option<SchemaName>;
128}
129
130pub trait BaseParseContext:
137 CastInfoRead
138 + FunctionInfoRead
139 + IndexInfoRead
140 + OperatorInfoRead
141 + SequenceInfoRead
142 + TypeInfoRead
143 + TableInfoRead
144 + ViewInfoRead
145 + SearchPathRead
146 + std::fmt::Debug
147{
148 fn get_args(&self) -> &SqlFunArgs;
150
151 fn get_source_file_path(&self) -> Option<&Path>;
153
154 fn get_type(&self, key: &FullName) -> Option<&TypeDefinition> {
156 expand_search_path(self, key, |k| self.get_type_impl(k))
157 }
158
159 fn get_table(&self, name: &TableName) -> Option<&CreateTable> {
161 expand_search_path(self, name.full_name(), |key| self.get_table_impl(key))
162 }
163
164 fn get_view(&self, key: &ViewName) -> Option<&ViewLike> {
166 expand_search_path(self, key.full_name(), |key| self.get_view_impl(key))
167 }
168
169 fn get_sequence(&self, seq_name: &FullName) -> Option<&CreateSequence> {
171 expand_search_path(self, seq_name, |key| self.get_sequence_impl(key))
172 }
173
174 fn get_function_by_name(&self, name: &FullName) -> Option<FunctionOverloadCollection> {
176 expand_search_path_inst(self, name, |key| self.get_function_impl(key))
177 }
178
179 fn resolve_function_name_with_search_path(&self, fun_name: &FullName) -> FullName {
181 if fun_name.schema().is_some() {
182 return fun_name.clone();
183 }
184
185 expand_search_path_inst(self, fun_name, |key| {
186 self.get_function_impl(key).map(|_| key.clone())
187 })
188 .unwrap_or_else(|| fun_name.clone())
189 }
190
191 fn report_problem(&mut self, problem: AnalysisProblem) -> Result<(), AnalysisError>;
193
194 fn extend(&mut self, extension: Box<dyn BaseParseContext>);
196
197 fn set_statement_span(&mut self, statement_span: StringSpan);
199
200 fn set_source_file(&mut self, source_acess_service: Box<dyn SourceAccessService>);
202
203 fn canonicalize_type_ref(&self, type_ref: &TypeReference) -> Option<TypeReference> {
205 let type_def = self.get_type(type_ref.full_name())?;
206 type_def.full_name().map(|full_name| {
207 TypeReference::concrete_type_ref(full_name, type_ref.is_array().unwrap_or(false))
208 })
209 }
210}
211
212pub trait ParseContext:
217 SequenceInfoWrite
218 + TypeInfoWrite
219 + TableInfoWrite
220 + ViewInfoWrite
221 + FunctionInfoWrite
222 + BaseParseContext
223 + std::fmt::Debug
224where
225 Self: Sized,
226{
227 fn apply_create_comp_type(
229 mut self,
230 create_comp_type: &CreateCompositType,
231 ) -> Result<Self, AnalysisError> {
232 let Some(name) = create_comp_type.name() else {
233 AnalysisError::raise_register_dynamic_type(create_comp_type)?;
234 AnalysisError::never()
235 };
236 let name = self.apply_default_schema(name)?;
237 self.insert_create_composite_type(&name, create_comp_type);
238 Ok(self)
239 }
240
241 fn apply_create_domain(mut self, create_domain: &CreateDomain) -> Result<Self, AnalysisError> {
243 let name = self.apply_default_schema(create_domain.name())?;
244 self.insert_create_domain(&name, create_domain);
245 Ok(self)
246 }
247
248 fn apply_comment(self, comment: &Comment) -> Result<Self, AnalysisError>;
250
251 fn apply_default_schema(&self, name: &FullName) -> Result<FullName, AnalysisError> {
253 let name = if name.schema().is_none() {
254 let Some(schema) = self.get_default_schema() else {
255 AnalysisError::raise_unexpected_none("context.get_default_schema")?
256 };
257 name.clone().set_schema(schema)
258 } else {
259 name.clone()
260 };
261 Ok(name)
262 }
263
264 fn apply_create_enum(mut self, create_enum_type: &CreateEnum) -> Result<Self, AnalysisError> {
266 let name = self.apply_default_schema(create_enum_type.name())?;
267 self.insert_create_enum(&name, create_enum_type);
268 Ok(self)
269 }
270
271 fn apply_create_table(mut self, create_table: &CreateTable) -> Result<Self, AnalysisError> {
273 let name = self.apply_default_schema(create_table.name().full_name())?;
274 self.insert_create_table(&name, create_table);
275 self.insert_table_ref_type(&TableName::from(name));
277 Ok(self)
278 }
279
280 fn apply_create_extension(
282 self,
283 create_extension: &CreateExtension,
284 ) -> Result<Self, AnalysisError>;
285
286 fn apply_create_function(
288 self,
289 create_function: &CreateFunction,
290 ) -> Result<Self, AnalysisError> {
291 let name = self.apply_default_schema(create_function.name())?;
292 self.apply_create_function_impl(&name, create_function)
293 }
294
295 fn apply_variable_set(self, variable_set: &VariableSet) -> Result<Self, AnalysisError>;
297
298 fn apply_create_schema(self, create_schema: &CreateSchema) -> Result<Self, AnalysisError>;
300
301 fn apply_create_index(self, create_index: &CreateIndex) -> Result<Self, AnalysisError>;
303
304 fn resolve_table_function(
306 &mut self,
307 call: &crate::syn::FuncCall,
308 func_name: FullName,
309 alias_name: &AliasSpec,
310 arg_exprs: IVec<SemScalarExpr>,
311 arg_types: ArgumentBindingCollection,
312 ) -> Result<DataSource, AnalysisError> {
313 let Some(overloads) = self.get_function_by_name(&func_name) else {
314 self.report_problem(AnalysisProblem::table_function_not_found(&func_name))?;
315 return DataSource::undefined_table_function(call, arg_exprs, alias_name);
316 };
317
318 let Some(calling_overload) = overloads.resolve_overload(self, &arg_types) else {
319 self.report_problem(
320 AnalysisProblem::parameter_type_missmatch_for_table_function(call, arg_types),
321 )?;
322 return DataSource::undefined_table_function(call, arg_exprs, alias_name);
323 };
324
325 Ok(DataSource::table_function(
326 &calling_overload,
327 arg_exprs,
328 alias_name,
329 ))
330 }
331}