This is an automated email from the ASF dual-hosted git repository.
mneumann pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs-object-store.git
The following commit(s) were added to refs/heads/main by this push:
new e89f62b fix[prefix]: strip_meta from get_opts result in PrefixStore
(#686)
e89f62b is described below
commit e89f62b6508f6f65873ce6a5017cd0d5d7395184
Author: Alfonso Subiotto Marqués <[email protected]>
AuthorDate: Wed Apr 8 14:52:59 2026 +0200
fix[prefix]: strip_meta from get_opts result in PrefixStore (#686)
---
src/integration.rs | 1 +
src/prefix.rs | 24 +++++++++++++++++++++++-
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/src/integration.rs b/src/integration.rs
index 6b55bb2..e68837c 100644
--- a/src/integration.rs
+++ b/src/integration.rs
@@ -177,6 +177,7 @@ pub async fn put_get_delete_list(storage: &DynObjectStore) {
let head = storage.head(&location).await.unwrap();
assert_eq!(head.size, data.len() as u64);
+ assert_eq!(head.location, location);
storage.delete(&location).await.unwrap();
diff --git a/src/prefix.rs b/src/prefix.rs
index 0ffb09a..9cdf3b0 100644
--- a/src/prefix.rs
+++ b/src/prefix.rs
@@ -117,7 +117,9 @@ impl<T: ObjectStore> ObjectStore for PrefixStore<T> {
async fn get_opts(&self, location: &Path, options: GetOptions) ->
Result<GetResult> {
let full_path = self.full_path(location);
- self.inner.get_opts(&full_path, options).await
+ let mut result = self.inner.get_opts(&full_path, options).await?;
+ result.meta = self.strip_meta(result.meta);
+ Ok(result)
}
async fn get_ranges(&self, location: &Path, ranges: &[Range<u64>]) ->
Result<Vec<Bytes>> {
@@ -299,6 +301,26 @@ mod tests {
assert_eq!(&*read_data, data)
}
+ // Regression test for
+ // https://github.com/apache/arrow-rs-object-store/issues/664:
+ // head/get returned an ObjectMeta whose location still contained the
+ // prefix, so round-tripping the returned location back into the store
would
+ // double-prefix it.
+ #[tokio::test]
+ async fn prefix_head_get_strip_prefix() {
+ let store = PrefixStore::new(InMemory::new(), "prefix");
+ let path = Path::from("test_file");
+ store.put(&path, "data".into()).await.unwrap();
+
+ let head = store.head(&path).await.unwrap();
+ assert_eq!(head.location, path);
+ let get = store.get(&path).await.unwrap();
+ assert_eq!(get.meta.location, path);
+
+ // The returned location must round-trip back into the same store.
+ store.get(&head.location).await.unwrap();
+ }
+
#[tokio::test]
async fn prefix_multipart() {
let store = PrefixStore::new(InMemory::new(), "prefix");