@@ -263,6 +263,63 @@ impl TableConfiguration {
263
263
version => ( 2 ..=6 ) . contains ( & version) ,
264
264
}
265
265
}
266
+
267
+ /// Returns `true` if the table supports writing in-commit timestamps.
268
+ ///
269
+ /// To support this feature the table must:
270
+ /// - Have a min_writer_version of 7
271
+ /// - Have the [`WriterFeature::InCommitTimestamps`] writer feature.
272
+ #[ allow( unused) ]
273
+ pub ( crate ) fn is_in_commit_timestamps_supported ( & self ) -> bool {
274
+ self . protocol ( ) . min_writer_version ( ) == 7
275
+ && self
276
+ . protocol ( )
277
+ . has_writer_feature ( & WriterFeature :: InCommitTimestamps )
278
+ }
279
+
280
+ /// Returns `true` if in-commit timestamps is supported and it is enabled. In-commit timestamps
281
+ /// is enabled when the `delta.enableInCommitTimestamps` configuration is set to `true`.
282
+ #[ allow( unused) ]
283
+ pub ( crate ) fn is_in_commit_timestamps_enabled ( & self ) -> bool {
284
+ self . is_in_commit_timestamps_supported ( )
285
+ && self
286
+ . table_properties ( )
287
+ . enable_in_commit_timestamps
288
+ . unwrap_or ( false )
289
+ }
290
+
291
+ /// If in-commit timestamps is enabled, this retrieves the in-commit timestamp enablement version
292
+ /// and timestamps.
293
+ ///
294
+ /// If in-commit timestamps is not supported, or not enabled, this returns `None`.
295
+ /// If in-commit timestams is enabled, but the enablement version or timestamp is not present,
296
+ /// this returns an error.
297
+ #[ allow( unused) ]
298
+ pub ( crate ) fn in_commit_timestamp_enablement ( & self ) -> DeltaResult < Option < ( Version , i64 ) > > {
299
+ if !self . is_in_commit_timestamps_enabled ( ) {
300
+ return Ok ( None ) ;
301
+ }
302
+ let enablement_version = self
303
+ . table_properties ( )
304
+ . in_commit_timestamp_enablement_version ;
305
+ let enablement_timestamp = self
306
+ . table_properties ( )
307
+ . in_commit_timestamp_enablement_timestamp ;
308
+
309
+ let ict_error = |err : & str | {
310
+ Error :: generic ( format ! (
311
+ "In-commit timestamp enabled, but missing Enablement version or timestamp. {err}"
312
+ ) )
313
+ } ;
314
+ match ( enablement_version, enablement_timestamp) {
315
+ ( Some ( version) , Some ( timestamp) ) => Ok ( Some ( ( version, timestamp) ) ) ,
316
+ ( Some ( version) , None ) => Err ( ict_error ( "Enablement timestamp is not present" ) ) ,
317
+ ( None , Some ( timestmap) ) => Err ( ict_error ( "Enablement version is not present" ) ) ,
318
+ ( None , None ) => Err ( ict_error (
319
+ "Enablement version and timestamp are not present." ,
320
+ ) ) ,
321
+ }
322
+ }
266
323
}
267
324
268
325
#[ cfg( test) ]
@@ -274,6 +331,7 @@ mod test {
274
331
use crate :: actions:: { Metadata , Protocol } ;
275
332
use crate :: table_features:: { ReaderFeature , WriterFeature } ;
276
333
use crate :: table_properties:: TableProperties ;
334
+ use crate :: Error ;
277
335
278
336
use super :: TableConfiguration ;
279
337
@@ -326,6 +384,75 @@ mod test {
326
384
assert ! ( table_config. is_deletion_vector_enabled( ) ) ;
327
385
}
328
386
#[ test]
387
+ fn ict_supported_and_enabled ( ) {
388
+ let metadata = Metadata {
389
+ schema_string : r#"{"type":"struct","fields":[{"name":"value","type":"integer","nullable":true,"metadata":{}}]}"# . to_string ( ) ,
390
+ configuration : HashMap :: from_iter ( [ (
391
+ "delta.enableInCommitTimestamps" . to_string ( ) ,
392
+ "true" . to_string ( ) ,
393
+ ) ,
394
+ ( "delta.inCommitTimestampEnablementVersion" . to_string ( ) , "5" . to_string ( ) ) ,
395
+ ( "delta.inCommitTimestampEnablementTimestamp" . to_string ( ) , "100" . to_string ( ) ) ] ) ,
396
+ ..Default :: default ( )
397
+ } ;
398
+ let protocol = Protocol :: try_new (
399
+ 3 ,
400
+ 7 ,
401
+ Some :: < Vec < String > > ( vec ! [ ] ) ,
402
+ Some ( [ WriterFeature :: InCommitTimestamps ] ) ,
403
+ )
404
+ . unwrap ( ) ;
405
+ let table_root = Url :: try_from ( "file:///" ) . unwrap ( ) ;
406
+ let table_config = TableConfiguration :: try_new ( metadata, protocol, table_root, 0 ) . unwrap ( ) ;
407
+ assert ! ( table_config. is_in_commit_timestamps_supported( ) ) ;
408
+ assert ! ( table_config. is_in_commit_timestamps_enabled( ) ) ;
409
+ let enablement = table_config. in_commit_timestamp_enablement ( ) . unwrap ( ) ;
410
+ assert_eq ! ( enablement, Some ( ( 5 , 100 ) ) )
411
+ }
412
+ #[ test]
413
+ fn ict_supported_and_enabled_without_enablement_info ( ) {
414
+ let metadata = Metadata {
415
+ schema_string : r#"{"type":"struct","fields":[{"name":"value","type":"integer","nullable":true,"metadata":{}}]}"# . to_string ( ) ,
416
+ configuration : HashMap :: from_iter ( [ (
417
+ "delta.enableInCommitTimestamps" . to_string ( ) ,
418
+ "true" . to_string ( ) ,
419
+ ) ] ) ,
420
+ ..Default :: default ( )
421
+ } ;
422
+ let protocol = Protocol :: try_new (
423
+ 3 ,
424
+ 7 ,
425
+ Some :: < Vec < String > > ( vec ! [ ] ) ,
426
+ Some ( [ WriterFeature :: InCommitTimestamps ] ) ,
427
+ )
428
+ . unwrap ( ) ;
429
+ let table_root = Url :: try_from ( "file:///" ) . unwrap ( ) ;
430
+ let table_config = TableConfiguration :: try_new ( metadata, protocol, table_root, 0 ) . unwrap ( ) ;
431
+ assert ! ( table_config. is_in_commit_timestamps_supported( ) ) ;
432
+ assert ! ( table_config. is_in_commit_timestamps_enabled( ) ) ;
433
+ assert ! ( matches!(
434
+ table_config. in_commit_timestamp_enablement( ) ,
435
+ Err ( Error :: Generic ( msg) ) if msg. contains( "Enablement version and timestamp are not present." ) ) ) ;
436
+ }
437
+ #[ test]
438
+ fn ict_supported_and_not_enabled ( ) {
439
+ let metadata = Metadata {
440
+ schema_string : r#"{"type":"struct","fields":[{"name":"value","type":"integer","nullable":true,"metadata":{}}]}"# . to_string ( ) ,
441
+ ..Default :: default ( )
442
+ } ;
443
+ let protocol = Protocol :: try_new (
444
+ 3 ,
445
+ 7 ,
446
+ Some :: < Vec < String > > ( vec ! [ ] ) ,
447
+ Some ( [ WriterFeature :: InCommitTimestamps ] ) ,
448
+ )
449
+ . unwrap ( ) ;
450
+ let table_root = Url :: try_from ( "file:///" ) . unwrap ( ) ;
451
+ let table_config = TableConfiguration :: try_new ( metadata, protocol, table_root, 0 ) . unwrap ( ) ;
452
+ assert ! ( table_config. is_in_commit_timestamps_supported( ) ) ;
453
+ assert ! ( !table_config. is_in_commit_timestamps_enabled( ) ) ;
454
+ }
455
+ #[ test]
329
456
fn fails_on_unsupported_feature ( ) {
330
457
let metadata = Metadata {
331
458
schema_string : r#"{"type":"struct","fields":[{"name":"value","type":"integer","nullable":true,"metadata":{}}]}"# . to_string ( ) ,
0 commit comments