ClickHouse/dbms/include/DB/DataTypes/DataTypeTuple.h

170 lines
4.9 KiB
C
Raw Normal View History

2012-08-23 18:43:57 +00:00
#pragma once
#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
{
/** Тип данных - кортеж.
* Используется как промежуточный результат при вычислении выражений.
* Также может быть использовать в качестве столбца - результата выполнения запроса.
* Не может быть сохранён в таблицы.
2012-08-23 18:43:57 +00:00
*/
class DataTypeTuple : public IDataType
2012-08-23 18:43:57 +00:00
{
private:
DataTypes elems;
public:
DataTypeTuple(DataTypes elems_) : elems(elems_) {}
2012-08-23 18:43:57 +00:00
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 << ")";
2012-08-23 18:43:57 +00:00
return s.str();
}
2012-08-23 18:43:57 +00:00
SharedPtr<IDataType> clone() const { return new DataTypeTuple(elems); }
2012-08-26 02:08:18 +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, double avg_value_size_hint) 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, avg_value_size_hint);
}
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
};
}