#include #include namespace DB { using Poco::SharedPtr; LimitBlockInputStream::LimitBlockInputStream(SharedPtr input_, size_t limit_, size_t offset_) : input(input_), limit(limit_), offset(offset_), pos(0) { } Block LimitBlockInputStream::read() { Block res; size_t rows = 0; /// pos - сколько строк было прочитано, включая последний прочитанный блок if (pos >= offset + limit) return res; do { res = input->read(); rows = res.rows(); pos += rows; } while (pos <= offset); /// отдать целый блок if (pos >= offset + rows && pos <= offset + limit) return res; /// отдать кусок блока size_t start = std::max( static_cast(0), static_cast(offset) - static_cast(pos) + static_cast(rows)); size_t length = std::min( static_cast(limit), std::min( static_cast(pos) - static_cast(offset), static_cast(limit) + static_cast(offset) - static_cast(pos) + static_cast(rows))); for (size_t i = 0; i < res.columns(); ++i) res.getByPosition(i).column->cut(start, length); return res; } }