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: public:
typedef T Type; 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() + ">"; } std::string getName() const { return "ColumnConst<" + TypeName<T>::get() + ">"; }
bool isNumeric() const { return IsNumber<T>::value; } bool isNumeric() const { return IsNumber<T>::value; }
size_t sizeOfField() const { return sizeof(T); } size_t sizeOfField() const { return sizeof(T); }
@ -116,7 +116,7 @@ public:
private: private:
size_t s; size_t s;
T data; T data;
DataTypePtr nested_type; /// Только для массивов. DataTypePtr data_type;
}; };
@ -124,13 +124,6 @@ typedef ColumnConst<String> ColumnConstString;
typedef ColumnConst<Array> ColumnConstArray; 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 template <typename T> ColumnPtr ColumnConst<T>::convertToFullColumn() const
{ {
ColumnVector<T> * res = new ColumnVector<T>; ColumnVector<T> * res = new ColumnVector<T>;

View File

@ -31,6 +31,11 @@ public:
{ {
return new DataTypeFixedString(n); return new DataTypeFixedString(n);
} }
size_t getN() const
{
return n;
}
void serializeBinary(const Field & field, WriteBuffer & ostr) const; void serializeBinary(const Field & field, WriteBuffer & ostr) const;
void deserializeBinary(Field & field, ReadBuffer & istr) 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) for (size_t i = 0, size = arguments.size(); i < size; ++i)
arr.push_back((*block.getByPosition(arguments[i]).column)[0]); 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; return true;
} }

View File

@ -436,7 +436,7 @@ public:
{ {
Array const_res; Array const_res;
TimeSlotsImpl<UInt32>::constant_constant(const_starts->getData(), const_durations->getData(), 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 else
throw Exception("Illegal columns " + block.getByPosition(arguments[0]).column->getName() throw Exception("Illegal columns " + block.getByPosition(arguments[0]).column->getName()

View File

@ -339,7 +339,7 @@ public:
cur = Transform::toParent(cur, dict); 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 else
throw Exception("Illegal column " + block.getByPosition(arguments[0]).column->getName() throw Exception("Illegal column " + block.getByPosition(arguments[0]).column->getName()

View File

@ -304,7 +304,7 @@ public:
while (generator.get(token_begin, token_end)) while (generator.get(token_begin, token_end))
dst.push_back(String(token_begin, token_end - token_begin)); 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 else
throw Exception("Illegal columns " + block.getByPosition(arguments.back()).column->getName() throw Exception("Illegal columns " + block.getByPosition(arguments.back()).column->getName()

View File

@ -1,42 +1,76 @@
#include <DB/DataTypes/FieldToDataType.h> #include <DB/DataTypes/FieldToDataType.h>
#include <DB/DataTypes/DataTypeFixedString.h>
#include <DB/Columns/ColumnString.h> #include <DB/Columns/ColumnString.h>
#include <DB/Columns/ColumnConst.h> #include <DB/Columns/ColumnConst.h>
#include <DB/Columns/ColumnFixedString.h>
namespace DB 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 template <> ColumnPtr ColumnConst<String>::convertToFullColumn() const
{ {
ColumnString * res = new ColumnString; if (!data_type || dynamic_cast<const DataTypeString *>(&*data_type))
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)
{ {
memcpy(&vec[offset], data.data(), string_size); ColumnString * res = new ColumnString;
offset += string_size; ColumnPtr res_ptr = res;
offsets[i] = offset; 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 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(); 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 * res = new ColumnArray(nested_column);
ColumnArray::Offsets_t & offsets = res->getOffsets(); 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 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 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());
} }
} }