Move most code from setTableStructure() to a separate function.

This commit is contained in:
Vitaly Baranov 2022-06-26 17:17:43 +02:00
parent 7689e0c36f
commit 01921ce9a3
3 changed files with 123 additions and 116 deletions

View File

@ -2,6 +2,7 @@
#include <Storages/MergeTree/MergeTreeData.h> #include <Storages/MergeTree/MergeTreeData.h>
#include <Parsers/formatAST.h> #include <Parsers/formatAST.h>
#include <Parsers/parseQuery.h> #include <Parsers/parseQuery.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/ExpressionListParsers.h> #include <Parsers/ExpressionListParsers.h>
#include <IO/Operators.h> #include <IO/Operators.h>
@ -353,4 +354,123 @@ ReplicatedMergeTreeTableMetadata::checkAndFindDiff(const ReplicatedMergeTreeTabl
return diff; 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;
}
} }

View File

@ -66,6 +66,8 @@ struct ReplicatedMergeTreeTableMetadata
return !sorting_key_changed && !sampling_expression_changed && !skip_indices_changed && !projections_changed return !sorting_key_changed && !sampling_expression_changed && !skip_indices_changed && !projections_changed
&& !ttl_table_changed && !constraints_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; void checkEquals(const ReplicatedMergeTreeTableMetadata & from_zk, const ColumnsDescription & columns, ContextPtr context) const;

View File

@ -1094,123 +1094,8 @@ void StorageReplicatedMergeTree::checkTableStructure(const String & zookeeper_pr
void StorageReplicatedMergeTree::setTableStructure( void StorageReplicatedMergeTree::setTableStructure(
ColumnsDescription new_columns, const ReplicatedMergeTreeTableMetadata::Diff & metadata_diff) ColumnsDescription new_columns, const ReplicatedMergeTreeTableMetadata::Diff & metadata_diff)
{ {
StorageInMemoryMetadata new_metadata = getInMemoryMetadata();
StorageInMemoryMetadata old_metadata = getInMemoryMetadata(); StorageInMemoryMetadata old_metadata = getInMemoryMetadata();
StorageInMemoryMetadata new_metadata = metadata_diff.getNewMetadata(new_columns, getContext(), old_metadata);
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);
/// Even if the primary/sorting/partition keys didn't change we must reinitialize it /// Even if the primary/sorting/partition keys didn't change we must reinitialize it
/// because primary/partition key column types might have changed. /// because primary/partition key column types might have changed.