1
1
use crate :: call_defs:: CallDef ;
2
+
2
3
use partiql_value:: Value ;
3
4
use std:: borrow:: Cow ;
4
5
@@ -66,19 +67,32 @@ impl TableFunction {
66
67
}
67
68
}
68
69
69
- /// Catalog Errors.
70
+ /// Contains the errors that occur during Catalog related operations
71
+ #[ derive( Error , Debug , Clone , PartialEq ) ]
72
+ #[ error( "Catalog error: encountered errors" ) ]
73
+ pub struct CatalogError {
74
+ pub errors : Vec < CatalogErrorKind > ,
75
+ }
76
+
77
+ impl CatalogError {
78
+ pub fn new ( errors : Vec < CatalogErrorKind > ) -> Self {
79
+ CatalogError { errors }
80
+ }
81
+ }
82
+
83
+ /// Catalog Error kind
70
84
///
71
85
/// ### Notes
72
86
/// This is marked `#[non_exhaustive]`, to reserve the right to add more variants in the future.
73
87
#[ derive( Error , Debug , Clone , PartialEq ) ]
74
88
#[ non_exhaustive]
75
- pub enum CatalogError {
89
+ pub enum CatalogErrorKind {
76
90
/// Entry exists error.
77
- #[ error( "Catalog error: entry already exists for `{}`" , . 0 ) ]
91
+ #[ error( "Catalog error: entry already exists for `{0 }`" ) ]
78
92
EntryExists ( String ) ,
79
93
80
94
/// Entry error.
81
- #[ error( "Catalog error: `{}`" , . 0 ) ]
95
+ #[ error( "Catalog error: `{0 }`" ) ]
82
96
EntryError ( String ) ,
83
97
84
98
/// Any other catalog error.
@@ -93,7 +107,6 @@ pub trait Catalog: Debug {
93
107
}
94
108
95
109
#[ derive( Debug ) ]
96
- #[ allow( dead_code) ]
97
110
pub struct FunctionEntry < ' a > {
98
111
id : ObjectId ,
99
112
function : & ' a FunctionEntryFunction ,
@@ -127,15 +140,13 @@ impl<'a> FunctionEntry<'a> {
127
140
#[ derive( Debug ) ]
128
141
pub struct PartiqlCatalog {
129
142
functions : CatalogEntrySet < FunctionEntryFunction > ,
130
-
131
143
id : CatalogId ,
132
144
}
133
145
134
146
impl Default for PartiqlCatalog {
135
147
fn default ( ) -> Self {
136
148
PartiqlCatalog {
137
149
functions : Default :: default ( ) ,
138
-
139
150
id : CatalogId ( 1 ) ,
140
151
}
141
152
}
@@ -156,9 +167,9 @@ impl Catalog for PartiqlCatalog {
156
167
entry_id : id,
157
168
} )
158
169
} else {
159
- Err ( CatalogError :: EntryError (
170
+ Err ( CatalogError :: new ( vec ! [ CatalogErrorKind :: EntryError (
160
171
"Function definition has no name" . into( ) ,
161
- ) )
172
+ ) ] ) )
162
173
}
163
174
}
164
175
@@ -179,6 +190,7 @@ impl Catalog for PartiqlCatalog {
179
190
struct CatalogEntrySet < T > {
180
191
entries : HashMap < EntryId , T > ,
181
192
by_name : HashMap < UniCase < String > , EntryId > ,
193
+ by_alias : HashMap < UniCase < String > , EntryId > ,
182
194
183
195
next_id : AtomicU64 ,
184
196
}
@@ -188,26 +200,49 @@ impl<T> Default for CatalogEntrySet<T> {
188
200
CatalogEntrySet {
189
201
entries : Default :: default ( ) ,
190
202
by_name : Default :: default ( ) ,
203
+ by_alias : Default :: default ( ) ,
191
204
next_id : 1 . into ( ) ,
192
205
}
193
206
}
194
207
}
195
208
196
209
impl < T > CatalogEntrySet < T > {
197
- fn add ( & mut self , name : & str , _aliases : & [ & str ] , info : T ) -> Result < EntryId , CatalogError > {
210
+ fn add ( & mut self , name : & str , aliases : & [ & str ] , info : T ) -> Result < EntryId , CatalogError > {
211
+ let mut errors = vec ! [ ] ;
198
212
let name = UniCase :: from ( name) ;
213
+ let aliases: Vec < UniCase < String > > = aliases
214
+ . iter ( )
215
+ . map ( |a| UniCase :: from ( a. to_string ( ) ) )
216
+ . collect ( ) ;
217
+
218
+ aliases. iter ( ) . for_each ( |a| {
219
+ if self . by_alias . contains_key ( a) {
220
+ errors. push ( CatalogErrorKind :: EntryExists ( a. as_ref ( ) . to_string ( ) ) )
221
+ }
222
+ } ) ;
223
+
199
224
if self . by_name . contains_key ( & name) {
200
- return Err ( CatalogError :: EntryExists ( name. to_string ( ) ) ) ;
225
+ errors . push ( CatalogErrorKind :: EntryExists ( name. to_string ( ) ) ) ;
201
226
}
202
227
203
228
let id = self . next_id . fetch_add ( 1 , Ordering :: SeqCst ) . into ( ) ;
229
+
204
230
if let Some ( _old_val) = self . entries . insert ( id, info) {
205
- return Err ( CatalogError :: Unknown ) ;
231
+ errors . push ( CatalogErrorKind :: Unknown ) ;
206
232
}
207
233
208
- self . by_name . insert ( name, id) ;
234
+ match errors. is_empty ( ) {
235
+ true => {
236
+ self . by_name . insert ( name, id) ;
237
+
238
+ for a in aliases. into_iter ( ) {
239
+ self . by_alias . insert ( a, id) ;
240
+ }
209
241
210
- Ok ( id)
242
+ Ok ( id)
243
+ }
244
+ _ => Err ( CatalogError :: new ( errors) ) ,
245
+ }
211
246
}
212
247
213
248
fn find_by_name ( & self , name : & str ) -> Option < ( EntryId , & T ) > {
0 commit comments