2017-06-26 12:30:35 +00:00
|
|
|
#include <DataStreams/BlockStreamProfileInfo.h>
|
2019-01-23 14:48:50 +00:00
|
|
|
#include <DataStreams/IBlockInputStream.h>
|
2017-06-26 12:30:35 +00:00
|
|
|
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <IO/ReadHelpers.h>
|
|
|
|
#include <IO/WriteHelpers.h>
|
2015-01-18 08:25:56 +00:00
|
|
|
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <Core/Block.h>
|
2015-01-18 08:25:56 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
|
|
|
void BlockStreamProfileInfo::read(ReadBuffer & in)
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
readVarUInt(rows, in);
|
|
|
|
readVarUInt(blocks, in);
|
|
|
|
readVarUInt(bytes, in);
|
|
|
|
readBinary(applied_limit, in);
|
|
|
|
readVarUInt(rows_before_limit, in);
|
|
|
|
readBinary(calculated_rows_before_limit, in);
|
2015-01-18 08:25:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void BlockStreamProfileInfo::write(WriteBuffer & out) const
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
writeVarUInt(rows, out);
|
|
|
|
writeVarUInt(blocks, out);
|
|
|
|
writeVarUInt(bytes, out);
|
|
|
|
writeBinary(hasAppliedLimit(), out);
|
|
|
|
writeVarUInt(getRowsBeforeLimit(), out);
|
|
|
|
writeBinary(calculated_rows_before_limit, out);
|
2015-01-18 08:25:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-01-27 12:38:59 +00:00
|
|
|
void BlockStreamProfileInfo::setFrom(const BlockStreamProfileInfo & rhs, bool skip_block_size_info)
|
2016-01-25 21:40:13 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
if (!skip_block_size_info)
|
|
|
|
{
|
|
|
|
rows = rhs.rows;
|
|
|
|
blocks = rhs.blocks;
|
|
|
|
bytes = rhs.bytes;
|
|
|
|
}
|
|
|
|
applied_limit = rhs.applied_limit;
|
|
|
|
rows_before_limit = rhs.rows_before_limit;
|
|
|
|
calculated_rows_before_limit = rhs.calculated_rows_before_limit;
|
2016-01-25 21:40:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-01-18 08:25:56 +00:00
|
|
|
size_t BlockStreamProfileInfo::getRowsBeforeLimit() const
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
if (!calculated_rows_before_limit)
|
|
|
|
calculateRowsBeforeLimit();
|
|
|
|
return rows_before_limit;
|
2015-01-18 08:25:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool BlockStreamProfileInfo::hasAppliedLimit() const
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
if (!calculated_rows_before_limit)
|
|
|
|
calculateRowsBeforeLimit();
|
|
|
|
return applied_limit;
|
2015-01-18 08:25:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void BlockStreamProfileInfo::update(Block & block)
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
++blocks;
|
|
|
|
rows += block.rows();
|
|
|
|
bytes += block.bytes();
|
2015-01-18 08:25:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void BlockStreamProfileInfo::collectInfosForStreamsWithName(const char * name, BlockStreamProfileInfos & res) const
|
|
|
|
{
|
2019-04-05 10:52:07 +00:00
|
|
|
if (!parent)
|
|
|
|
return;
|
|
|
|
|
2017-06-26 12:30:35 +00:00
|
|
|
if (parent->getName() == name)
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
|
|
|
res.push_back(this);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-01-23 14:48:50 +00:00
|
|
|
parent->forEachChild([&] (IBlockInputStream & child)
|
2017-06-26 12:30:35 +00:00
|
|
|
{
|
2018-02-23 10:43:24 +00:00
|
|
|
child.getProfileInfo().collectInfosForStreamsWithName(name, res);
|
|
|
|
return false;
|
|
|
|
});
|
2015-01-18 08:25:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void BlockStreamProfileInfo::calculateRowsBeforeLimit() const
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
calculated_rows_before_limit = true;
|
|
|
|
|
|
|
|
/// is there a Limit?
|
|
|
|
BlockStreamProfileInfos limits;
|
|
|
|
collectInfosForStreamsWithName("Limit", limits);
|
|
|
|
|
|
|
|
if (!limits.empty())
|
|
|
|
{
|
|
|
|
applied_limit = true;
|
|
|
|
|
|
|
|
/** Take the number of lines read below `PartialSorting`, if any, or below `Limit`.
|
|
|
|
* This is necessary, because sorting can return only part of the rows.
|
|
|
|
*/
|
|
|
|
BlockStreamProfileInfos partial_sortings;
|
|
|
|
collectInfosForStreamsWithName("PartialSorting", partial_sortings);
|
|
|
|
|
|
|
|
BlockStreamProfileInfos & limits_or_sortings = partial_sortings.empty() ? limits : partial_sortings;
|
|
|
|
|
2017-06-26 12:30:35 +00:00
|
|
|
for (const BlockStreamProfileInfo * info_limit_or_sort : limits_or_sortings)
|
|
|
|
{
|
2019-01-23 14:48:50 +00:00
|
|
|
info_limit_or_sort->parent->forEachChild([&] (IBlockInputStream & child)
|
2017-06-26 12:30:35 +00:00
|
|
|
{
|
2018-02-23 10:43:24 +00:00
|
|
|
rows_before_limit += child.getProfileInfo().rows;
|
|
|
|
return false;
|
|
|
|
});
|
2017-06-26 12:30:35 +00:00
|
|
|
}
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/// Then the data about `rows_before_limit` can be in `RemoteBlockInputStream` (come from a remote server).
|
|
|
|
BlockStreamProfileInfos remotes;
|
|
|
|
collectInfosForStreamsWithName("Remote", remotes);
|
2020-02-18 13:16:30 +00:00
|
|
|
collectInfosForStreamsWithName("TreeExecutor", remotes);
|
2017-04-01 07:20:54 +00:00
|
|
|
|
|
|
|
if (remotes.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (const auto & info : remotes)
|
|
|
|
{
|
|
|
|
if (info->applied_limit)
|
|
|
|
{
|
|
|
|
applied_limit = true;
|
|
|
|
rows_before_limit += info->rows_before_limit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-01-18 08:25:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|