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

170 lines
4.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <DB/DataTypes/IDataType.h>
#include <DB/Columns/ColumnTuple.h>
#include <DB/Columns/ColumnConst.h>
namespace DB
{
/** Тип данных - кортеж.
* Используется как промежуточный результат при вычислении выражений.
* Также может быть использовать в качестве столбца - результата выполнения запроса.
* Не может быть сохранён в таблицы.
*/
class DataTypeTuple : public IDataType
{
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();
}
SharedPtr<IDataType> clone() const { return new DataTypeTuple(elems); }
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;
}
const DataTypes & getElements() const { return elems; }
};
}