mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
Add limited support for nested structs
This commit is contained in:
parent
c03d48bd39
commit
0b3e81aef0
@ -39,6 +39,7 @@ namespace ErrorCodes
|
|||||||
extern const int NOT_FOUND_COLUMN_IN_BLOCK;
|
extern const int NOT_FOUND_COLUMN_IN_BLOCK;
|
||||||
extern const int LOGICAL_ERROR;
|
extern const int LOGICAL_ERROR;
|
||||||
extern const int DUPLICATE_COLUMN;
|
extern const int DUPLICATE_COLUMN;
|
||||||
|
extern const int NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -778,6 +779,12 @@ void AlterCommands::validate(const StorageInMemoryMetadata & metadata, const Con
|
|||||||
}
|
}
|
||||||
else if (command.type == AlterCommand::RENAME_COLUMN)
|
else if (command.type == AlterCommand::RENAME_COLUMN)
|
||||||
{
|
{
|
||||||
|
/// TODO Implement nested rename
|
||||||
|
if (metadata.columns.hasNested(command.column_name))
|
||||||
|
{
|
||||||
|
throw Exception{"Cannot rename whole Nested struct", ErrorCodes::NOT_IMPLEMENTED};
|
||||||
|
}
|
||||||
|
|
||||||
if (!metadata.columns.has(command.column_name))
|
if (!metadata.columns.has(command.column_name))
|
||||||
{
|
{
|
||||||
if (!command.if_exists)
|
if (!command.if_exists)
|
||||||
@ -797,7 +804,24 @@ void AlterCommands::validate(const StorageInMemoryMetadata & metadata, const Con
|
|||||||
throw Exception{"Rename loop detected in ALTER query",
|
throw Exception{"Rename loop detected in ALTER query",
|
||||||
ErrorCodes::BAD_ARGUMENTS};
|
ErrorCodes::BAD_ARGUMENTS};
|
||||||
|
|
||||||
renames_map[command.column_name] = command.rename_to;
|
String from_nested_table_name = Nested::extractTableName(command.column_name);
|
||||||
|
String to_nested_table_name = Nested::extractTableName(command.rename_to);
|
||||||
|
bool from_nested = from_nested_table_name != command.column_name;
|
||||||
|
bool to_nested = to_nested_table_name != command.rename_to;
|
||||||
|
|
||||||
|
if (from_nested && to_nested)
|
||||||
|
{
|
||||||
|
if (from_nested_table_name != to_nested_table_name)
|
||||||
|
throw Exception{"Cannot rename column from one nested name to another", ErrorCodes::BAD_ARGUMENTS};
|
||||||
|
}
|
||||||
|
else if (!from_nested && !to_nested)
|
||||||
|
{
|
||||||
|
renames_map[command.column_name] = command.rename_to;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw Exception{"Cannot rename column from nested struct to normal column and vice versa", ErrorCodes::BAD_ARGUMENTS};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Collect default expressions for MODIFY and ADD comands
|
/// Collect default expressions for MODIFY and ADD comands
|
||||||
|
@ -38,6 +38,7 @@ namespace ErrorCodes
|
|||||||
extern const int ILLEGAL_COLUMN;
|
extern const int ILLEGAL_COLUMN;
|
||||||
extern const int CANNOT_PARSE_TEXT;
|
extern const int CANNOT_PARSE_TEXT;
|
||||||
extern const int THERE_IS_NO_DEFAULT_VALUE;
|
extern const int THERE_IS_NO_DEFAULT_VALUE;
|
||||||
|
extern const int LOGICAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnDescription::ColumnDescription(String name_, DataTypePtr type_, bool is_virtual_)
|
ColumnDescription::ColumnDescription(String name_, DataTypePtr type_, bool is_virtual_)
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <Common/SimpleIncrement.h>
|
#include <Common/SimpleIncrement.h>
|
||||||
#include <Common/interpolate.h>
|
#include <Common/interpolate.h>
|
||||||
#include <Common/typeid_cast.h>
|
#include <Common/typeid_cast.h>
|
||||||
|
#include <Common/escapeForFileName.h>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
@ -1061,7 +1062,6 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mutatePartToTempor
|
|||||||
NameSet files_to_skip = collectFilesToSkip(updated_header, indices_to_recalc, mrk_extension);
|
NameSet files_to_skip = collectFilesToSkip(updated_header, indices_to_recalc, mrk_extension);
|
||||||
NameToNameMap files_to_rename = collectFilesForRenames(source_part, for_file_renames, mrk_extension);
|
NameToNameMap files_to_rename = collectFilesForRenames(source_part, for_file_renames, mrk_extension);
|
||||||
|
|
||||||
|
|
||||||
if (need_remove_expired_values)
|
if (need_remove_expired_values)
|
||||||
files_to_skip.insert("ttl.txt");
|
files_to_skip.insert("ttl.txt");
|
||||||
|
|
||||||
@ -1108,7 +1108,9 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mutatePartToTempor
|
|||||||
for (const auto & [rename_from, rename_to] : files_to_rename)
|
for (const auto & [rename_from, rename_to] : files_to_rename)
|
||||||
{
|
{
|
||||||
if (rename_to.empty() && new_data_part->checksums.files.count(rename_from))
|
if (rename_to.empty() && new_data_part->checksums.files.count(rename_from))
|
||||||
|
{
|
||||||
new_data_part->checksums.files.erase(rename_from);
|
new_data_part->checksums.files.erase(rename_from);
|
||||||
|
}
|
||||||
else if (new_data_part->checksums.files.count(rename_from))
|
else if (new_data_part->checksums.files.count(rename_from))
|
||||||
{
|
{
|
||||||
new_data_part->checksums.files[rename_to] = new_data_part->checksums.files[rename_from];
|
new_data_part->checksums.files[rename_to] = new_data_part->checksums.files[rename_from];
|
||||||
@ -1329,13 +1331,20 @@ NameToNameMap MergeTreeDataMergerMutator::collectFilesForRenames(
|
|||||||
}
|
}
|
||||||
else if (command.type == MutationCommand::Type::RENAME_COLUMN)
|
else if (command.type == MutationCommand::Type::RENAME_COLUMN)
|
||||||
{
|
{
|
||||||
|
String escaped_name_from = escapeForFileName(command.column_name);
|
||||||
|
String escaped_name_to = escapeForFileName(command.rename_to);
|
||||||
|
|
||||||
IDataType::StreamCallback callback = [&](const IDataType::SubstreamPath & substream_path)
|
IDataType::StreamCallback callback = [&](const IDataType::SubstreamPath & substream_path)
|
||||||
{
|
{
|
||||||
String stream_from = IDataType::getFileNameForStream(command.column_name, substream_path);
|
String stream_from = IDataType::getFileNameForStream(command.column_name, substream_path);
|
||||||
|
|
||||||
String stream_to = boost::replace_first_copy(stream_from, command.column_name, command.rename_to);
|
String stream_to = boost::replace_first_copy(stream_from, escaped_name_from, escaped_name_to);
|
||||||
rename_map.emplace(stream_from + ".bin", stream_to + ".bin");
|
|
||||||
rename_map.emplace(stream_from + mrk_extension, stream_to + mrk_extension);
|
if (stream_from != stream_to)
|
||||||
|
{
|
||||||
|
rename_map.emplace(stream_from + ".bin", stream_to + ".bin");
|
||||||
|
rename_map.emplace(stream_from + mrk_extension, stream_to + mrk_extension);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
IDataType::SubstreamPath stream_path;
|
IDataType::SubstreamPath stream_path;
|
||||||
auto column = source_part->getColumns().tryGetByName(command.column_name);
|
auto column = source_part->getColumns().tryGetByName(command.column_name);
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
[8,9,10]
|
||||||
|
['a','b','c']
|
||||||
|
CREATE TABLE default.table_for_rename_nested (`date` Date, `key` UInt64, `n.x` Array(UInt32), `n.y` Array(String), `value1` String) ENGINE = MergeTree() PARTITION BY date ORDER BY key SETTINGS index_granularity = 8192
|
||||||
|
CREATE TABLE default.table_for_rename_nested (`date` Date, `key` UInt64, `n.renamed_x` Array(UInt32), `n.renamed_y` Array(String), `value1` String) ENGINE = MergeTree() PARTITION BY date ORDER BY key SETTINGS index_granularity = 8192
|
||||||
|
7 [8,9,10]
|
||||||
|
7 ['a','b','c']
|
34
dbms/tests/queries/0_stateless/01213_alter_rename_nested.sql
Normal file
34
dbms/tests/queries/0_stateless/01213_alter_rename_nested.sql
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
DROP TABLE IF EXISTS table_for_rename_nested;
|
||||||
|
CREATE TABLE table_for_rename_nested
|
||||||
|
(
|
||||||
|
date Date,
|
||||||
|
key UInt64,
|
||||||
|
n Nested(x UInt32, y String),
|
||||||
|
value1 String
|
||||||
|
)
|
||||||
|
ENGINE = MergeTree()
|
||||||
|
PARTITION BY date
|
||||||
|
ORDER BY key;
|
||||||
|
|
||||||
|
INSERT INTO table_for_rename_nested (date, key, n.x, n.y, value1) SELECT toDate('2019-10-01'), number, [number + 1, number + 2, number + 3], ['a', 'b', 'c'], toString(number) FROM numbers(10);
|
||||||
|
|
||||||
|
SELECT n.x FROM table_for_rename_nested WHERE key = 7;
|
||||||
|
SELECT n.y FROM table_for_rename_nested WHERE key = 7;
|
||||||
|
|
||||||
|
SHOW CREATE TABLE table_for_rename_nested;
|
||||||
|
|
||||||
|
ALTER TABLE table_for_rename_nested RENAME COLUMN n.x TO n.renamed_x;
|
||||||
|
ALTER TABLE table_for_rename_nested RENAME COLUMN n.y TO n.renamed_y;
|
||||||
|
|
||||||
|
SHOW CREATE TABLE table_for_rename_nested;
|
||||||
|
|
||||||
|
SELECT key, n.renamed_x FROM table_for_rename_nested WHERE key = 7;
|
||||||
|
SELECT key, n.renamed_y FROM table_for_rename_nested WHERE key = 7;
|
||||||
|
|
||||||
|
ALTER TABLE table_for_rename_nested RENAME COLUMN n.renamed_x TO not_nested_x; --{serverError 36}
|
||||||
|
|
||||||
|
-- Currently not implemented
|
||||||
|
ALTER TABLE table_for_rename_nested RENAME COLUMN n TO renamed_n; --{serverError 48}
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS table_for_rename_nested;
|
||||||
|
|
@ -0,0 +1,38 @@
|
|||||||
|
DROP TABLE IF EXISTS table_for_rename_nested;
|
||||||
|
CREATE TABLE table_for_rename_nested
|
||||||
|
(
|
||||||
|
date Date,
|
||||||
|
key UInt64,
|
||||||
|
n Nested(x UInt32, y String),
|
||||||
|
value1 String
|
||||||
|
)
|
||||||
|
ENGINE = MergeTree()
|
||||||
|
PARTITION BY date
|
||||||
|
ORDER BY key;
|
||||||
|
|
||||||
|
INSERT INTO table_for_rename_nested (date, key, n.x, n.y, value1) SELECT toDate('2019-10-01'), number, [number + 1, number + 2, number + 3], ['a', 'b', 'c'], toString(number) FROM numbers(10);
|
||||||
|
|
||||||
|
SELECT n.x FROM table_for_rename_nested WHERE key = 7;
|
||||||
|
SELECT n.y FROM table_for_rename_nested WHERE key = 7;
|
||||||
|
|
||||||
|
SHOW CREATE TABLE table_for_rename_nested;
|
||||||
|
|
||||||
|
ALTER TABLE table_for_rename_nested RENAME COLUMN n.x TO n.renamed_x;
|
||||||
|
ALTER TABLE table_for_rename_nested RENAME COLUMN n.y TO n.renamed_y;
|
||||||
|
|
||||||
|
SHOW CREATE TABLE table_for_rename_nested;
|
||||||
|
|
||||||
|
SELECT key, n.renamed_x FROM table_for_rename_nested WHERE key = 7;
|
||||||
|
SELECT key, n.renamed_y FROM table_for_rename_nested WHERE key = 7;
|
||||||
|
|
||||||
|
ALTER TABLE table_for_rename_nested RENAME COLUMN n.renamed_x TO not_nested_x; --{serverError 36}
|
||||||
|
|
||||||
|
ALTER TABLE table_for_rename_nested RENAME COLUMN n.renamed_x TO q.renamed_x; --{serverError 36}
|
||||||
|
|
||||||
|
ALTER TABLE table_for_rename_nested RENAME COLUMN value1 TO q.renamed_x; --{serverError 36}
|
||||||
|
|
||||||
|
-- Currently not implemented
|
||||||
|
ALTER TABLE table_for_rename_nested RENAME COLUMN n TO renamed_n; --{serverError 48}
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS table_for_rename_nested;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user