2010-03-12 18:25:35 +00:00
|
|
|
|
#ifndef DBMS_CORE_COLUMN_TUPLE_H
|
|
|
|
|
#define DBMS_CORE_COLUMN_TUPLE_H
|
|
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
#include <Poco/SharedPtr.h>
|
|
|
|
|
|
|
|
|
|
#include <DB/Core/Exception.h>
|
|
|
|
|
#include <DB/Core/ErrorCodes.h>
|
|
|
|
|
#include <DB/Column/IColumn.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
using Poco::SharedPtr;
|
|
|
|
|
|
|
|
|
|
/** Столбец со значениями-кортежами.
|
|
|
|
|
*/
|
2010-05-13 16:13:38 +00:00
|
|
|
|
class ColumnTuple : public IColumn
|
2010-03-12 18:25:35 +00:00
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
typedef std::vector<SharedPtr<IColumn> > Container_t;
|
|
|
|
|
Container_t data;
|
|
|
|
|
|
|
|
|
|
/// убедиться в том, что размеры столбцов-элементов совпадают.
|
|
|
|
|
void checkSizes() const
|
|
|
|
|
{
|
|
|
|
|
if (data.empty())
|
|
|
|
|
throw Exception("Empty tuple", ErrorCodes::EMPTY_TUPLE);
|
|
|
|
|
|
|
|
|
|
size_t size = data[0]->size();
|
|
|
|
|
for (size_t i = 1; i < data.size(); ++i)
|
|
|
|
|
if (data[i]->size() != size)
|
|
|
|
|
throw Exception("Sizes of columns (elements of tuple column) doesn't match",
|
|
|
|
|
ErrorCodes::SIZES_OF_COLUMNS_IN_TUPLE_DOESNT_MATCH);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
ColumnTuple(const Container_t & data_)
|
|
|
|
|
: data(data_)
|
|
|
|
|
{
|
|
|
|
|
checkSizes();
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-21 19:52:50 +00:00
|
|
|
|
SharedPtr<IColumn> cloneEmpty() const
|
|
|
|
|
{
|
|
|
|
|
Container_t new_data(data.size());
|
|
|
|
|
for (size_t i = 0; i < data.size(); ++i)
|
|
|
|
|
new_data[i] = data[i]->cloneEmpty();
|
|
|
|
|
|
|
|
|
|
return new ColumnTuple(new_data);
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-12 18:25:35 +00:00
|
|
|
|
size_t size() const
|
|
|
|
|
{
|
|
|
|
|
return data[0]->size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Field operator[](size_t n) const
|
|
|
|
|
{
|
|
|
|
|
Array res = Array(data.size());
|
|
|
|
|
for (size_t i = 0; i < data.size(); ++i)
|
|
|
|
|
res[i] = (*data[i])[n];
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void cut(size_t start, size_t length)
|
|
|
|
|
{
|
|
|
|
|
for (size_t i = 0; i < data.size(); ++i)
|
|
|
|
|
data[i]->cut(start, length);
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-20 19:29:04 +00:00
|
|
|
|
void insert(const Field & x)
|
|
|
|
|
{
|
|
|
|
|
Array & arr = boost::get<Array &>(x);
|
|
|
|
|
if (arr.size() != data.size())
|
|
|
|
|
throw Exception("Sizes of columns in tuple doesn't match", ErrorCodes::SIZES_OF_COLUMNS_IN_TUPLE_DOESNT_MATCH);
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < data.size(); ++i)
|
|
|
|
|
data[i]->insert(arr[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void insertDefault()
|
|
|
|
|
{
|
|
|
|
|
for (size_t i = 0; i < data.size(); ++i)
|
|
|
|
|
data[i]->insertDefault();
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-13 16:13:38 +00:00
|
|
|
|
void clear()
|
|
|
|
|
{
|
|
|
|
|
data.clear();
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-12 18:25:35 +00:00
|
|
|
|
/// манипуляция с Tuple
|
|
|
|
|
|
|
|
|
|
void insertColumn(size_t pos, SharedPtr<IColumn> & column)
|
|
|
|
|
{
|
|
|
|
|
if (pos > data.size())
|
|
|
|
|
throw Exception("Position out of bound in ColumnTuple::insertColumn().",
|
|
|
|
|
ErrorCodes::POSITION_OUT_OF_BOUND);
|
|
|
|
|
|
|
|
|
|
data.insert(data.begin() + pos, column);
|
|
|
|
|
checkSizes();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void eraseColumn(size_t pos)
|
|
|
|
|
{
|
|
|
|
|
if (data.size() == 1)
|
|
|
|
|
throw Exception("Empty tuple", ErrorCodes::EMPTY_TUPLE);
|
|
|
|
|
|
|
|
|
|
if (pos >= data.size())
|
|
|
|
|
throw Exception("Position out of bound in ColumnTuple::eraseColumn().",
|
|
|
|
|
ErrorCodes::POSITION_OUT_OF_BOUND);
|
|
|
|
|
|
|
|
|
|
data.erase(data.begin() + pos);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|