11use crate :: call_defs:: CallDef ;
2+
23use partiql_value:: Value ;
34use std:: borrow:: Cow ;
45
@@ -66,19 +67,32 @@ impl TableFunction {
6667 }
6768}
6869
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
7084///
7185/// ### Notes
7286/// This is marked `#[non_exhaustive]`, to reserve the right to add more variants in the future.
7387#[ derive( Error , Debug , Clone , PartialEq ) ]
7488#[ non_exhaustive]
75- pub enum CatalogError {
89+ pub enum CatalogErrorKind {
7690 /// Entry exists error.
77- #[ error( "Catalog error: entry already exists for `{}`" , . 0 ) ]
91+ #[ error( "Catalog error: entry already exists for `{0 }`" ) ]
7892 EntryExists ( String ) ,
7993
8094 /// Entry error.
81- #[ error( "Catalog error: `{}`" , . 0 ) ]
95+ #[ error( "Catalog error: `{0 }`" ) ]
8296 EntryError ( String ) ,
8397
8498 /// Any other catalog error.
@@ -93,7 +107,6 @@ pub trait Catalog: Debug {
93107}
94108
95109#[ derive( Debug ) ]
96- #[ allow( dead_code) ]
97110pub struct FunctionEntry < ' a > {
98111 id : ObjectId ,
99112 function : & ' a FunctionEntryFunction ,
@@ -127,15 +140,13 @@ impl<'a> FunctionEntry<'a> {
127140#[ derive( Debug ) ]
128141pub struct PartiqlCatalog {
129142 functions : CatalogEntrySet < FunctionEntryFunction > ,
130-
131143 id : CatalogId ,
132144}
133145
134146impl Default for PartiqlCatalog {
135147 fn default ( ) -> Self {
136148 PartiqlCatalog {
137149 functions : Default :: default ( ) ,
138-
139150 id : CatalogId ( 1 ) ,
140151 }
141152 }
@@ -156,9 +167,9 @@ impl Catalog for PartiqlCatalog {
156167 entry_id : id,
157168 } )
158169 } else {
159- Err ( CatalogError :: EntryError (
170+ Err ( CatalogError :: new ( vec ! [ CatalogErrorKind :: EntryError (
160171 "Function definition has no name" . into( ) ,
161- ) )
172+ ) ] ) )
162173 }
163174 }
164175
@@ -179,6 +190,7 @@ impl Catalog for PartiqlCatalog {
179190struct CatalogEntrySet < T > {
180191 entries : HashMap < EntryId , T > ,
181192 by_name : HashMap < UniCase < String > , EntryId > ,
193+ by_alias : HashMap < UniCase < String > , EntryId > ,
182194
183195 next_id : AtomicU64 ,
184196}
@@ -188,26 +200,49 @@ impl<T> Default for CatalogEntrySet<T> {
188200 CatalogEntrySet {
189201 entries : Default :: default ( ) ,
190202 by_name : Default :: default ( ) ,
203+ by_alias : Default :: default ( ) ,
191204 next_id : 1 . into ( ) ,
192205 }
193206 }
194207}
195208
196209impl < 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 ! [ ] ;
198212 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+
199224 if self . by_name . contains_key ( & name) {
200- return Err ( CatalogError :: EntryExists ( name. to_string ( ) ) ) ;
225+ errors . push ( CatalogErrorKind :: EntryExists ( name. to_string ( ) ) ) ;
201226 }
202227
203228 let id = self . next_id . fetch_add ( 1 , Ordering :: SeqCst ) . into ( ) ;
229+
204230 if let Some ( _old_val) = self . entries . insert ( id, info) {
205- return Err ( CatalogError :: Unknown ) ;
231+ errors . push ( CatalogErrorKind :: Unknown ) ;
206232 }
207233
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+ }
209241
210- Ok ( id)
242+ Ok ( id)
243+ }
244+ _ => Err ( CatalogError :: new ( errors) ) ,
245+ }
211246 }
212247
213248 fn find_by_name ( & self , name : & str ) -> Option < ( EntryId , & T ) > {
0 commit comments