Skip to content

Commit f665ffd

Browse files
zfarrellclaude
andcommitted
fix: handle empty catalogs where data directory does not yet exist
Replace canonicalize() with std::path::absolute() in parse_local_path() so that the data directory is not required to exist at catalog creation time. This supports new DuckLake catalogs that have schemas/tables defined but no data files written yet. Closes #57 Co-Authored-By: Claude Opus 4.6 <[email protected]>
1 parent b3b25a7 commit f665ffd

1 file changed

Lines changed: 20 additions & 13 deletions

File tree

src/path_resolver.rs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,12 @@ fn parse_file_url(data_path: &str) -> Result<(ObjectStoreUrl, String)> {
9999
fn parse_local_path(data_path: &str) -> Result<(ObjectStoreUrl, String)> {
100100
let has_trailing_slash = data_path.ends_with('/') || data_path.ends_with('\\');
101101

102-
let absolute_path = std::path::PathBuf::from(data_path)
103-
.canonicalize()
104-
.map_err(|e| {
105-
DuckLakeError::InvalidConfig(format!("Failed to resolve path '{}': {}", data_path, e))
106-
})?;
102+
// Use std::path::absolute() instead of canonicalize() so that the path
103+
// does not need to exist on disk yet. This supports empty catalogs where
104+
// the data directory has not been created (#57).
105+
let absolute_path = std::path::absolute(data_path).map_err(|e| {
106+
DuckLakeError::InvalidConfig(format!("Failed to resolve path '{}': {}", data_path, e))
107+
})?;
107108

108109
let object_store_url = ObjectStoreUrl::parse("file:///").map_err(|e| {
109110
DuckLakeError::InvalidConfig(format!("Failed to create ObjectStoreUrl: {}", e))
@@ -442,14 +443,20 @@ mod tests {
442443

443444
#[test]
444445
fn test_parse_local_path_nonexistent() {
445-
let result = parse_object_store_url("/nonexistent/path/that/does/not/exist");
446-
assert!(result.is_err());
447-
assert!(
448-
result
449-
.unwrap_err()
450-
.to_string()
451-
.contains("Failed to resolve path")
452-
);
446+
// Non-existent paths should now succeed (#57) - the directory does not
447+
// need to exist at catalog creation time (e.g., empty catalogs).
448+
let (url, path) =
449+
parse_object_store_url("/nonexistent/path/that/does/not/exist").unwrap();
450+
assert_eq!(url, ObjectStoreUrl::parse("file:///").unwrap());
451+
assert_eq!(path, "/nonexistent/path/that/does/not/exist");
452+
}
453+
454+
#[test]
455+
fn test_parse_local_path_nonexistent_with_trailing_slash() {
456+
let (url, path) =
457+
parse_object_store_url("/nonexistent/data/path/").unwrap();
458+
assert_eq!(url, ObjectStoreUrl::parse("file:///").unwrap());
459+
assert_eq!(path, "/nonexistent/data/path/");
453460
}
454461

455462
#[test]

0 commit comments

Comments
 (0)