@@ -22,6 +22,7 @@ use std::fmt::{Debug, Display};
22
22
use std:: future:: Future ;
23
23
use std:: mem:: take;
24
24
use std:: ops:: Deref ;
25
+ use std:: sync:: Arc ;
25
26
26
27
use _serde:: deserialize_snapshot;
27
28
use async_trait:: async_trait;
@@ -313,6 +314,27 @@ impl TableCommit {
313
314
pub fn take_updates ( & mut self ) -> Vec < TableUpdate > {
314
315
take ( & mut self . updates )
315
316
}
317
+
318
+ /// Applies this [`TableCommit`] to the given [`Table`] as part of a catalog update.
319
+ /// Typically used by [`Catalog::update_table`] to validate requirements and apply metadata updates.
320
+ ///
321
+ /// Returns a new [`Table`] with updated metadata,
322
+ /// or an error if validation or application fails.
323
+ pub fn apply ( self , table : Table ) -> Result < Table > {
324
+ // check requirements
325
+ for requirement in self . requirements {
326
+ requirement. check ( Some ( table. metadata ( ) ) ) ?;
327
+ }
328
+
329
+ // apply updates to metadata builder
330
+ let mut metadata_builder = table. metadata ( ) . clone ( ) . into_builder ( None ) ;
331
+
332
+ for update in self . updates {
333
+ metadata_builder = update. apply ( metadata_builder) ?;
334
+ }
335
+
336
+ Ok ( table. with_metadata ( Arc :: new ( metadata_builder. build ( ) ?. metadata ) ) )
337
+ }
316
338
}
317
339
318
340
/// TableRequirement represents a requirement for a table in the catalog.
@@ -884,12 +906,15 @@ mod _serde_set_statistics {
884
906
mod tests {
885
907
use std:: collections:: HashMap ;
886
908
use std:: fmt:: Debug ;
909
+ use std:: fs:: File ;
910
+ use std:: io:: BufReader ;
887
911
888
912
use serde:: Serialize ;
889
913
use serde:: de:: DeserializeOwned ;
890
914
use uuid:: uuid;
891
915
892
916
use super :: ViewUpdate ;
917
+ use crate :: io:: FileIOBuilder ;
893
918
use crate :: spec:: {
894
919
BlobMetadata , FormatVersion , MAIN_BRANCH , NestedField , NullOrder , Operation ,
895
920
PartitionStatisticsFile , PrimitiveType , Schema , Snapshot , SnapshotReference ,
@@ -898,7 +923,10 @@ mod tests {
898
923
UnboundPartitionSpec , ViewFormatVersion , ViewRepresentation , ViewRepresentations ,
899
924
ViewVersion ,
900
925
} ;
901
- use crate :: { NamespaceIdent , TableCreation , TableIdent , TableRequirement , TableUpdate } ;
926
+ use crate :: table:: Table ;
927
+ use crate :: {
928
+ NamespaceIdent , TableCommit , TableCreation , TableIdent , TableRequirement , TableUpdate ,
929
+ } ;
902
930
903
931
#[ test]
904
932
fn test_parent_namespace ( ) {
@@ -2111,4 +2139,66 @@ mod tests {
2111
2139
} ,
2112
2140
) ;
2113
2141
}
2142
+
2143
+ #[ test]
2144
+ fn test_table_commit ( ) {
2145
+ let table = {
2146
+ let file = File :: open ( format ! (
2147
+ "{}/testdata/table_metadata/{}" ,
2148
+ env!( "CARGO_MANIFEST_DIR" ) ,
2149
+ "TableMetadataV2Valid.json"
2150
+ ) )
2151
+ . unwrap ( ) ;
2152
+ let reader = BufReader :: new ( file) ;
2153
+ let resp = serde_json:: from_reader :: < _ , TableMetadata > ( reader) . unwrap ( ) ;
2154
+
2155
+ Table :: builder ( )
2156
+ . metadata ( resp)
2157
+ . metadata_location ( "s3://bucket/test/location/metadata/v2.json" . to_string ( ) )
2158
+ . identifier ( TableIdent :: from_strs ( [ "ns1" , "test1" ] ) . unwrap ( ) )
2159
+ . file_io ( FileIOBuilder :: new ( "memory" ) . build ( ) . unwrap ( ) )
2160
+ . build ( )
2161
+ . unwrap ( )
2162
+ } ;
2163
+
2164
+ let updates = vec ! [
2165
+ TableUpdate :: SetLocation {
2166
+ location: "s3://bucket/test/new_location/metadata/v2.json" . to_string( ) ,
2167
+ } ,
2168
+ TableUpdate :: SetProperties {
2169
+ updates: vec![
2170
+ ( "prop1" . to_string( ) , "v1" . to_string( ) ) ,
2171
+ ( "prop2" . to_string( ) , "v2" . to_string( ) ) ,
2172
+ ]
2173
+ . into_iter( )
2174
+ . collect( ) ,
2175
+ } ,
2176
+ ] ;
2177
+
2178
+ let requirements = vec ! [ TableRequirement :: UuidMatch {
2179
+ uuid: table. metadata( ) . table_uuid,
2180
+ } ] ;
2181
+
2182
+ let table_commit = TableCommit :: builder ( )
2183
+ . ident ( table. identifier ( ) . to_owned ( ) )
2184
+ . updates ( updates)
2185
+ . requirements ( requirements)
2186
+ . build ( ) ;
2187
+
2188
+ let updated_table = table_commit. apply ( table) . unwrap ( ) ;
2189
+
2190
+ assert_eq ! (
2191
+ updated_table. metadata( ) . properties. get( "prop1" ) . unwrap( ) ,
2192
+ "v1"
2193
+ ) ;
2194
+ assert_eq ! (
2195
+ updated_table. metadata( ) . properties. get( "prop2" ) . unwrap( ) ,
2196
+ "v2"
2197
+ ) ;
2198
+
2199
+ assert_eq ! (
2200
+ updated_table. metadata( ) . location,
2201
+ "s3://bucket/test/new_location/metadata/v2.json" . to_string( )
2202
+ )
2203
+ }
2114
2204
}
0 commit comments