diff --git a/dbms/include/DB/Core/Block.h b/dbms/include/DB/Core/Block.h index e2ac32e1365..f2d317ccc60 100644 --- a/dbms/include/DB/Core/Block.h +++ b/dbms/include/DB/Core/Block.h @@ -6,6 +6,8 @@ #include #include +#include +#include namespace DB @@ -31,7 +33,11 @@ private: void rebuildIndexByPosition(); public: + /// вставить столбец в заданную позицию void insert(size_t position, const ColumnWithNameAndType & elem); + /// вставить столбец в конец + void insert(const ColumnWithNameAndType & elem); + /// удалить столбец в заданной позиции void erase(size_t position); ColumnWithNameAndType & getByPosition(size_t position); diff --git a/dbms/include/DB/Core/Column.h b/dbms/include/DB/Core/Column.h index 0012f22ceae..8002458fe9b 100644 --- a/dbms/include/DB/Core/Column.h +++ b/dbms/include/DB/Core/Column.h @@ -5,7 +5,6 @@ #include #include -#include #include #include @@ -47,36 +46,6 @@ typedef boost::make_recursive_variant< typedef std::vector TupleColumn; /// Столбец значений типа "кортеж" - несколько столбцов произвольного типа typedef std::vector ArrayColumn; /// Столбец значений типа "массив" - столбец, значения в котором - массивы - -/** Возвращает количество значений в столбце - * TODO: поправить для tuple. - */ -class ColumnVisitorSize : public boost::static_visitor -{ -public: - template size_t operator() (const T & x) const { return x.size(); } -}; - - -/** Возвращает n-ый элемент столбца. - * TODO: поправить для tuple. - */ -class ColumnVisitorNthElement : public boost::static_visitor -{ -public: - ColumnVisitorNthElement(size_t n_) : n(n_) {} - - template Field operator() (const T & x) const - { - return x.size() == 1 - ? x[0] /// столбец - константа - : x[n]; - } -private: - size_t n; -}; - - } #endif diff --git a/dbms/include/DB/Core/ColumnTypeToFieldType.h b/dbms/include/DB/Core/ColumnTypeToFieldType.h new file mode 100644 index 00000000000..cb920ea4e7c --- /dev/null +++ b/dbms/include/DB/Core/ColumnTypeToFieldType.h @@ -0,0 +1,33 @@ +#ifndef DBMS_CORE_COLUMN_TYPE_TO_FIELD_TYPE_H +#define DBMS_CORE_COLUMN_TYPE_TO_FIELD_TYPE_H + +#include +#include + + +namespace DB +{ + +/** Переводит типы, использующиеся в Column в типы, использующиеся в Field + */ +template struct ColumnTypeToFieldType; + +template <> struct ColumnTypeToFieldType { typedef UInt64 Type; }; +template <> struct ColumnTypeToFieldType { typedef UInt64 Type; }; +template <> struct ColumnTypeToFieldType { typedef UInt64 Type; }; +template <> struct ColumnTypeToFieldType { typedef UInt64 Type; }; + +template <> struct ColumnTypeToFieldType { typedef Int64 Type; }; +template <> struct ColumnTypeToFieldType { typedef Int64 Type; }; +template <> struct ColumnTypeToFieldType { typedef Int64 Type; }; +template <> struct ColumnTypeToFieldType { typedef Int64 Type; }; + +template <> struct ColumnTypeToFieldType { typedef Float64 Type; }; +template <> struct ColumnTypeToFieldType { typedef Float64 Type; }; + +template <> struct ColumnTypeToFieldType { typedef String Type; }; +template <> struct ColumnTypeToFieldType { typedef Field Type; }; + +} + +#endif diff --git a/dbms/include/DB/Core/ColumnVisitors.h b/dbms/include/DB/Core/ColumnVisitors.h new file mode 100644 index 00000000000..240cb23abc2 --- /dev/null +++ b/dbms/include/DB/Core/ColumnVisitors.h @@ -0,0 +1,53 @@ +#ifndef DBMS_CORE_COLUMN_VISITORS_H +#define DBMS_CORE_COLUMN_VISITORS_H + +#include + +#include +#include +#include + + +namespace DB +{ + + +/** Возвращает количество значений в столбце + * TODO: поправить для tuple. + */ +class ColumnVisitorSize : public boost::static_visitor +{ +public: + template size_t operator() (const T & x) const { return x.size(); } +}; + + +/** Возвращает n-ый элемент столбца. + * TODO: поправить для tuple. + */ +class ColumnVisitorNthElement : public boost::static_visitor +{ +public: + ColumnVisitorNthElement(size_t n_) : n(n_) {} + + template Field operator() (const T & x) const + { + return typename ColumnTypeToFieldType::Type( + x.size() == 1 + ? x[0] /// столбец - константа + : x[n]); + } + + Field operator() (const TupleColumn & x) const + { + return UInt64(0); /// заглушка + } + +private: + size_t n; +}; + + +} + +#endif diff --git a/dbms/include/DB/Core/ErrorCodes.h b/dbms/include/DB/Core/ErrorCodes.h index 65f865a5e1c..7cb5339e528 100644 --- a/dbms/include/DB/Core/ErrorCodes.h +++ b/dbms/include/DB/Core/ErrorCodes.h @@ -19,6 +19,7 @@ namespace ErrorCodes SIZES_OF_COLUMNS_DOESNT_MATCH, EMPTY_COLUMN_IN_BLOCK, NOT_FOUND_COLUMN_IN_BLOCK, + POSITION_OUT_OF_BOUND, }; } diff --git a/dbms/src/Core/Block.cpp b/dbms/src/Core/Block.cpp index 9ba2f1a5cbb..47a7c1bcca4 100644 --- a/dbms/src/Core/Block.cpp +++ b/dbms/src/Core/Block.cpp @@ -1,5 +1,6 @@ #include #include +#include #include @@ -18,14 +19,28 @@ void Block::rebuildIndexByPosition() void Block::insert(size_t position, const ColumnWithNameAndType & elem) { + if (position >= index_by_position.size()) + throw Exception("Position out of bound in Block::insert()", ErrorCodes::POSITION_OUT_OF_BOUND); + Container_t::iterator it = data.insert(index_by_position[position], elem); rebuildIndexByPosition(); index_by_name[elem.name] = it; } +void Block::insert(const ColumnWithNameAndType & elem) +{ + Container_t::iterator it = data.insert(data.end(), elem); + rebuildIndexByPosition(); + index_by_name[elem.name] = it; +} + + void Block::erase(size_t position) { + if (position >= index_by_position.size()) + throw Exception("Position out of bound in Block::erase()", ErrorCodes::POSITION_OUT_OF_BOUND); + Container_t::iterator it = index_by_position[position]; index_by_name.erase(index_by_name.find(it->name)); data.erase(it); diff --git a/dbms/src/DataStreams/RowInputStreamFromBlockInputStream.cpp b/dbms/src/DataStreams/RowInputStreamFromBlockInputStream.cpp index 00438213230..9bef7ec258b 100644 --- a/dbms/src/DataStreams/RowInputStreamFromBlockInputStream.cpp +++ b/dbms/src/DataStreams/RowInputStreamFromBlockInputStream.cpp @@ -1,5 +1,6 @@ -#include +#include +#include namespace DB { @@ -12,19 +13,10 @@ RowInputStreamFromBlockInputStream::RowInputStreamFromBlockInputStream(IBlockInp { } -class TestVisitor : public boost::static_visitor -{ -public: - template UInt64 operator() (const T & x) const - { - return 0; - } -}; - Row RowInputStreamFromBlockInputStream::read() { -/* if (pos >= current_rows) + if (pos >= current_rows) { current_block = block_input.read(); current_rows = current_block.rows(); @@ -38,13 +30,7 @@ Row RowInputStreamFromBlockInputStream::read() for (size_t i = 0; i < columns; ++i) row[i] = boost::apply_visitor(visitor, *current_block.getByPosition(i).column); - return row; -*/ - - Column column = UInt64Column(0); - Field field = boost::apply_visitor(TestVisitor(), column); - - Row row; + ++pos; return row; } diff --git a/dbms/src/Storages/StorageSystemNumbers.cpp b/dbms/src/Storages/StorageSystemNumbers.cpp index ec1d1b97aff..ebda8160f2c 100644 --- a/dbms/src/Storages/StorageSystemNumbers.cpp +++ b/dbms/src/Storages/StorageSystemNumbers.cpp @@ -20,7 +20,7 @@ NumbersBlockInputStream::NumbersBlockInputStream(size_t block_size_) : block_siz Block NumbersBlockInputStream::read() { Block res; - res.insert(0, ColumnWithNameAndType()); + 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 ColumnTypeUInt64(); diff --git a/dbms/src/Storages/tests/system_numbers.cpp b/dbms/src/Storages/tests/system_numbers.cpp index bca167ea652..5107f0bc434 100644 --- a/dbms/src/Storages/tests/system_numbers.cpp +++ b/dbms/src/Storages/tests/system_numbers.cpp @@ -12,18 +12,26 @@ using Poco::SharedPtr; int main(int argc, char ** argv) { - DB::StorageSystemNumbers table; + try + { + DB::StorageSystemNumbers table; - DB::ColumnNames column_names; - column_names.push_back("numbers"); + DB::ColumnNames column_names; + column_names.push_back("number"); - Poco::SharedPtr column_types; - column_types->push_back(new DB::ColumnTypeUInt64); - - SharedPtr input = table.read(column_names, 0); - DB::TabSeparatedRowOutputStream output(std::cout, column_types); - - DB::copyData(*input, output); + Poco::SharedPtr column_types = new DB::ColumnTypes; + column_types->push_back(new DB::ColumnTypeUInt64); + + SharedPtr input = table.read(column_names, 0); + DB::TabSeparatedRowOutputStream output(std::cout, column_types); + + DB::copyData(*input, output); + } + catch (const DB::Exception & e) + { + std::cerr << e.what() << ", " << e.message() << std::endl; + return 1; + } return 0; }