mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 08:40:50 +00:00
Merge pull request #30190 from azat/ReadBuffer-throw-on-empty
Do not allow zero-length reads
This commit is contained in:
commit
1e058fb207
23
src/IO/ReadBufferFromEmptyFile.h
Normal file
23
src/IO/ReadBufferFromEmptyFile.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <IO/ReadBuffer.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/// In case of empty file it does not make any sense to read it.
|
||||
///
|
||||
/// Plus regular readers from file has an assert that buffer is not empty, that will fail:
|
||||
/// - ReadBufferFromFileDescriptor
|
||||
/// - SynchronousReader
|
||||
/// - ThreadPoolReader
|
||||
class ReadBufferFromEmptyFile : public ReadBufferFromFileBase
|
||||
{
|
||||
private:
|
||||
bool nextImpl() override { return false; }
|
||||
std::string getFileName() const override { return "<empty>"; }
|
||||
off_t seek(off_t /*off*/, int /*whence*/) override { return 0; }
|
||||
off_t getPosition() override { return 0; }
|
||||
};
|
||||
|
||||
}
|
@ -51,6 +51,9 @@ std::string ReadBufferFromFileDescriptor::getFileName() const
|
||||
|
||||
bool ReadBufferFromFileDescriptor::nextImpl()
|
||||
{
|
||||
/// If internal_buffer size is empty, then read() cannot be distinguished from EOF
|
||||
assert(!internal_buffer.empty());
|
||||
|
||||
size_t bytes_read = 0;
|
||||
while (!bytes_read)
|
||||
{
|
||||
|
@ -36,6 +36,9 @@ namespace ErrorCodes
|
||||
|
||||
std::future<IAsynchronousReader::Result> SynchronousReader::submit(Request request)
|
||||
{
|
||||
/// If size is zero, then read() cannot be distinguished from EOF
|
||||
assert(request.size);
|
||||
|
||||
int fd = assert_cast<const LocalFileDescriptor &>(*request.descriptor).fd;
|
||||
|
||||
#if defined(POSIX_FADV_WILLNEED)
|
||||
|
@ -76,6 +76,9 @@ ThreadPoolReader::ThreadPoolReader(size_t pool_size, size_t queue_size_)
|
||||
|
||||
std::future<IAsynchronousReader::Result> ThreadPoolReader::submit(Request request)
|
||||
{
|
||||
/// If size is zero, then read() cannot be distinguished from EOF
|
||||
assert(request.size);
|
||||
|
||||
int fd = assert_cast<const LocalFileDescriptor &>(*request.descriptor).fd;
|
||||
|
||||
#if defined(__linux__)
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <IO/createReadBufferFromFileBase.h>
|
||||
#include <IO/ReadBufferFromEmptyFile.h>
|
||||
#include <IO/ReadBufferFromFile.h>
|
||||
#include <IO/MMapReadBufferFromFileWithCache.h>
|
||||
#include <IO/AsynchronousReadBufferFromFile.h>
|
||||
@ -33,6 +34,8 @@ std::unique_ptr<ReadBufferFromFileBase> createReadBufferFromFileBase(
|
||||
char * existing_memory,
|
||||
size_t alignment)
|
||||
{
|
||||
if (size.has_value() && !*size)
|
||||
return std::make_unique<ReadBufferFromEmptyFile>();
|
||||
size_t estimated_size = size.has_value() ? *size : 0;
|
||||
|
||||
if (!existing_memory
|
||||
|
@ -71,6 +71,9 @@ MergeTreeReaderCompact::MergeTreeReaderCompact(
|
||||
if (buffer_size)
|
||||
settings.read_settings = settings.read_settings.adjustBufferSize(buffer_size);
|
||||
|
||||
if (!settings.read_settings.local_fs_buffer_size || !settings.read_settings.remote_fs_buffer_size)
|
||||
throw Exception(ErrorCodes::CANNOT_READ_ALL_DATA, "Cannot read to empty buffer.");
|
||||
|
||||
const String full_data_path = data_part->getFullRelativePath() + MergeTreeDataPartCompact::DATA_FILE_NAME_WITH_EXTENSION;
|
||||
if (uncompressed_cache)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user