2012-08-23 18:43:57 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
2013-10-26 19:00:13 +00:00
|
|
|
|
#include <DB/DataTypes/IDataType.h>
|
|
|
|
|
#include <DB/Columns/ColumnTuple.h>
|
|
|
|
|
#include <DB/Columns/ColumnConst.h>
|
2012-08-23 18:43:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/** Тип данных - кортеж.
|
2013-10-26 19:00:13 +00:00
|
|
|
|
* Используется как промежуточный результат при вычислении выражений.
|
|
|
|
|
* Также может быть использовать в качестве столбца - результата выполнения запроса.
|
|
|
|
|
* Не может быть сохранён в таблицы.
|
2012-08-23 18:43:57 +00:00
|
|
|
|
*/
|
2013-10-26 19:00:13 +00:00
|
|
|
|
class DataTypeTuple : public IDataType
|
2012-08-23 18:43:57 +00:00
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
DataTypes elems;
|
|
|
|
|
public:
|
|
|
|
|
DataTypeTuple(DataTypes elems_) : elems(elems_) {}
|
|
|
|
|
|
|
|
|
|
std::string getName() const
|
|
|
|
|
{
|
|
|
|
|
std::stringstream s;
|
|
|
|
|
|
|
|
|
|
s << "Tuple(";
|
|
|
|
|
for (DataTypes::const_iterator it = elems.begin(); it != elems.end(); ++it)
|
|
|
|
|
s << (it == elems.begin() ? "" : ", ") << (*it)->getName();
|
|
|
|
|
s << ")";
|
|
|
|
|
|
|
|
|
|
return s.str();
|
|
|
|
|
}
|
2013-10-26 19:00:13 +00:00
|
|
|
|
|
2012-08-23 18:43:57 +00:00
|
|
|
|
SharedPtr<IDataType> clone() const { return new DataTypeTuple(elems); }
|
2012-08-26 02:08:18 +00:00
|
|
|
|
|
2013-10-26 19:00:13 +00:00
|
|
|
|
void serializeBinary(const Field & field, WriteBuffer & ostr) const
|
|
|
|
|
{
|
|
|
|
|
const Array & arr = get<const Array &>(field);
|
|
|
|
|
for (size_t i = 0, size = elems.size(); i < size; ++i)
|
|
|
|
|
elems[i]->serializeBinary(arr[i], ostr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void deserializeBinary(Field & field, ReadBuffer & istr) const
|
|
|
|
|
{
|
|
|
|
|
size_t size = elems.size();
|
|
|
|
|
field = Array(size);
|
|
|
|
|
Array & arr = get<Array &>(field);
|
|
|
|
|
for (size_t i = 0; i < size; ++i)
|
|
|
|
|
elems[i]->deserializeBinary(arr[i], istr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void serializeText(const Field & field, WriteBuffer & ostr) const
|
|
|
|
|
{
|
|
|
|
|
const Array & arr = get<const Array &>(field);
|
|
|
|
|
writeChar('(', ostr);
|
|
|
|
|
for (size_t i = 0, size = elems.size(); i < size; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (i != 0)
|
|
|
|
|
writeChar(',', ostr);
|
|
|
|
|
elems[i]->serializeTextQuoted(arr[i], ostr);
|
|
|
|
|
}
|
|
|
|
|
writeChar(')', ostr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void deserializeText(Field & field, ReadBuffer & istr) const
|
|
|
|
|
{
|
|
|
|
|
size_t size = elems.size();
|
|
|
|
|
field = Array(size);
|
|
|
|
|
Array & arr = get<Array &>(field);
|
|
|
|
|
assertString("(", istr);
|
|
|
|
|
for (size_t i = 0; i < size; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (i != 0)
|
|
|
|
|
assertString(",", istr);
|
|
|
|
|
elems[i]->deserializeTextQuoted(arr[i], istr);
|
|
|
|
|
}
|
|
|
|
|
assertString(")", istr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void serializeTextEscaped(const Field & field, WriteBuffer & ostr) const
|
|
|
|
|
{
|
|
|
|
|
serializeText(field, ostr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void deserializeTextEscaped(Field & field, ReadBuffer & istr) const
|
|
|
|
|
{
|
|
|
|
|
deserializeText(field, istr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void serializeTextQuoted(const Field & field, WriteBuffer & ostr) const
|
|
|
|
|
{
|
|
|
|
|
serializeText(field, ostr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void deserializeTextQuoted(Field & field, ReadBuffer & istr) const
|
|
|
|
|
{
|
|
|
|
|
deserializeText(field, istr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void serializeTextJSON(const Field & field, WriteBuffer & ostr) const
|
|
|
|
|
{
|
|
|
|
|
const Array & arr = get<const Array &>(field);
|
|
|
|
|
writeChar('[', ostr);
|
|
|
|
|
for (size_t i = 0, size = elems.size(); i < size; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (i != 0)
|
|
|
|
|
writeChar(',', ostr);
|
|
|
|
|
elems[i]->serializeTextJSON(arr[i], ostr);
|
|
|
|
|
}
|
|
|
|
|
writeChar(']', ostr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void serializeBinary(const IColumn & column, WriteBuffer & ostr, size_t offset = 0, size_t limit = 0) const
|
|
|
|
|
{
|
|
|
|
|
const ColumnTuple & real_column = static_cast<const ColumnTuple &>(column);
|
|
|
|
|
for (size_t i = 0, size = elems.size(); i < size; ++i)
|
|
|
|
|
{
|
|
|
|
|
const IColumn & nested_column = *real_column.getData().getByPosition(i).column;
|
|
|
|
|
|
|
|
|
|
if (nested_column.isConst())
|
|
|
|
|
elems[i]->serializeBinary(*static_cast<const IColumnConst &>(nested_column).convertToFullColumn(), ostr, offset, limit);
|
|
|
|
|
else
|
|
|
|
|
elems[i]->serializeBinary(nested_column, ostr, offset, limit);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** limit обязательно должен быть в точности равен количеству сериализованных значений.
|
|
|
|
|
* Именно из-за этого (невозможности читать меньший кусок записанных данных), Tuple не могут быть использованы для хранения данных в таблицах.
|
|
|
|
|
* (Хотя могут быть использованы для передачи данных по сети в Native формате.)
|
|
|
|
|
*/
|
|
|
|
|
void deserializeBinary(IColumn & column, ReadBuffer & istr, size_t limit) const
|
|
|
|
|
{
|
|
|
|
|
ColumnTuple & real_column = static_cast<ColumnTuple &>(column);
|
|
|
|
|
for (size_t i = 0, size = elems.size(); i < size; ++i)
|
|
|
|
|
elems[i]->deserializeBinary(*real_column.getData().getByPosition(i).column, istr, limit);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ColumnPtr createColumn() const
|
|
|
|
|
{
|
|
|
|
|
Block tuple_block;
|
|
|
|
|
for (size_t i = 0, size = elems.size(); i < size; ++i)
|
|
|
|
|
{
|
|
|
|
|
ColumnWithNameAndType col;
|
|
|
|
|
col.column = elems[i]->createColumn();
|
|
|
|
|
tuple_block.insert(col);
|
|
|
|
|
}
|
|
|
|
|
return new ColumnTuple(tuple_block);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ColumnPtr createConstColumn(size_t size, const Field & field) const
|
|
|
|
|
{
|
|
|
|
|
return new ColumnConstArray(size, get<const Array &>(field), new DataTypeTuple(elems));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Field getDefault() const
|
|
|
|
|
{
|
|
|
|
|
size_t size = elems.size();
|
|
|
|
|
Array res(size);
|
|
|
|
|
for (size_t i = 0; i < size; ++i)
|
|
|
|
|
res[i] = elems[i]->getDefault();
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-26 02:08:18 +00:00
|
|
|
|
const DataTypes & getElements() const { return elems; }
|
2012-08-23 18:43:57 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|