提交 7a4eb6a4 编写于 作者: A Alexey Milovidov

Merge

......@@ -10,8 +10,8 @@ namespace DB
template <typename FieldType> struct EnumName;
template <> struct EnumName<UInt8> { static constexpr auto value = "Enum8"; };
template <> struct EnumName<UInt16> { static constexpr auto value = "Enum16"; };
template <> struct EnumName<Int8> { static constexpr auto value = "Enum8"; };
template <> struct EnumName<Int16> { static constexpr auto value = "Enum16"; };
template <typename Type>
class DataTypeEnum final : public IDataType
......@@ -258,8 +258,8 @@ public:
};
using DataTypeEnum8 = DataTypeEnum<UInt8>;
using DataTypeEnum16 = DataTypeEnum<UInt16>;
using DataTypeEnum8 = DataTypeEnum<Int8>;
using DataTypeEnum16 = DataTypeEnum<Int16>;
}
......@@ -1788,9 +1788,9 @@ class FunctionCast final : public IFunction
else if (const auto type_tuple = typeid_cast<const DataTypeTuple *>(to_type))
return createTupleWrapper(from_type, type_tuple);
else if (const auto type_enum = typeid_cast<const DataTypeEnum8 *>(to_type))
return createEnumWrapper<ToPrimitiveType<UInt8>::Type>(from_type, type_enum);
return createEnumWrapper<ToPrimitiveType<DataTypeEnum8::FieldType>::Type>(from_type, type_enum);
else if (const auto type_enum = typeid_cast<const DataTypeEnum16 *>(to_type))
return createEnumWrapper<ToPrimitiveType<UInt16>::Type>(from_type, type_enum);
return createEnumWrapper<ToPrimitiveType<DataTypeEnum16::FieldType>::Type>(from_type, type_enum);
throw Exception{
"Conversion from " + from_type->getName() + " to " + to_type->getName() +
......
......@@ -12,9 +12,9 @@ class ASTEnumElement : public IAST
{
public:
String name;
UInt64 value;
Field value;
ASTEnumElement(const StringRange range, const String & name, const UInt64 & value)
ASTEnumElement(const StringRange range, const String & name, const Field & value)
: IAST{range}, name{name}, value {value} {}
String getID() const override { return "EnumElement"; }
......@@ -30,7 +30,7 @@ protected:
frame.need_parens = false;
const std::string indent_str = settings.one_line ? "" : std::string(4 * frame.indent, ' ');
settings.ostr << settings.nl_or_ws << indent_str << '\'' << name << "' = " << value;
settings.ostr << settings.nl_or_ws << indent_str << '\'' << name << "' = " << apply_visitor(FieldVisitorToString{}, value);
}
};
......
......@@ -11,7 +11,7 @@ namespace DB
class ParserEnumElement : public IParserBase
{
ParserStringLiteral name_parser;
ParserUnsignedInteger value_parser;
ParserNumber value_parser;
protected:
const char * getName() const override { return "enum element"; }
......@@ -39,7 +39,7 @@ protected:
node = new ASTEnumElement{
{ begin, pos },
static_cast<const ASTLiteral &>(*name).value.get<String>(),
static_cast<const ASTLiteral &>(*value).value.get<UInt64>()
static_cast<const ASTLiteral &>(*value).value
};
return true;
......
......@@ -57,17 +57,20 @@ inline DataTypePtr parseEnum(const String & name, const String & base_name, cons
typename DataTypeEnum::Values values;
values.reserve(elements->children.size());
using FieldType = typename DataTypeEnum::FieldType;
for (const auto & element : typeid_cast<const ASTExpressionList &>(*elements).children)
{
const auto & e = static_cast<const ASTEnumElement &>(*element);
const auto value = e.value.get<typename NearestFieldType<FieldType>::Type>();
if (e.value > std::numeric_limits<typename DataTypeEnum::FieldType>::max())
if (value > std::numeric_limits<FieldType>::max() || value < std::numeric_limits<FieldType>::min())
throw Exception{
"Value " + toString(e.value) + " for element '" + e.name + "' exceeds range of " + base_name,
"Value " + apply_visitor(FieldVisitorToString{}, e.value) + " for element '" + e.name + "' exceeds range of " + base_name,
ErrorCodes::ARGUMENT_OUT_OF_BOUND
};
values.emplace_back(e.name, e.value);
values.emplace_back(e.name, value);
}
return new DataTypeEnum{values};
......
......@@ -131,12 +131,12 @@ namespace VisibleWidth
return false;
}
template <typename T>
template <typename DataTypeEnum>
static bool executeEnum(Block & block, const DataTypePtr & type_ptr, const ColumnPtr & column, const size_t result)
{
if (const auto type = typeid_cast<const DataTypeEnum<T> *>(type_ptr.get()))
if (const auto type = typeid_cast<const DataTypeEnum *>(type_ptr.get()))
{
if (const auto col = typeid_cast<const ColumnVector<T> *>(column.get()))
if (const auto col = typeid_cast<const typename DataTypeEnum::ColumnType *>(column.get()))
{
const auto res = new ColumnUInt64(col->size());
ColumnPtr res_ptr{res};
......@@ -150,7 +150,7 @@ namespace VisibleWidth
return true;
}
else if (const auto col = typeid_cast<const ColumnConst<T> *>(column.get()))
else if (const auto col = typeid_cast<const typename DataTypeEnum::ConstColumnType *>(column.get()))
{
block.getByPosition(result).column = new ColumnConstUInt64{
col->size(), type->getNameLength(col->getData())
......@@ -179,8 +179,8 @@ void FunctionVisibleWidth::execute(Block & block, const ColumnNumbers & argument
{
block.getByPosition(result).column = new ColumnConstUInt64(rows, strlen("0000-00-00 00:00:00"));
}
else if (VisibleWidth::executeEnum<UInt8>(block, type, column, result)
|| VisibleWidth::executeEnum<UInt16>(block, type, column, result))
else if (VisibleWidth::executeEnum<DataTypeEnum8>(block, type, column, result)
|| VisibleWidth::executeEnum<DataTypeEnum16>(block, type, column, result))
{
}
else if (VisibleWidth::executeConstNumber<UInt8>(block, column, result)
......
......@@ -13,6 +13,7 @@
#include <DB/IO/CompressedReadBuffer.h>
#include <DB/DataTypes/DataTypeDate.h>
#include <DB/DataTypes/DataTypeFixedString.h>
#include <DB/DataTypes/DataTypeEnum.h>
#include <DB/Common/localBackup.h>
#include <DB/Functions/FunctionFactory.h>
#include <Poco/DirectoryIterator.h>
......@@ -491,8 +492,13 @@ void MergeTreeData::createConvertExpression(const DataPartPtr & part, const Name
{
const auto new_type = new_types[column.name].get();
const String new_type_name = new_type->getName();
const auto & old_type = column.type;
if (new_type_name != column.type->getName() &&
/// if this is not a check (part != nullptr) and alter does not change enum underlying type - do nothing
if (part && typeid(*new_type) == typeid(*old_type) &&
(typeid_cast<const DataTypeEnum8 *>(new_type) || typeid_cast<const DataTypeEnum16 *>(new_type)))
continue;
else if (new_type_name != old_type->getName() &&
(!part || part->hasColumnFiles(column.name)))
{
/// Нужно изменить тип столбца.
......@@ -554,8 +560,6 @@ MergeTreeData::AlterDataPartTransactionPtr MergeTreeData::alterDataPart(
if (expression)
{
MarkRanges ranges(1, MarkRange(0, part->size));
/** @todo expression->getRequiedColumns may contain integer width columns for FixedString(N) type which after
* passing them to ITableDeclaration::check will trigger and exception about unknown column `N` */
BlockInputStreamPtr part_in = new MergeTreeBlockInputStream(full_path + part->name + '/',
DEFAULT_MERGE_BLOCK_SIZE, expression->getRequiredColumns(), *this, part, ranges,
false, nullptr, "", false, 0, DBMS_DEFAULT_BUFFER_SIZE, false);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册