mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 08:40:50 +00:00
Move most code from setTableStructure() to a separate function.
This commit is contained in:
parent
7689e0c36f
commit
01921ce9a3
@ -2,6 +2,7 @@
|
||||
#include <Storages/MergeTree/MergeTreeData.h>
|
||||
#include <Parsers/formatAST.h>
|
||||
#include <Parsers/parseQuery.h>
|
||||
#include <Parsers/ASTFunction.h>
|
||||
#include <Parsers/ExpressionListParsers.h>
|
||||
#include <IO/Operators.h>
|
||||
|
||||
@ -353,4 +354,123 @@ ReplicatedMergeTreeTableMetadata::checkAndFindDiff(const ReplicatedMergeTreeTabl
|
||||
return diff;
|
||||
}
|
||||
|
||||
StorageInMemoryMetadata ReplicatedMergeTreeTableMetadata::Diff::getNewMetadata(const ColumnsDescription & new_columns, ContextPtr context, const StorageInMemoryMetadata & old_metadata) const
|
||||
{
|
||||
StorageInMemoryMetadata new_metadata = old_metadata;
|
||||
new_metadata.columns = new_columns;
|
||||
|
||||
if (!empty())
|
||||
{
|
||||
auto parse_key_expr = [] (const String & key_expr)
|
||||
{
|
||||
ParserNotEmptyExpressionList parser(false);
|
||||
auto new_sorting_key_expr_list = parseQuery(parser, key_expr, 0, DBMS_DEFAULT_MAX_PARSER_DEPTH);
|
||||
|
||||
ASTPtr order_by_ast;
|
||||
if (new_sorting_key_expr_list->children.size() == 1)
|
||||
order_by_ast = new_sorting_key_expr_list->children[0];
|
||||
else
|
||||
{
|
||||
auto tuple = makeASTFunction("tuple");
|
||||
tuple->arguments->children = new_sorting_key_expr_list->children;
|
||||
order_by_ast = tuple;
|
||||
}
|
||||
return order_by_ast;
|
||||
};
|
||||
|
||||
if (sorting_key_changed)
|
||||
{
|
||||
auto order_by_ast = parse_key_expr(new_sorting_key);
|
||||
|
||||
new_metadata.sorting_key.recalculateWithNewAST(order_by_ast, new_metadata.columns, context);
|
||||
|
||||
if (new_metadata.primary_key.definition_ast == nullptr)
|
||||
{
|
||||
/// Primary and sorting key become independent after this ALTER so we have to
|
||||
/// save the old ORDER BY expression as the new primary key.
|
||||
auto old_sorting_key_ast = old_metadata.getSortingKey().definition_ast;
|
||||
new_metadata.primary_key = KeyDescription::getKeyFromAST(
|
||||
old_sorting_key_ast, new_metadata.columns, context);
|
||||
}
|
||||
}
|
||||
|
||||
if (sampling_expression_changed)
|
||||
{
|
||||
if (!new_sampling_expression.empty())
|
||||
{
|
||||
auto sample_by_ast = parse_key_expr(new_sampling_expression);
|
||||
new_metadata.sampling_key.recalculateWithNewAST(sample_by_ast, new_metadata.columns, context);
|
||||
}
|
||||
else /// SAMPLE BY was removed
|
||||
{
|
||||
new_metadata.sampling_key = {};
|
||||
}
|
||||
}
|
||||
|
||||
if (skip_indices_changed)
|
||||
new_metadata.secondary_indices = IndicesDescription::parse(new_skip_indices, new_columns, context);
|
||||
|
||||
if (constraints_changed)
|
||||
new_metadata.constraints = ConstraintsDescription::parse(new_constraints);
|
||||
|
||||
if (projections_changed)
|
||||
new_metadata.projections = ProjectionsDescription::parse(new_projections, new_columns, context);
|
||||
|
||||
if (ttl_table_changed)
|
||||
{
|
||||
if (!new_ttl_table.empty())
|
||||
{
|
||||
ParserTTLExpressionList parser;
|
||||
auto ttl_for_table_ast = parseQuery(parser, new_ttl_table, 0, DBMS_DEFAULT_MAX_PARSER_DEPTH);
|
||||
new_metadata.table_ttl = TTLTableDescription::getTTLForTableFromAST(
|
||||
ttl_for_table_ast, new_metadata.columns, context, new_metadata.primary_key);
|
||||
}
|
||||
else /// TTL was removed
|
||||
{
|
||||
new_metadata.table_ttl = TTLTableDescription{};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Changes in columns may affect following metadata fields
|
||||
new_metadata.column_ttls_by_name.clear();
|
||||
for (const auto & [name, ast] : new_metadata.columns.getColumnTTLs())
|
||||
{
|
||||
auto new_ttl_entry = TTLDescription::getTTLFromAST(ast, new_metadata.columns, context, new_metadata.primary_key);
|
||||
new_metadata.column_ttls_by_name[name] = new_ttl_entry;
|
||||
}
|
||||
|
||||
if (new_metadata.partition_key.definition_ast != nullptr)
|
||||
new_metadata.partition_key.recalculateWithNewColumns(new_metadata.columns, context);
|
||||
|
||||
if (!sorting_key_changed) /// otherwise already updated
|
||||
new_metadata.sorting_key.recalculateWithNewColumns(new_metadata.columns, context);
|
||||
|
||||
/// Primary key is special, it exists even if not defined
|
||||
if (new_metadata.primary_key.definition_ast != nullptr)
|
||||
{
|
||||
new_metadata.primary_key.recalculateWithNewColumns(new_metadata.columns, context);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_metadata.primary_key = KeyDescription::getKeyFromAST(new_metadata.sorting_key.definition_ast, new_metadata.columns, context);
|
||||
new_metadata.primary_key.definition_ast = nullptr;
|
||||
}
|
||||
|
||||
if (!sampling_expression_changed && new_metadata.sampling_key.definition_ast != nullptr)
|
||||
new_metadata.sampling_key.recalculateWithNewColumns(new_metadata.columns, context);
|
||||
|
||||
if (!skip_indices_changed) /// otherwise already updated
|
||||
{
|
||||
for (auto & index : new_metadata.secondary_indices)
|
||||
index.recalculateWithNewColumns(new_metadata.columns, context);
|
||||
}
|
||||
|
||||
if (!ttl_table_changed && new_metadata.table_ttl.definition_ast != nullptr)
|
||||
new_metadata.table_ttl = TTLTableDescription::getTTLForTableFromAST(
|
||||
new_metadata.table_ttl.definition_ast, new_metadata.columns, context, new_metadata.primary_key);
|
||||
|
||||
return new_metadata;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -66,6 +66,8 @@ struct ReplicatedMergeTreeTableMetadata
|
||||
return !sorting_key_changed && !sampling_expression_changed && !skip_indices_changed && !projections_changed
|
||||
&& !ttl_table_changed && !constraints_changed;
|
||||
}
|
||||
|
||||
StorageInMemoryMetadata getNewMetadata(const ColumnsDescription & new_columns, ContextPtr context, const StorageInMemoryMetadata & old_metadata) const;
|
||||
};
|
||||
|
||||
void checkEquals(const ReplicatedMergeTreeTableMetadata & from_zk, const ColumnsDescription & columns, ContextPtr context) const;
|
||||
|
@ -1094,123 +1094,8 @@ void StorageReplicatedMergeTree::checkTableStructure(const String & zookeeper_pr
|
||||
void StorageReplicatedMergeTree::setTableStructure(
|
||||
ColumnsDescription new_columns, const ReplicatedMergeTreeTableMetadata::Diff & metadata_diff)
|
||||
{
|
||||
StorageInMemoryMetadata new_metadata = getInMemoryMetadata();
|
||||
StorageInMemoryMetadata old_metadata = getInMemoryMetadata();
|
||||
|
||||
new_metadata.columns = new_columns;
|
||||
|
||||
if (!metadata_diff.empty())
|
||||
{
|
||||
auto parse_key_expr = [] (const String & key_expr)
|
||||
{
|
||||
ParserNotEmptyExpressionList parser(false);
|
||||
auto new_sorting_key_expr_list = parseQuery(parser, key_expr, 0, DBMS_DEFAULT_MAX_PARSER_DEPTH);
|
||||
|
||||
ASTPtr order_by_ast;
|
||||
if (new_sorting_key_expr_list->children.size() == 1)
|
||||
order_by_ast = new_sorting_key_expr_list->children[0];
|
||||
else
|
||||
{
|
||||
auto tuple = makeASTFunction("tuple");
|
||||
tuple->arguments->children = new_sorting_key_expr_list->children;
|
||||
order_by_ast = tuple;
|
||||
}
|
||||
return order_by_ast;
|
||||
};
|
||||
|
||||
if (metadata_diff.sorting_key_changed)
|
||||
{
|
||||
auto order_by_ast = parse_key_expr(metadata_diff.new_sorting_key);
|
||||
auto & sorting_key = new_metadata.sorting_key;
|
||||
auto & primary_key = new_metadata.primary_key;
|
||||
|
||||
sorting_key.recalculateWithNewAST(order_by_ast, new_metadata.columns, getContext());
|
||||
|
||||
if (primary_key.definition_ast == nullptr)
|
||||
{
|
||||
/// Primary and sorting key become independent after this ALTER so we have to
|
||||
/// save the old ORDER BY expression as the new primary key.
|
||||
auto old_sorting_key_ast = old_metadata.getSortingKey().definition_ast;
|
||||
primary_key = KeyDescription::getKeyFromAST(
|
||||
old_sorting_key_ast, new_metadata.columns, getContext());
|
||||
}
|
||||
}
|
||||
|
||||
if (metadata_diff.sampling_expression_changed)
|
||||
{
|
||||
if (!metadata_diff.new_sampling_expression.empty())
|
||||
{
|
||||
auto sample_by_ast = parse_key_expr(metadata_diff.new_sampling_expression);
|
||||
new_metadata.sampling_key.recalculateWithNewAST(sample_by_ast, new_metadata.columns, getContext());
|
||||
}
|
||||
else /// SAMPLE BY was removed
|
||||
{
|
||||
new_metadata.sampling_key = {};
|
||||
}
|
||||
}
|
||||
|
||||
if (metadata_diff.skip_indices_changed)
|
||||
new_metadata.secondary_indices = IndicesDescription::parse(metadata_diff.new_skip_indices, new_columns, getContext());
|
||||
|
||||
if (metadata_diff.constraints_changed)
|
||||
new_metadata.constraints = ConstraintsDescription::parse(metadata_diff.new_constraints);
|
||||
|
||||
if (metadata_diff.projections_changed)
|
||||
new_metadata.projections = ProjectionsDescription::parse(metadata_diff.new_projections, new_columns, getContext());
|
||||
|
||||
if (metadata_diff.ttl_table_changed)
|
||||
{
|
||||
if (!metadata_diff.new_ttl_table.empty())
|
||||
{
|
||||
ParserTTLExpressionList parser;
|
||||
auto ttl_for_table_ast = parseQuery(parser, metadata_diff.new_ttl_table, 0, DBMS_DEFAULT_MAX_PARSER_DEPTH);
|
||||
new_metadata.table_ttl = TTLTableDescription::getTTLForTableFromAST(
|
||||
ttl_for_table_ast, new_metadata.columns, getContext(), new_metadata.primary_key);
|
||||
}
|
||||
else /// TTL was removed
|
||||
{
|
||||
new_metadata.table_ttl = TTLTableDescription{};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Changes in columns may affect following metadata fields
|
||||
new_metadata.column_ttls_by_name.clear();
|
||||
for (const auto & [name, ast] : new_metadata.columns.getColumnTTLs())
|
||||
{
|
||||
auto new_ttl_entry = TTLDescription::getTTLFromAST(ast, new_metadata.columns, getContext(), new_metadata.primary_key);
|
||||
new_metadata.column_ttls_by_name[name] = new_ttl_entry;
|
||||
}
|
||||
|
||||
if (new_metadata.partition_key.definition_ast != nullptr)
|
||||
new_metadata.partition_key.recalculateWithNewColumns(new_metadata.columns, getContext());
|
||||
|
||||
if (!metadata_diff.sorting_key_changed) /// otherwise already updated
|
||||
new_metadata.sorting_key.recalculateWithNewColumns(new_metadata.columns, getContext());
|
||||
|
||||
/// Primary key is special, it exists even if not defined
|
||||
if (new_metadata.primary_key.definition_ast != nullptr)
|
||||
{
|
||||
new_metadata.primary_key.recalculateWithNewColumns(new_metadata.columns, getContext());
|
||||
}
|
||||
else
|
||||
{
|
||||
new_metadata.primary_key = KeyDescription::getKeyFromAST(new_metadata.sorting_key.definition_ast, new_metadata.columns, getContext());
|
||||
new_metadata.primary_key.definition_ast = nullptr;
|
||||
}
|
||||
|
||||
if (!metadata_diff.sampling_expression_changed && new_metadata.sampling_key.definition_ast != nullptr)
|
||||
new_metadata.sampling_key.recalculateWithNewColumns(new_metadata.columns, getContext());
|
||||
|
||||
if (!metadata_diff.skip_indices_changed) /// otherwise already updated
|
||||
{
|
||||
for (auto & index : new_metadata.secondary_indices)
|
||||
index.recalculateWithNewColumns(new_metadata.columns, getContext());
|
||||
}
|
||||
|
||||
if (!metadata_diff.ttl_table_changed && new_metadata.table_ttl.definition_ast != nullptr)
|
||||
new_metadata.table_ttl = TTLTableDescription::getTTLForTableFromAST(
|
||||
new_metadata.table_ttl.definition_ast, new_metadata.columns, getContext(), new_metadata.primary_key);
|
||||
StorageInMemoryMetadata new_metadata = metadata_diff.getNewMetadata(new_columns, getContext(), old_metadata);
|
||||
|
||||
/// Even if the primary/sorting/partition keys didn't change we must reinitialize it
|
||||
/// because primary/partition key column types might have changed.
|
||||
|
Loading…
Reference in New Issue
Block a user