@@ -22,6 +22,7 @@ use std::fmt::{Debug, Display};
2222use std:: future:: Future ;
2323use std:: mem:: take;
2424use std:: ops:: Deref ;
25+ use std:: sync:: Arc ;
2526
2627use _serde:: deserialize_snapshot;
2728use async_trait:: async_trait;
@@ -313,6 +314,27 @@ impl TableCommit {
313314 pub fn take_updates ( & mut self ) -> Vec < TableUpdate > {
314315 take ( & mut self . updates )
315316 }
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+ }
316338}
317339
318340/// TableRequirement represents a requirement for a table in the catalog.
@@ -884,12 +906,15 @@ mod _serde_set_statistics {
884906mod tests {
885907 use std:: collections:: HashMap ;
886908 use std:: fmt:: Debug ;
909+ use std:: fs:: File ;
910+ use std:: io:: BufReader ;
887911
888912 use serde:: Serialize ;
889913 use serde:: de:: DeserializeOwned ;
890914 use uuid:: uuid;
891915
892916 use super :: ViewUpdate ;
917+ use crate :: io:: FileIOBuilder ;
893918 use crate :: spec:: {
894919 BlobMetadata , FormatVersion , MAIN_BRANCH , NestedField , NullOrder , Operation ,
895920 PartitionStatisticsFile , PrimitiveType , Schema , Snapshot , SnapshotReference ,
@@ -898,7 +923,10 @@ mod tests {
898923 UnboundPartitionSpec , ViewFormatVersion , ViewRepresentation , ViewRepresentations ,
899924 ViewVersion ,
900925 } ;
901- use crate :: { NamespaceIdent , TableCreation , TableIdent , TableRequirement , TableUpdate } ;
926+ use crate :: table:: Table ;
927+ use crate :: {
928+ NamespaceIdent , TableCommit , TableCreation , TableIdent , TableRequirement , TableUpdate ,
929+ } ;
902930
903931 #[ test]
904932 fn test_parent_namespace ( ) {
@@ -2111,4 +2139,66 @@ mod tests {
21112139 } ,
21122140 ) ;
21132141 }
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+ }
21142204}
0 commit comments