This commit is contained in:
Michael Kolupaev 2013-03-27 10:07:23 +00:00
parent 3ae8c09e54
commit 0f94ab34bf
10 changed files with 70 additions and 37 deletions

View File

@ -32,10 +32,10 @@ class ColumnConst : public IColumnConst
public:
typedef T Type;
ColumnConst(size_t s_, const T & data_);
/// Для ColumnConst<Array> data_type_ должен быть ненулевым.
/// Для ColumnConst<String> data_type_ должен быть ненулевым, если тип данных FixedString.
ColumnConst(size_t s_, const T & data_, DataTypePtr data_type_ = DataTypePtr()) : s(s_), data(data_), data_type(data_type_) {}
ColumnConst(size_t s_, const T & data_, DataTypePtr nested_type_);
std::string getName() const { return "ColumnConst<" + TypeName<T>::get() + ">"; }
bool isNumeric() const { return IsNumber<T>::value; }
size_t sizeOfField() const { return sizeof(T); }
@ -116,7 +116,7 @@ public:
private:
size_t s;
T data;
DataTypePtr nested_type; /// Только для массивов.
DataTypePtr data_type;
};
@ -124,13 +124,6 @@ typedef ColumnConst<String> ColumnConstString;
typedef ColumnConst<Array> ColumnConstArray;
template <typename T> ColumnConst<T>::ColumnConst(size_t s_, const T & data_) : s(s_), data(data_) {}
template <typename T> ColumnConst<T>::ColumnConst(size_t s_, const T & data_, DataTypePtr nested_type_) { throw Exception("Can't create non-array ColumnConst with nested type", ErrorCodes::LOGICAL_ERROR); }
template <> ColumnConst<Array>::ColumnConst(size_t s_, const Array & data_);
template <> ColumnConst<Array>::ColumnConst(size_t s_, const Array & data_, DataTypePtr nested_type_);
template <typename T> ColumnPtr ColumnConst<T>::convertToFullColumn() const
{
ColumnVector<T> * res = new ColumnVector<T>;

View File

@ -31,6 +31,11 @@ public:
{
return new DataTypeFixedString(n);
}
size_t getN() const
{
return n;
}
void serializeBinary(const Field & field, WriteBuffer & ostr) const;
void deserializeBinary(Field & field, ReadBuffer & istr) const;

View File

@ -54,7 +54,7 @@ public:
for (size_t i = 0, size = arguments.size(); i < size; ++i)
arr.push_back((*block.getByPosition(arguments[i]).column)[0]);
block.getByPosition(result).column = new ColumnConstArray(block.getByPosition(arguments[0]).column->size(), arr, block.getByPosition(arguments[0]).type);
block.getByPosition(result).column = new ColumnConstArray(block.getByPosition(arguments[0]).column->size(), arr, new DataTypeArray(block.getByPosition(arguments[0]).type));
}
};

View File

@ -601,7 +601,7 @@ public:
}
}
out_column = new ColumnConstArray(col_from->size(), res, new typename DataTypeFromFieldType<T>::Type);
out_column = new ColumnConstArray(col_from->size(), res, new DataTypeArray(new typename DataTypeFromFieldType<T>::Type));
return true;
}

View File

@ -436,7 +436,7 @@ public:
{
Array const_res;
TimeSlotsImpl<UInt32>::constant_constant(const_starts->getData(), const_durations->getData(), const_res);
block.getByPosition(result).column = new ColumnConstArray(block.getByPosition(0).column->size(), const_res, new DataTypeDateTime);
block.getByPosition(result).column = new ColumnConstArray(block.getByPosition(0).column->size(), const_res, new DataTypeArray(new DataTypeDateTime));
}
else
throw Exception("Illegal columns " + block.getByPosition(arguments[0]).column->getName()

View File

@ -339,7 +339,7 @@ public:
cur = Transform::toParent(cur, dict);
}
block.getByPosition(result).column = new ColumnConstArray(col_from->size(), res, new typename DataTypeFromFieldType<T>::Type);
block.getByPosition(result).column = new ColumnConstArray(col_from->size(), res, new DataTypeArray(new typename DataTypeFromFieldType<T>::Type));
}
else
throw Exception("Illegal column " + block.getByPosition(arguments[0]).column->getName()

View File

@ -304,7 +304,7 @@ public:
while (generator.get(token_begin, token_end))
dst.push_back(String(token_begin, token_end - token_begin));
block.getByPosition(result).column = new ColumnConstArray(col_const_str->size(), dst, new DataTypeString);
block.getByPosition(result).column = new ColumnConstArray(col_const_str->size(), dst, new DataTypeArray(new DataTypeString));
}
else
throw Exception("Illegal columns " + block.getByPosition(arguments.back()).column->getName()

View File

@ -1,42 +1,76 @@
#include <DB/DataTypes/FieldToDataType.h>
#include <DB/DataTypes/DataTypeFixedString.h>
#include <DB/Columns/ColumnString.h>
#include <DB/Columns/ColumnConst.h>
#include <DB/Columns/ColumnFixedString.h>
namespace DB
{
template <> ColumnConst<Array>::ColumnConst(size_t s_, const Array & data_) { throw Exception("Can't create ColumnConst<Array> without nested type", ErrorCodes::LOGICAL_ERROR); }
template <> ColumnConst<Array>::ColumnConst(size_t s_, const Array & data_, DataTypePtr nested_type_) : s(s_), data(data_), nested_type(nested_type_) {}
template <> ColumnPtr ColumnConst<String>::convertToFullColumn() const
{
ColumnString * res = new ColumnString;
ColumnString::Offsets_t & offsets = res->getOffsets();
ColumnUInt8::Container_t & vec = dynamic_cast<ColumnVector<UInt8> &>(res->getData()).getData();
size_t string_size = data.size() + 1;
size_t offset = 0;
offsets.resize(s);
vec.resize(s * string_size);
for (size_t i = 0; i < s; ++i)
if (!data_type || dynamic_cast<const DataTypeString *>(&*data_type))
{
memcpy(&vec[offset], data.data(), string_size);
offset += string_size;
offsets[i] = offset;
}
ColumnString * res = new ColumnString;
ColumnPtr res_ptr = res;
ColumnString::Offsets_t & offsets = res->getOffsets();
ColumnUInt8::Container_t & vec = dynamic_cast<ColumnVector<UInt8> &>(res->getData()).getData();
return res;
size_t string_size = data.size() + 1;
size_t offset = 0;
offsets.resize(s);
vec.resize(s * string_size);
for (size_t i = 0; i < s; ++i)
{
memcpy(&vec[offset], data.data(), string_size);
offset += string_size;
offsets[i] = offset;
}
return res_ptr;
}
else if (const DataTypeFixedString * type = dynamic_cast<const DataTypeFixedString *>(&*data_type))
{
size_t n = type->getN();
if (data.size() > n)
throw Exception("Too long value for " + type->getName(), ErrorCodes::TOO_LARGE_STRING_SIZE);
ColumnFixedString * res = new ColumnFixedString(n);
ColumnPtr res_ptr = res;
ColumnUInt8::Container_t & vec = dynamic_cast<ColumnVector<UInt8> &>(res->getData()).getData();
vec.resize(n * s, 0);
size_t offset = 0;
for (size_t i = 0; i < s; ++i)
{
memcpy(&vec[offset], data.data(), data.size());
offset += n;
}
return res_ptr;
}
else
throw Exception("Invalid data type in ColumnConstString: " + data_type->getName(), ErrorCodes::LOGICAL_ERROR);
}
template <> ColumnPtr ColumnConst<Array>::convertToFullColumn() const
{
if (!data_type)
throw Exception("No data type specified for ColumnConstArray", ErrorCodes::LOGICAL_ERROR);
const DataTypeArray * type = dynamic_cast<const DataTypeArray *>(&*data_type);
if (!type)
throw Exception("Non-array data type specified for ColumnConstArray", ErrorCodes::LOGICAL_ERROR);
size_t array_size = data.size();
ColumnPtr nested_column = nested_type->createColumn();
ColumnPtr nested_column = type->getNestedType()->createColumn();
ColumnArray * res = new ColumnArray(nested_column);
ColumnArray::Offsets_t & offsets = res->getOffsets();

View File

@ -179,7 +179,8 @@ ColumnPtr DataTypeArray::createColumn() const
ColumnPtr DataTypeArray::createConstColumn(size_t size, const Field & field) const
{
return new ColumnConst<Array>(size, get<const Array &>(field), nested);
/// Последним аргументом нельзя отдать this.
return new ColumnConstArray(size, get<const Array &>(field), new DataTypeArray(nested));
}
}

View File

@ -116,7 +116,7 @@ ColumnPtr DataTypeFixedString::createColumn() const
ColumnPtr DataTypeFixedString::createConstColumn(size_t size, const Field & field) const
{
return new ColumnConst<String>(size, get<const String &>(field));
return new ColumnConstString(size, get<const String &>(field), clone());
}
}