diff --git a/dbms/src/Storages/MergeTree/MergeTreeData.cpp b/dbms/src/Storages/MergeTree/MergeTreeData.cpp index 2278b22eb30..012edf311eb 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeData.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeData.cpp @@ -356,36 +356,49 @@ void MergeTreeData::setSkipIndices(const ASTPtr &indices_asts, bool only_check) if (!only_check) { skip_indices_ast = nullptr; + skip_indices_expr = nullptr; skip_indices.clear(); } return; } - MergeTreeIndices new_indexes; + MergeTreeIndices new_indices; std::set names; auto index_list = std::dynamic_pointer_cast(indices_asts); + ASTPtr indices_expr_list = std::make_shared(); - for (const auto &index_ast : index_list->children) + for (const auto & index_ast : index_list->children) { - new_indexes.push_back( + const auto & index_decl = std::dynamic_pointer_cast(index_ast); + + new_indices.push_back( std::move(MergeTreeIndexFactory::instance().get( *this, - std::dynamic_pointer_cast(index_ast), + std::dynamic_pointer_cast(index_decl->clone()), global_context))); - if (names.find(new_indexes.back()->name) != names.end()) - { + if (names.find(new_indices.back()->name) != names.end()) throw Exception( - "Index with name `" + new_indexes.back()->name + "` already exsists", + "Index with name `" + new_indices.back()->name + "` already exsists", ErrorCodes::LOGICAL_ERROR); - } - names.insert(new_indexes.back()->name); + + ASTPtr expr_list = MergeTreeData::extractKeyExpressionList(index_decl->expr->clone()); + for (auto expr : expr_list->children) + indices_expr_list->children.push_back(expr->clone()); + + names.insert(new_indices.back()->name); } + auto syntax = SyntaxAnalyzer(global_context, {}).analyze( + indices_expr_list, getColumns().getAllPhysical()); + auto new_skip_indices_expr = ExpressionAnalyzer(indices_expr_list, syntax, global_context) + .getActions(false); + if (!only_check) { skip_indices_ast = indices_asts; - skip_indices = std::move(new_indexes); + skip_indices_expr = new_skip_indices_expr; + skip_indices = std::move(new_indices); } } diff --git a/dbms/src/Storages/MergeTree/MergeTreeData.h b/dbms/src/Storages/MergeTree/MergeTreeData.h index e7db445689b..611bc4500bc 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeData.h +++ b/dbms/src/Storages/MergeTree/MergeTreeData.h @@ -585,6 +585,7 @@ public: /// Secondary (data skipping) indices for MergeTree MergeTreeIndices skip_indices; ASTPtr skip_indices_ast; + ExpressionActionsPtr skip_indices_expr; /// Names of columns for primary key + secondary sorting columns. Names sorting_key_columns; diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp index 3acb5fa5e21..e2b75a503fc 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp @@ -636,9 +636,9 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mergePartsToTempor merge_entry, sum_input_rows_upper_bound, column_sizes, watch_prev_elapsed, merge_alg)); BlockInputStreamPtr stream = std::move(input); - for (const auto & index : data.skip_indices) { + if (data.skip_indices_expr) { stream = std::make_shared( - std::make_shared(stream, index->expr)); + std::make_shared(stream, data.skip_indices_expr)); } if (data.hasPrimaryKey()) { @@ -911,9 +911,9 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mutatePartToTempor { /// All columns are modified, proceed to write a new part from scratch. - for (const auto & index : data.skip_indices) + if (data.skip_indices_expr) in = std::make_shared( - std::make_shared(in, index->expr)); + std::make_shared(in, data.skip_indices_expr)); if (data.hasPrimaryKey()) in = std::make_shared( diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataWriter.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataWriter.cpp index 05a5253323c..7a853855ba7 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataWriter.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataWriter.cpp @@ -214,8 +214,8 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataWriter::writeTempPart(BlockWithPa NamesAndTypesList columns = data.getColumns().getAllPhysical().filter(block.getNames()); MergedBlockOutputStream out(data, new_data_part->getFullPath(), columns, compression_codec); - for (auto index : data.skip_indices) - index->expr->execute(block); + if (data.skip_indices_expr) + data.skip_indices_expr->execute(block); out.writePrefix(); out.writeWithPermutation(block, perm_ptr); diff --git a/dbms/tests/queries/0_stateless/00823_minmax_index.sql b/dbms/tests/queries/0_stateless/00823_minmax_index.sql index 00d89fcfcd9..3278eac275d 100644 --- a/dbms/tests/queries/0_stateless/00823_minmax_index.sql +++ b/dbms/tests/queries/0_stateless/00823_minmax_index.sql @@ -11,7 +11,8 @@ CREATE TABLE test.minmax_idx dt Date ) ENGINE = MergeTree() ORDER BY u64 -INDICES idx_all BY (i32, i32 + f64, d, s, e, dt) TYPE minmax GRANULARITY 2, +INDICES idx_all BY (i32, i32 + f64, d, s, e, dt) TYPE minmax GRANULARITY 4, + idx_all2 BY (i32, i32 + f64, d, s, e, dt) TYPE minmax GRANULARITY 2, idx_2 BY (u64 + toYear(dt), substring(s, 2, 4)) TYPE minmax GRANULARITY 3 SETTINGS index_granularity = 2;