@@ -538,34 +538,64 @@ pub(crate) fn object_store_path(table_root: &Url) -> DeltaResult<Path> {
538538
539539/// TODO
540540pub fn to_uri ( root : & Url , location : & Path ) -> String {
541+ let location_str = location. as_ref ( ) ;
542+
543+ // Handle absolute URIs in location (e.g., s3://, gcs://, abfss://) regardless of root scheme
544+ if location_str. contains ( "://" ) {
545+ return location_str. to_string ( ) ;
546+ }
547+
541548 match root. scheme ( ) {
542549 "file" => {
543- #[ cfg( windows) ]
544- let uri = format ! (
545- "{}/{}" ,
546- root. as_ref( ) . trim_end_matches( '/' ) ,
547- location. as_ref( )
548- )
549- . replace ( "file:///" , "" ) ;
550- #[ cfg( unix) ]
551- let uri = format ! (
552- "{}/{}" ,
553- root. as_ref( ) . trim_end_matches( '/' ) ,
554- location. as_ref( )
555- )
556- . replace ( "file://" , "" ) ;
557- uri
550+ // Handle file URIs by stripping the scheme prefix
551+ if let Some ( path) = strip_file_uri_scheme ( location_str) {
552+ return ensure_absolute_path ( path) ;
553+ }
554+
555+ // Handle relative paths by making them absolute with respect to the table root
556+ let uri_intermediate = format ! ( "{}/{}" , root. as_ref( ) . trim_end_matches( '/' ) , location_str) ;
557+ let os_abs_path = strip_file_uri_scheme ( & uri_intermediate)
558+ . map ( ensure_absolute_path)
559+ . unwrap_or_else ( || {
560+ // Fallback: strip file:// prefix manually
561+ #[ cfg( windows) ]
562+ let stripped = uri_intermediate. replace ( "file:///" , "" ) ;
563+ #[ cfg( unix) ]
564+ let stripped = uri_intermediate. replace ( "file://" , "" ) ;
565+ stripped
566+ } ) ;
567+
568+ os_abs_path
558569 }
559570 _ => {
560- if location . as_ref ( ) . is_empty ( ) || location . as_ref ( ) == "/" {
571+ if location_str . is_empty ( ) || location_str == "/" {
561572 root. as_ref ( ) . to_string ( )
562573 } else {
563- format ! ( "{}/{}" , root. as_ref( ) , location . as_ref ( ) )
574+ format ! ( "{}/{}" , root. as_ref( ) , location_str )
564575 }
565576 }
566577 }
567578}
568579
580+ /// Strip file URI scheme prefixes and return the path portion
581+ fn strip_file_uri_scheme ( uri : & str ) -> Option < String > {
582+ if uri. starts_with ( "file:///" ) {
583+ Some ( uri. strip_prefix ( "file:///" ) ?. to_string ( ) )
584+ } else if uri. starts_with ( "file:/" ) && !uri. starts_with ( "file://" ) {
585+ Some ( uri. strip_prefix ( "file:/" ) ?. to_string ( ) )
586+ } else {
587+ None
588+ }
589+ }
590+
591+ /// Ensure the path starts with '/' to make it a valid OS absolute path
592+ fn ensure_absolute_path ( mut path : String ) -> String {
593+ if !path. starts_with ( '/' ) && !path. is_empty ( ) {
594+ path. insert ( 0 , '/' ) ;
595+ }
596+ path
597+ }
598+
569599/// Reads a commit and gets list of actions
570600pub async fn get_actions (
571601 version : i64 ,
0 commit comments