Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions clickhouse/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,7 @@ bool Client::Impl::ReceiveData(Block & block) {

bool Client::Impl::ReceiveException(ServerError & error) {
std::shared_ptr<Exception> e(new Exception);
bool has_nested = false; // obsolete: https://github.com/ClickHouse/ClickHouse/blob/ef11941cf5a/src/IO/ReadHelpers.cpp#L2017
uint8_t has_nested = 0; // obsolete: https://github.com/ClickHouse/ClickHouse/blob/ef11941cf5a/src/IO/ReadHelpers.cpp#L2017

if (!WireFormat::ReadFixed(*input_, &e->code) ||
!WireFormat::ReadString(*input_, &e->name) ||
Expand All @@ -924,15 +924,18 @@ bool Client::Impl::ReceiveException(ServerError & error) {
}

bool Client::Impl::ReceiveProfileInfo(Profile & profile) {
if (!WireFormat::ReadUInt64(*input_, &profile.rows) ||
!WireFormat::ReadUInt64(*input_, &profile.blocks) ||
!WireFormat::ReadUInt64(*input_, &profile.bytes) ||
!WireFormat::ReadFixed(*input_, &profile.applied_limit) ||
!WireFormat::ReadUInt64(*input_, &profile.rows_before_limit) ||
!WireFormat::ReadFixed(*input_, &profile.calculated_rows_before_limit)) {
uint8_t applied_limit = 0;
uint8_t calculated_rows_before_limit = 0;

if (!WireFormat::ReadUInt64(*input_, &profile.rows) || !WireFormat::ReadUInt64(*input_, &profile.blocks) ||
!WireFormat::ReadUInt64(*input_, &profile.bytes) || !WireFormat::ReadFixed(*input_, &applied_limit) ||
!WireFormat::ReadUInt64(*input_, &profile.rows_before_limit) || !WireFormat::ReadFixed(*input_, &calculated_rows_before_limit)) {
return false;
}

profile.applied_limit = applied_limit != 0;
profile.calculated_rows_before_limit = calculated_rows_before_limit != 0;

if (events_) {
events_->OnProfile(profile);
}
Expand Down
41 changes: 41 additions & 0 deletions ut/client_protocol_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,44 @@ TEST(ClientProtocol, WellFormedSelectResponseSucceeds) {
}));
EXPECT_EQ(blocks, 1u);
}

TEST(ClientProtocol, ProfileInfoFlagsAcceptAnyNonZeroByte) {
std::vector<uint8_t> script = kServerHello;
const std::vector<uint8_t> response = {
0x06, // packet type: ServerCodes::ProfileInfo (varint)
0x01, // rows = 1 (varint)
0x00, // blocks = 0 (varint)
0x02, // bytes = 2 (varint)
0x05, // applied_limit: non-canonical true (fixed, 1 byte)
0x03, // rows_before_limit = 3 (varint)
0x00, // calculated_rows_before_limit = false (fixed, 1 byte)
0x06, // packet type: ServerCodes::ProfileInfo (varint)
0x01, 0x00, 0x02,
0x00, // applied_limit = false
0x03,
0xFF, // calculated_rows_before_limit: non-canonical true
0x05, // packet type: ServerCodes::EndOfStream (varint)
};
script.insert(script.end(), response.begin(), response.end());

Client client(ScriptedClientOptions(), std::make_unique<ScriptedSocketFactory>(script));

std::vector<std::pair<uint8_t, uint8_t>> flags;
Query query("SELECT 1");
query.OnProfile([&flags](const Profile& profile) {
EXPECT_EQ(profile.rows, 1u);
EXPECT_EQ(profile.bytes, 2u);
EXPECT_EQ(profile.rows_before_limit, 3u);
// Inspect the object representation: a bool holding anything other
// than 0 or 1 is undefined behaviour to load.
flags.emplace_back(*reinterpret_cast<const uint8_t*>(&profile.applied_limit),
*reinterpret_cast<const uint8_t*>(&profile.calculated_rows_before_limit));
});
client.Select(query);

ASSERT_EQ(flags.size(), 2u);
EXPECT_EQ(flags[0].first, 1u);
EXPECT_EQ(flags[0].second, 0u);
EXPECT_EQ(flags[1].first, 0u);
EXPECT_EQ(flags[1].second, 1u);
}
Loading