mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 07:31:57 +00:00
Add ability to change some types for primary key
This commit is contained in:
parent
0e807d0647
commit
35413635e7
@ -5,6 +5,7 @@
|
||||
#include <DataTypes/DataTypeDateTime.h>
|
||||
#include <DataTypes/DataTypeEnum.h>
|
||||
#include <DataTypes/DataTypeNullable.h>
|
||||
#include <DataTypes/DataTypeLowCardinality.h>
|
||||
#include <DataTypes/NestedUtils.h>
|
||||
#include <Formats/FormatFactory.h>
|
||||
#include <Functions/FunctionFactory.h>
|
||||
@ -1316,10 +1317,10 @@ void MergeTreeData::dropIfEmpty()
|
||||
namespace
|
||||
{
|
||||
|
||||
/// Conversion that is allowed for partition key.
|
||||
/// Partition key should be serialized in the same way after conversion.
|
||||
/// Conversion that is allowed for serializable key (primary key, sorting key).
|
||||
/// Key should be serialized in the same way after conversion.
|
||||
/// NOTE: The list is not complete.
|
||||
bool isSafeForPartitionKeyConversion(const IDataType * from, const IDataType * to)
|
||||
bool isSafeForKeyConversion(const IDataType * from, const IDataType * to)
|
||||
{
|
||||
if (from->getName() == to->getName())
|
||||
return true;
|
||||
@ -1346,6 +1347,12 @@ bool isSafeForPartitionKeyConversion(const IDataType * from, const IDataType * t
|
||||
return false;
|
||||
}
|
||||
|
||||
if (const auto * from_lc = typeid_cast<const DataTypeLowCardinality *>(from))
|
||||
return from_lc->getDictionaryType()->equals(*to);
|
||||
|
||||
if (const auto * to_lc = typeid_cast<const DataTypeLowCardinality *>(to))
|
||||
return to_lc->getDictionaryType()->equals(*from);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1540,7 +1547,7 @@ void MergeTreeData::checkAlterIsPossible(const AlterCommands & commands, const S
|
||||
auto it = old_types.find(command.column_name);
|
||||
|
||||
assert(it != old_types.end());
|
||||
if (!isSafeForPartitionKeyConversion(it->second, command.data_type.get()))
|
||||
if (!isSafeForKeyConversion(it->second, command.data_type.get()))
|
||||
throw Exception("ALTER of partition key column " + backQuoteIfNeed(command.column_name) + " from type "
|
||||
+ it->second->getName() + " to type " + command.data_type->getName()
|
||||
+ " is not safe because it can change the representation of partition key",
|
||||
@ -1554,9 +1561,11 @@ void MergeTreeData::checkAlterIsPossible(const AlterCommands & commands, const S
|
||||
{
|
||||
auto it = old_types.find(command.column_name);
|
||||
assert(it != old_types.end());
|
||||
throw Exception("ALTER of key column " + backQuoteIfNeed(command.column_name) + " from type "
|
||||
+ it->second->getName() + " to type " + command.data_type->getName() + " must be metadata-only",
|
||||
ErrorCodes::ALTER_OF_COLUMN_IS_FORBIDDEN);
|
||||
if (!isSafeForKeyConversion(it->second, command.data_type.get()))
|
||||
throw Exception("ALTER of key column " + backQuoteIfNeed(command.column_name) + " from type "
|
||||
+ it->second->getName() + " to type " + command.data_type->getName()
|
||||
+ " is not safe because it can change the representation of primary key",
|
||||
ErrorCodes::ALTER_OF_COLUMN_IS_FORBIDDEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
CREATE TABLE default.table_with_lc_key\n(\n `enum_key` Enum8(\'y\' = 1, \'x\' = 2),\n `lc_key` String,\n `value` String\n)\nENGINE = MergeTree\nORDER BY (enum_key, lc_key)\nSETTINGS index_granularity = 8192
|
||||
y hello world
|
||||
CREATE TABLE default.table_with_lc_key\n(\n `enum_key` Enum8(\'y\' = 1, \'x\' = 2, \'z\' = 3),\n `lc_key` String,\n `value` String\n)\nENGINE = MergeTree\nORDER BY (enum_key, lc_key)\nSETTINGS index_granularity = 8192
|
||||
y hello world
|
||||
CREATE TABLE default.table_with_lc_key\n(\n `enum_key` Int8,\n `lc_key` String,\n `value` String\n)\nENGINE = MergeTree\nORDER BY (enum_key, lc_key)\nSETTINGS index_granularity = 8192
|
||||
1 hello world
|
||||
CREATE TABLE default.table_with_string_key\n(\n `int_key` Int8,\n `str_key` LowCardinality(String),\n `value` String\n)\nENGINE = MergeTree\nORDER BY (int_key, str_key)\nSETTINGS index_granularity = 8192
|
||||
1 hello world
|
@ -0,0 +1,67 @@
|
||||
DROP TABLE IF EXISTS table_with_lc_key;
|
||||
|
||||
CREATE TABLE table_with_lc_key
|
||||
(
|
||||
enum_key Enum8('x' = 2, 'y' = 1),
|
||||
lc_key LowCardinality(String),
|
||||
value String
|
||||
)
|
||||
ENGINE MergeTree()
|
||||
ORDER BY (enum_key, lc_key);
|
||||
|
||||
INSERT INTO table_with_lc_key VALUES(1, 'hello', 'world');
|
||||
|
||||
ALTER TABLE table_with_lc_key MODIFY COLUMN lc_key String;
|
||||
|
||||
SHOW CREATE TABLE table_with_lc_key;
|
||||
|
||||
DETACH TABLE table_with_lc_key;
|
||||
ATTACH TABLE table_with_lc_key;
|
||||
|
||||
SELECT * FROM table_with_lc_key WHERE enum_key > 0 and lc_key like 'h%';
|
||||
|
||||
ALTER TABLE table_with_lc_key MODIFY COLUMN enum_key Enum('x' = 2, 'y' = 1, 'z' = 3);
|
||||
ALTER TABLE table_with_lc_key MODIFY COLUMN enum_key Enum16('x' = 2, 'y' = 1, 'z' = 3); --{serverError 524}
|
||||
SHOW CREATE TABLE table_with_lc_key;
|
||||
|
||||
DETACH TABLE table_with_lc_key;
|
||||
ATTACH TABLE table_with_lc_key;
|
||||
|
||||
SELECT * FROM table_with_lc_key WHERE enum_key > 0 and lc_key like 'h%';
|
||||
|
||||
ALTER TABLE table_with_lc_key MODIFY COLUMN enum_key Int8;
|
||||
|
||||
SHOW CREATE TABLE table_with_lc_key;
|
||||
|
||||
DETACH TABLE table_with_lc_key;
|
||||
ATTACH TABLE table_with_lc_key;
|
||||
|
||||
SELECT * FROM table_with_lc_key WHERE enum_key > 0 and lc_key like 'h%';
|
||||
|
||||
DROP TABLE IF EXISTS table_with_lc_key;
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS table_with_string_key;
|
||||
CREATE TABLE table_with_string_key
|
||||
(
|
||||
int_key Int8,
|
||||
str_key String,
|
||||
value String
|
||||
)
|
||||
ENGINE MergeTree()
|
||||
ORDER BY (int_key, str_key);
|
||||
|
||||
INSERT INTO table_with_string_key VALUES(1, 'hello', 'world');
|
||||
|
||||
ALTER TABLE table_with_string_key MODIFY COLUMN str_key LowCardinality(String);
|
||||
|
||||
SHOW CREATE TABLE table_with_string_key;
|
||||
|
||||
DETACH TABLE table_with_string_key;
|
||||
ATTACH TABLE table_with_string_key;
|
||||
|
||||
SELECT * FROM table_with_string_key WHERE int_key > 0 and str_key like 'h%';
|
||||
|
||||
ALTER TABLE table_with_string_key MODIFY COLUMN int_key Enum8('y' = 1, 'x' = 2); --{serverError 524}
|
||||
|
||||
DROP TABLE IF EXISTS table_with_string_key;
|
Loading…
Reference in New Issue
Block a user