@@ -414,7 +414,9 @@ mod tests {
414
414
use std:: vec;
415
415
416
416
use iceberg:: io:: FileIOBuilder ;
417
- use iceberg:: spec:: { NestedField , PartitionSpec , PrimitiveType , Schema , SortOrder , Type } ;
417
+ use iceberg:: spec:: {
418
+ NestedField , NullOrder , PartitionSpec , PrimitiveType , Schema , SortOrder , Type ,
419
+ } ;
418
420
use iceberg:: transaction:: Transaction ;
419
421
use regex:: Regex ;
420
422
use tempfile:: TempDir ;
@@ -480,6 +482,14 @@ mod tests {
480
482
}
481
483
}
482
484
485
+ async fn create_table_with_namespace < C : Catalog > ( catalog : & C ) -> Table {
486
+ let namespace_ident = NamespaceIdent :: new ( "abc" . into ( ) ) ;
487
+ create_namespace ( catalog, & namespace_ident) . await ;
488
+
489
+ let table_ident = TableIdent :: new ( namespace_ident, "test" . to_string ( ) ) ;
490
+ create_table ( catalog, & table_ident) . await
491
+ }
492
+
483
493
fn assert_table_eq ( table : & Table , expected_table_ident : & TableIdent , expected_schema : & Schema ) {
484
494
assert_eq ! ( table. identifier( ) , expected_table_ident) ;
485
495
@@ -1812,10 +1822,7 @@ mod tests {
1812
1822
async fn test_update_table ( ) {
1813
1823
let catalog = new_memory_catalog ( ) ;
1814
1824
1815
- let namespace_ident = NamespaceIdent :: new ( "a" . into ( ) ) ;
1816
- create_namespace ( & catalog, & namespace_ident) . await ;
1817
- let table_ident = TableIdent :: new ( namespace_ident, "test" . to_string ( ) ) ;
1818
- let table = create_table ( & catalog, & table_ident) . await ;
1825
+ let table = create_table_with_namespace ( & catalog) . await ;
1819
1826
1820
1827
// Assert the table doesn't contain the update yet
1821
1828
assert ! ( !table. metadata( ) . properties( ) . contains_key( "key" ) ) ;
@@ -1842,15 +1849,48 @@ mod tests {
1842
1849
) ;
1843
1850
}
1844
1851
1852
+ #[ tokio:: test]
1853
+ async fn test_update_table_fails_if_commit_conflicts ( ) {
1854
+ let catalog = new_memory_catalog ( ) ;
1855
+ let base_table = create_table_with_namespace ( & catalog) . await ;
1856
+
1857
+ // Update the table by adding a new sort order.
1858
+ let _sorted_table = Transaction :: new ( & base_table)
1859
+ . replace_sort_order ( )
1860
+ . asc ( "foo" , NullOrder :: First )
1861
+ . unwrap ( )
1862
+ . apply ( )
1863
+ . unwrap ( )
1864
+ . commit ( & catalog)
1865
+ . await
1866
+ . unwrap ( ) ;
1867
+
1868
+ // Try to update the -now old- table again with a different sort order.
1869
+ let err = Transaction :: new ( & base_table)
1870
+ . replace_sort_order ( )
1871
+ . desc ( "foo" , NullOrder :: Last )
1872
+ . unwrap ( )
1873
+ . apply ( )
1874
+ . unwrap ( )
1875
+ . commit ( & catalog)
1876
+ . await
1877
+ . unwrap_err ( ) ;
1878
+
1879
+ // The second transaction should fail because it didn't take the new update
1880
+ // into account.
1881
+ assert_eq ! ( err. kind( ) , ErrorKind :: Unexpected ) ;
1882
+ assert ! ( err. message( ) . to_lowercase( ) . contains( "conflict" ) ) ;
1883
+ }
1884
+
1845
1885
#[ tokio:: test]
1846
1886
async fn test_update_table_fails_if_table_doesnt_exist ( ) {
1847
1887
let catalog = new_memory_catalog ( ) ;
1848
1888
1849
1889
let namespace_ident = NamespaceIdent :: new ( "a" . into ( ) ) ;
1850
1890
create_namespace ( & catalog, & namespace_ident) . await ;
1851
- let table_ident = TableIdent :: new ( namespace_ident, "test" . to_string ( ) ) ;
1852
1891
1853
1892
// This table is not known to the catalog.
1893
+ let table_ident = TableIdent :: new ( namespace_ident, "test" . to_string ( ) ) ;
1854
1894
let table = build_table ( table_ident) ;
1855
1895
1856
1896
let err = Transaction :: new ( & table)
0 commit comments