@@ -13,9 +13,9 @@ use futures::TryStreamExt;
13
13
use object_store:: ObjectStore ;
14
14
15
15
use crate :: errors:: DeltaResult ;
16
- use crate :: open_table_with_storage_options;
17
- use crate :: storage:: * ;
18
16
use crate :: table:: builder:: ensure_table_uri;
17
+ use crate :: DeltaTableBuilder ;
18
+ use crate :: { storage:: * , DeltaTable } ;
19
19
20
20
const DELTA_LOG_FOLDER : & str = "_delta_log" ;
21
21
@@ -36,7 +36,7 @@ pub struct ListingSchemaProvider {
36
36
/// Underlying object store
37
37
store : Arc < dyn ObjectStore > ,
38
38
/// A map of table names to a fully quilfied storage location
39
- tables : DashMap < String , String > ,
39
+ tables : DashMap < String , Arc < dyn TableProvider > > ,
40
40
/// Options used to create underlying object stores
41
41
storage_options : StorageOptions ,
42
42
}
@@ -73,17 +73,42 @@ impl ListingSchemaProvider {
73
73
parent = p;
74
74
}
75
75
}
76
+
76
77
for table in tables. into_iter ( ) {
77
78
let table_name = normalize_table_name ( table) ?;
78
79
let table_path = table
79
80
. to_str ( )
80
81
. ok_or_else ( || DataFusionError :: Internal ( "Cannot parse file name!" . to_string ( ) ) ) ?
81
82
. to_string ( ) ;
82
83
if !self . table_exist ( & table_name) {
83
- let table_url = format ! ( "{}/{table_path}" , self . authority) ;
84
- self . tables . insert ( table_name. to_string ( ) , table_url) ;
84
+ let table_url = format ! ( "{}/{}" , self . authority, table_path) ;
85
+ let Ok ( delta_table) = DeltaTableBuilder :: from_uri ( table_url)
86
+ . with_storage_options ( self . storage_options . 0 . clone ( ) )
87
+ . build ( )
88
+ else {
89
+ continue ;
90
+ } ;
91
+ let _ = self . register_table ( table_name, Arc :: new ( delta_table) ) ;
92
+ }
93
+ }
94
+ Ok ( ( ) )
95
+ }
96
+
97
+ /// Tables are not initialized but have a reference setup. To initialize the delta
98
+ /// table, the `load()` function must be called on the delta table. This function helps with
99
+ /// that and ensures the DashMap is updated
100
+ pub async fn load_table ( & self , table_name : & str ) -> datafusion:: common:: Result < ( ) > {
101
+ if let Some ( mut table) = self . tables . get_mut ( & table_name. to_string ( ) ) {
102
+ if let Some ( delta_table) = table. value ( ) . as_any ( ) . downcast_ref :: < DeltaTable > ( ) {
103
+ // If table has not yet been loaded, we remove it from the tables map and add it again
104
+ if delta_table. state . is_none ( ) {
105
+ let mut delta_table = delta_table. clone ( ) ;
106
+ delta_table. load ( ) . await ?;
107
+ * table = Arc :: from ( delta_table) ;
108
+ }
85
109
}
86
110
}
111
+
87
112
Ok ( ( ) )
88
113
}
89
114
}
@@ -112,31 +137,31 @@ impl SchemaProvider for ListingSchemaProvider {
112
137
}
113
138
114
139
async fn table ( & self , name : & str ) -> datafusion_common:: Result < Option < Arc < dyn TableProvider > > > {
115
- let Some ( location ) = self . tables . get ( name) . map ( |t| t. clone ( ) ) else {
140
+ let Some ( provider ) = self . tables . get ( name) . map ( |t| t. clone ( ) ) else {
116
141
return Ok ( None ) ;
117
142
} ;
118
- let provider =
119
- open_table_with_storage_options ( location, self . storage_options . 0 . clone ( ) ) . await ?;
120
- Ok ( Some ( Arc :: new ( provider) as Arc < dyn TableProvider > ) )
143
+ Ok ( Some ( provider) )
121
144
}
122
145
123
146
fn register_table (
124
147
& self ,
125
- _name : String ,
126
- _table : Arc < dyn TableProvider > ,
148
+ name : String ,
149
+ table : Arc < dyn TableProvider > ,
127
150
) -> datafusion_common:: Result < Option < Arc < dyn TableProvider > > > {
128
- Err ( DataFusionError :: Execution (
129
- "schema provider does not support registering tables" . to_owned ( ) ,
130
- ) )
151
+ if !self . table_exist ( name. as_str ( ) ) {
152
+ self . tables . insert ( name, table. clone ( ) ) ;
153
+ }
154
+ Ok ( Some ( table) )
131
155
}
132
156
133
157
fn deregister_table (
134
158
& self ,
135
- _name : & str ,
159
+ name : & str ,
136
160
) -> datafusion_common:: Result < Option < Arc < dyn TableProvider > > > {
137
- Err ( DataFusionError :: Execution (
138
- "schema provider does not support deregistering tables" . to_owned ( ) ,
139
- ) )
161
+ if let Some ( table) = self . tables . remove ( name) {
162
+ return Ok ( Some ( table. 1 ) ) ;
163
+ }
164
+ Ok ( None )
140
165
}
141
166
142
167
fn table_exist ( & self , name : & str ) -> bool {
@@ -177,6 +202,7 @@ mod tests {
177
202
async fn test_query_table ( ) {
178
203
let schema = Arc :: new ( ListingSchemaProvider :: try_new ( "../test/tests/data/" , None ) . unwrap ( ) ) ;
179
204
schema. refresh ( ) . await . unwrap ( ) ;
205
+ schema. load_table ( "simple_table" ) . await . unwrap ( ) ;
180
206
181
207
let ctx = SessionContext :: new ( ) ;
182
208
let catalog = Arc :: new ( MemoryCatalogProvider :: default ( ) ) ;
0 commit comments