diff --git a/dbms/include/DB/Core/Block.h b/dbms/include/DB/Core/Block.h index f2d317ccc60..9657b25ee1e 100644 --- a/dbms/include/DB/Core/Block.h +++ b/dbms/include/DB/Core/Block.h @@ -33,6 +33,12 @@ private: void rebuildIndexByPosition(); public: + Block() {} + + /// нужны, чтобы правильно скопировались индексы + Block(const Block & other); + Block & operator= (const Block & other); + /// вставить столбец в заданную позицию void insert(size_t position, const ColumnWithNameAndType & elem); /// вставить столбец в конец diff --git a/dbms/src/Core/Block.cpp b/dbms/src/Core/Block.cpp index 79af8bd1931..f6d338322b0 100644 --- a/dbms/src/Core/Block.cpp +++ b/dbms/src/Core/Block.cpp @@ -1,3 +1,5 @@ +#include + #include #include @@ -7,6 +9,29 @@ namespace DB { + +Block::Block(const Block & other) +{ + *this = other; +} + + +Block & Block::operator= (const Block & other) +{ + data = other.data; + rebuildIndexByPosition(); + + for (IndexByName_t::const_iterator it = other.index_by_name.begin(); it != other.index_by_name.end(); ++it) + { + Container_t::iterator value = data.begin(); + std::advance(value, std::distance(const_cast(other).data.begin(), it->second)); + index_by_name[it->first] = value; + } + + return *this; +} + + void Block::rebuildIndexByPosition() { index_by_position.resize(data.size()); diff --git a/dbms/src/DataStreams/LimitBlockInputStream.cpp b/dbms/src/DataStreams/LimitBlockInputStream.cpp index 5481f285164..8fec7e82ae4 100644 --- a/dbms/src/DataStreams/LimitBlockInputStream.cpp +++ b/dbms/src/DataStreams/LimitBlockInputStream.cpp @@ -19,26 +19,30 @@ Block LimitBlockInputStream::read() Block res; size_t rows = 0; + /// pos - сколько строк было прочитано, включая последний прочитанный блок + if (pos >= offset + limit) return res; - while (pos + rows <= offset) + do { res = input->read(); + res.getByPosition(0); rows = res.rows(); pos += rows; - } + } while (pos <= offset); - if (pos >= offset && pos + rows <= offset + limit) - { - pos += rows; + /// отдать целый блок + if (pos >= offset + rows && pos <= offset + limit) return res; - } - /// блок, от которого надо выбрать кусок + /// отдать кусок блока + size_t start = std::max(0, static_cast(offset) + static_cast(rows) - static_cast(pos)); + size_t length = std::min(rows - start, limit + offset + rows - pos); + for (size_t i = 0; i < res.columns(); ++i) - res.getByPosition(i).column->cut(std::max(0, static_cast(offset) - static_cast(pos)), limit); - pos += rows; + res.getByPosition(i).column->cut(start, length); + return res; } diff --git a/dbms/src/DataStreams/RowInputStreamFromBlockInputStream.cpp b/dbms/src/DataStreams/RowInputStreamFromBlockInputStream.cpp index b8a9e0d861c..3b545c65c6f 100644 --- a/dbms/src/DataStreams/RowInputStreamFromBlockInputStream.cpp +++ b/dbms/src/DataStreams/RowInputStreamFromBlockInputStream.cpp @@ -1,5 +1,6 @@ #include + namespace DB { diff --git a/dbms/src/Storages/StorageSystemNumbers.cpp b/dbms/src/Storages/StorageSystemNumbers.cpp index f59b1290746..93c863d8646 100644 --- a/dbms/src/Storages/StorageSystemNumbers.cpp +++ b/dbms/src/Storages/StorageSystemNumbers.cpp @@ -22,7 +22,9 @@ Block NumbersBlockInputStream::read() { Block res; res.insert(ColumnWithNameAndType()); + ColumnWithNameAndType & column_with_name_and_type = res.getByPosition(0); + column_with_name_and_type.name = "number"; column_with_name_and_type.type = new DataTypeUInt64(); ColumnUInt64 * column = new ColumnUInt64(block_size); @@ -31,7 +33,7 @@ Block NumbersBlockInputStream::read() for (size_t i = 0; i < block_size; ++i) vec[i] = next++; - + return res; } diff --git a/dbms/src/Storages/tests/system_numbers.cpp b/dbms/src/Storages/tests/system_numbers.cpp index 83b55faf1d6..20e58a9a5bf 100644 --- a/dbms/src/Storages/tests/system_numbers.cpp +++ b/dbms/src/Storages/tests/system_numbers.cpp @@ -23,7 +23,7 @@ int main(int argc, char ** argv) Poco::SharedPtr column_types = new DB::DataTypes; column_types->push_back(new DB::DataTypeUInt64); - DB::LimitBlockInputStream input(table.read(column_names, 0, 10), 100, 100); + DB::LimitBlockInputStream input(table.read(column_names, 0, 10), 10, 96); DB::TabSeparatedRowOutputStream output(std::cout, column_types); DB::copyData(input, output);