uqa_sql/schema/
type_lookup.rs1use super::RowSchema;
10use crate::ast::{ColumnDef, ColumnType, InternalColumnRef};
11
12pub trait ScalarTypeSchema {
14 fn has_unqualified_column(&self, name: &str) -> bool;
15 fn column_is_ambiguous(&self, name: &str) -> bool;
16 fn type_of(&self, name: &str) -> Option<&ColumnType>;
17 fn column_type(&self, position: usize) -> Option<&ColumnType>;
18 fn internal_type(&self, column: InternalColumnRef) -> Option<&ColumnType>;
19 fn has_qualifier(&self, qualifier: &str) -> bool;
20 fn has_qualified_column(&self, qualifier: &str, name: &str) -> bool;
21 fn qualified_column_is_ambiguous(&self, qualifier: &str, name: &str) -> bool;
22 fn qualified_type(&self, qualifier: &str, name: &str) -> Option<&ColumnType>;
23 fn columns_are_open(&self, qualifier: Option<&str>) -> bool;
24
25 fn physical_schema(&self) -> Option<&RowSchema>;
27}
28
29impl ScalarTypeSchema for RowSchema {
30 fn has_unqualified_column(&self, name: &str) -> bool {
31 Self::has_unqualified_column(self, name)
32 }
33 fn column_is_ambiguous(&self, name: &str) -> bool {
34 Self::column_is_ambiguous(self, name)
35 }
36 fn type_of(&self, name: &str) -> Option<&ColumnType> {
37 Self::type_of(self, name)
38 }
39 fn column_type(&self, position: usize) -> Option<&ColumnType> {
40 Self::column_type(self, position)
41 }
42 fn internal_type(&self, column: InternalColumnRef) -> Option<&ColumnType> {
43 Self::internal_type(self, column)
44 }
45 fn has_qualifier(&self, qualifier: &str) -> bool {
46 Self::has_qualifier(self, qualifier)
47 }
48 fn has_qualified_column(&self, qualifier: &str, name: &str) -> bool {
49 Self::has_qualified_column(self, qualifier, name)
50 }
51 fn qualified_column_is_ambiguous(&self, qualifier: &str, name: &str) -> bool {
52 Self::qualified_column_is_ambiguous(self, qualifier, name)
53 }
54 fn qualified_type(&self, qualifier: &str, name: &str) -> Option<&ColumnType> {
55 Self::qualified_type(self, qualifier, name)
56 }
57 fn columns_are_open(&self, qualifier: Option<&str>) -> bool {
58 Self::columns_are_open(self, qualifier)
59 }
60 fn physical_schema(&self) -> Option<&RowSchema> {
61 Some(self)
62 }
63}
64
65#[derive(Clone, Copy)]
67pub struct ColumnTypeSchema<'a> {
68 columns: &'a [ColumnDef],
69}
70
71impl<'a> ColumnTypeSchema<'a> {
72 pub fn new(columns: &'a [ColumnDef]) -> Self {
73 Self { columns }
74 }
75}
76
77impl ScalarTypeSchema for ColumnTypeSchema<'_> {
78 fn has_unqualified_column(&self, name: &str) -> bool {
79 self.columns.iter().any(|column| column.name == name)
80 }
81 fn column_is_ambiguous(&self, name: &str) -> bool {
82 self.columns
83 .iter()
84 .filter(|column| column.name == name)
85 .nth(1)
86 .is_some()
87 }
88 fn type_of(&self, name: &str) -> Option<&ColumnType> {
89 let mut matching = self.columns.iter().filter(|column| column.name == name);
90 let first = matching.next()?;
91 matching.next().is_none().then_some(&first.ty)
92 }
93 fn column_type(&self, position: usize) -> Option<&ColumnType> {
94 self.columns.get(position).map(|column| &column.ty)
95 }
96 fn internal_type(&self, _: InternalColumnRef) -> Option<&ColumnType> {
97 None
98 }
99 fn has_qualifier(&self, _: &str) -> bool {
100 false
101 }
102 fn has_qualified_column(&self, _: &str, _: &str) -> bool {
103 false
104 }
105 fn qualified_column_is_ambiguous(&self, _: &str, _: &str) -> bool {
106 false
107 }
108 fn qualified_type(&self, _: &str, _: &str) -> Option<&ColumnType> {
109 None
110 }
111 fn columns_are_open(&self, _: Option<&str>) -> bool {
112 false
113 }
114 fn physical_schema(&self) -> Option<&RowSchema> {
115 None
116 }
117}
118
119#[cfg(test)]
120mod tests;