mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-04 13:32:13 +00:00
feat: add etag for object storage
This commit is contained in:
parent
905495e59b
commit
766130bc98
@ -86,6 +86,7 @@ private:
|
|||||||
Poco::Timestamp::fromEpochTime(
|
Poco::Timestamp::fromEpochTime(
|
||||||
std::chrono::duration_cast<std::chrono::seconds>(
|
std::chrono::duration_cast<std::chrono::seconds>(
|
||||||
static_cast<std::chrono::system_clock::time_point>(blob.Details.LastModified).time_since_epoch()).count()),
|
static_cast<std::chrono::system_clock::time_point>(blob.Details.LastModified).time_since_epoch()).count()),
|
||||||
|
blob.Details.ETag.ToString(),
|
||||||
{}}));
|
{}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,6 +187,7 @@ void AzureObjectStorage::listObjects(const std::string & path, RelativePathsWith
|
|||||||
Poco::Timestamp::fromEpochTime(
|
Poco::Timestamp::fromEpochTime(
|
||||||
std::chrono::duration_cast<std::chrono::seconds>(
|
std::chrono::duration_cast<std::chrono::seconds>(
|
||||||
static_cast<std::chrono::system_clock::time_point>(blob.Details.LastModified).time_since_epoch()).count()),
|
static_cast<std::chrono::system_clock::time_point>(blob.Details.LastModified).time_since_epoch()).count()),
|
||||||
|
blob.Details.ETag.ToString(),
|
||||||
{}}));
|
{}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +205,7 @@ void DiskObjectStorageMetadata::addObject(ObjectStorageKey key, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
total_size += size;
|
total_size += size;
|
||||||
keys_with_meta.emplace_back(std::move(key), ObjectMetadata{size, {}, {}});
|
keys_with_meta.emplace_back(std::move(key), ObjectMetadata{size, {}, {}, {}});
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectKeyWithMetadata DiskObjectStorageMetadata::popLastObject()
|
ObjectKeyWithMetadata DiskObjectStorageMetadata::popLastObject()
|
||||||
|
@ -221,6 +221,7 @@ void HDFSObjectStorage::listObjects(const std::string & path, RelativePathsWithM
|
|||||||
ObjectMetadata{
|
ObjectMetadata{
|
||||||
static_cast<uint64_t>(ls.file_info[i].mSize),
|
static_cast<uint64_t>(ls.file_info[i].mSize),
|
||||||
Poco::Timestamp::fromEpochTime(ls.file_info[i].mLastMod),
|
Poco::Timestamp::fromEpochTime(ls.file_info[i].mLastMod),
|
||||||
|
"",
|
||||||
{}}));
|
{}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ struct ObjectMetadata
|
|||||||
{
|
{
|
||||||
uint64_t size_bytes = 0;
|
uint64_t size_bytes = 0;
|
||||||
Poco::Timestamp last_modified;
|
Poco::Timestamp last_modified;
|
||||||
|
std::string etag;
|
||||||
ObjectAttributes attributes;
|
ObjectAttributes attributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ private:
|
|||||||
auto objects = outcome.GetResult().GetContents();
|
auto objects = outcome.GetResult().GetContents();
|
||||||
for (const auto & object : objects)
|
for (const auto & object : objects)
|
||||||
{
|
{
|
||||||
ObjectMetadata metadata{static_cast<uint64_t>(object.GetSize()), Poco::Timestamp::fromEpochTime(object.GetLastModified().Seconds()), {}};
|
ObjectMetadata metadata{static_cast<uint64_t>(object.GetSize()), Poco::Timestamp::fromEpochTime(object.GetLastModified().Seconds()), object.GetETag(), {}};
|
||||||
batch.emplace_back(std::make_shared<RelativePathWithMetadata>(object.GetKey(), std::move(metadata)));
|
batch.emplace_back(std::make_shared<RelativePathWithMetadata>(object.GetKey(), std::move(metadata)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,6 +329,7 @@ void S3ObjectStorage::listObjects(const std::string & path, RelativePathsWithMet
|
|||||||
ObjectMetadata{
|
ObjectMetadata{
|
||||||
static_cast<uint64_t>(object.GetSize()),
|
static_cast<uint64_t>(object.GetSize()),
|
||||||
Poco::Timestamp::fromEpochTime(object.GetLastModified().Seconds()),
|
Poco::Timestamp::fromEpochTime(object.GetLastModified().Seconds()),
|
||||||
|
object.GetETag(),
|
||||||
{}}));
|
{}}));
|
||||||
|
|
||||||
if (max_keys)
|
if (max_keys)
|
||||||
@ -476,6 +477,7 @@ ObjectMetadata S3ObjectStorage::getObjectMetadata(const std::string & path) cons
|
|||||||
ObjectMetadata result;
|
ObjectMetadata result;
|
||||||
result.size_bytes = object_info.size;
|
result.size_bytes = object_info.size;
|
||||||
result.last_modified = Poco::Timestamp::fromEpochTime(object_info.last_modification_time);
|
result.last_modified = Poco::Timestamp::fromEpochTime(object_info.last_modification_time);
|
||||||
|
result.etag = object_info.etag;
|
||||||
result.attributes = object_info.metadata;
|
result.attributes = object_info.metadata;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -54,6 +54,8 @@ namespace
|
|||||||
ObjectInfo object_info;
|
ObjectInfo object_info;
|
||||||
object_info.size = static_cast<size_t>(result.GetContentLength());
|
object_info.size = static_cast<size_t>(result.GetContentLength());
|
||||||
object_info.last_modification_time = result.GetLastModified().Seconds();
|
object_info.last_modification_time = result.GetLastModified().Seconds();
|
||||||
|
String etag(result.GetETag.c_str(), result.GetETag().size());
|
||||||
|
object_info.etag = etag;
|
||||||
|
|
||||||
if (with_metadata)
|
if (with_metadata)
|
||||||
object_info.metadata = result.GetMetadata();
|
object_info.metadata = result.GetMetadata();
|
||||||
|
@ -15,6 +15,7 @@ struct ObjectInfo
|
|||||||
{
|
{
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
time_t last_modification_time = 0;
|
time_t last_modification_time = 0;
|
||||||
|
String etag = "";
|
||||||
|
|
||||||
std::map<String, String> metadata = {}; /// Set only if getObjectInfo() is called with `with_metadata = true`.
|
std::map<String, String> metadata = {}; /// Set only if getObjectInfo() is called with `with_metadata = true`.
|
||||||
};
|
};
|
||||||
|
@ -201,7 +201,8 @@ Chunk StorageObjectStorageSource::generate()
|
|||||||
.path = getUniqueStoragePathIdentifier(*configuration, reader.getObjectInfo(), false),
|
.path = getUniqueStoragePathIdentifier(*configuration, reader.getObjectInfo(), false),
|
||||||
.size = object_info.metadata->size_bytes,
|
.size = object_info.metadata->size_bytes,
|
||||||
.filename = &filename,
|
.filename = &filename,
|
||||||
.last_modified = object_info.metadata->last_modified
|
.last_modified = object_info.metadata->last_modified,
|
||||||
|
.etag = &(object_info.metadata->etag)
|
||||||
});
|
});
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ void filterBlockWithDAG(ActionsDAGPtr dag, Block & block, ContextPtr context)
|
|||||||
|
|
||||||
NameSet getVirtualNamesForFileLikeStorage()
|
NameSet getVirtualNamesForFileLikeStorage()
|
||||||
{
|
{
|
||||||
return {"_path", "_file", "_size", "_time"};
|
return {"_path", "_file", "_size", "_time", "_etag", "_last_modified"};
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualColumnsDescription getVirtualsForFileLikeStorage(const ColumnsDescription & storage_columns)
|
VirtualColumnsDescription getVirtualsForFileLikeStorage(const ColumnsDescription & storage_columns)
|
||||||
@ -131,6 +131,7 @@ VirtualColumnsDescription getVirtualsForFileLikeStorage(const ColumnsDescription
|
|||||||
add_virtual("_file", std::make_shared<DataTypeLowCardinality>(std::make_shared<DataTypeString>()));
|
add_virtual("_file", std::make_shared<DataTypeLowCardinality>(std::make_shared<DataTypeString>()));
|
||||||
add_virtual("_size", makeNullable(std::make_shared<DataTypeUInt64>()));
|
add_virtual("_size", makeNullable(std::make_shared<DataTypeUInt64>()));
|
||||||
add_virtual("_time", makeNullable(std::make_shared<DataTypeDateTime>()));
|
add_virtual("_time", makeNullable(std::make_shared<DataTypeDateTime>()));
|
||||||
|
add_virtual("_etag", std::make_shared<DataTypeLowCardinality>(std::make_shared<DataTypeString>()));
|
||||||
|
|
||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
@ -226,6 +227,13 @@ void addRequestedFileLikeStorageVirtualsToChunk(
|
|||||||
else
|
else
|
||||||
chunk.addColumn(virtual_column.type->createColumnConstWithDefaultValue(chunk.getNumRows())->convertToFullColumnIfConst());
|
chunk.addColumn(virtual_column.type->createColumnConstWithDefaultValue(chunk.getNumRows())->convertToFullColumnIfConst());
|
||||||
}
|
}
|
||||||
|
else if (virtual_column.name == "_etag")
|
||||||
|
{
|
||||||
|
if (virtual_values.etag)
|
||||||
|
chunk.addColumn(virtual_column.type->createColumnConst(chunk.getNumRows(), (*virtual_values.etag))->convertToFullColumnIfConst());
|
||||||
|
else
|
||||||
|
chunk.addColumn(virtual_column.type->createColumnConstWithDefaultValue(chunk.getNumRows())->convertToFullColumnIfConst());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ struct VirtualsForFileLikeStorage
|
|||||||
std::optional<size_t> size { std::nullopt };
|
std::optional<size_t> size { std::nullopt };
|
||||||
const String * filename { nullptr };
|
const String * filename { nullptr };
|
||||||
std::optional<Poco::Timestamp> last_modified { std::nullopt };
|
std::optional<Poco::Timestamp> last_modified { std::nullopt };
|
||||||
|
const String * etag { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
void addRequestedFileLikeStorageVirtualsToChunk(
|
void addRequestedFileLikeStorageVirtualsToChunk(
|
||||||
|
Loading…
Reference in New Issue
Block a user