chore: merge main into probe validation repair

This commit is contained in:
Gatefixer
2026-10-03 11:29:12 +00:00
2 changed files with 73 additions and 1 deletions
+58
View File
@@ -568,6 +568,7 @@ impl Connection {
/// Creates a new table by cloning from an existing source table.
/// By default, this performs a shallow clone where the new table shares
/// the underlying data files with the source table.
/// The target table name must be unused. An existing table is left unchanged.
///
/// # Parameters
/// - `target_table_name`: The name of the new table to create
@@ -2193,6 +2194,63 @@ mod tests {
assert_eq!(tables.len(), 0);
}
#[rstest::rstest]
#[tokio::test]
async fn test_clone_table_target_already_exists(
#[values("source", "target")] target: &str,
#[values(false, true)] enable_v2_manifest_paths: bool,
) {
use crate::query::ExecutableQuery;
use futures::TryStreamExt;
let tmp_dir = tempdir().unwrap();
let options = ListingDatabaseOptions::builder()
.enable_v2_manifest_paths(enable_v2_manifest_paths)
.build();
let db = connect(tmp_dir.path().to_str().unwrap())
.database_options(&options)
.execute()
.await
.unwrap();
let source_data = arrow_array::record_batch!(("id", Int32, [0, 1, 2])).unwrap();
let target_data = arrow_array::record_batch!(("id", Int32, [10, 11])).unwrap();
db.create_table("source", source_data.clone())
.execute()
.await
.unwrap();
db.create_table("target", target_data.clone())
.execute()
.await
.unwrap();
let source_uri = tmp_dir.path().join("source.lance");
let err = db
.clone_table(target, source_uri.to_str().unwrap())
.execute()
.await
.unwrap_err();
assert!(
matches!(&err, Error::TableAlreadyExists { name } if name == target),
"unexpected clone error: {err:?}"
);
// Reopen both tables to verify that the failed clone left their data and versions intact.
for (name, expected_data) in [("source", source_data), ("target", target_data)] {
let table = db.open_table(name).execute().await.unwrap();
assert_eq!(table.version().await.unwrap(), 1);
assert_eq!(table.list_versions().await.unwrap().len(), 1);
let batches = table
.query()
.execute()
.await
.unwrap()
.try_collect::<Vec<_>>()
.await
.unwrap();
assert_eq!(batches, vec![expected_data]);
}
}
#[tokio::test]
async fn test_clone_table() {
let tmp_dir = tempdir().unwrap();
+15 -1
View File
@@ -1107,6 +1107,21 @@ impl Database for ListingDatabase {
..Default::default()
};
let target_uri = self.table_uri(&request.target_table_name)?;
match DatasetBuilder::from_uri(&target_uri)
.with_read_params(read_params.clone())
.load()
.await
{
Ok(_) => {
return Err(Error::TableAlreadyExists {
name: request.target_table_name,
});
}
Err(lance::Error::DatasetNotFound { .. }) => {}
Err(err) => return Err(err.into()),
}
let mut source_dataset = DatasetBuilder::from_uri(&request.source_uri)
.with_read_params(read_params.clone())
.load()
@@ -1122,7 +1137,6 @@ impl Database for ListingDatabase {
}),
}?;
let target_uri = self.table_uri(&request.target_table_name)?;
source_dataset
.shallow_clone(&target_uri, version_ref, Some(storage_params))
.await