diff --git a/src/Interpreters/InterpreterCreateQuery.cpp b/src/Interpreters/InterpreterCreateQuery.cpp index f8bcbf02ab4..c6afe3d05e0 100644 --- a/src/Interpreters/InterpreterCreateQuery.cpp +++ b/src/Interpreters/InterpreterCreateQuery.cpp @@ -354,7 +354,7 @@ ASTPtr InterpreterCreateQuery::formatConstraints(const ConstraintsDescription & { auto res = std::make_shared(); - for (const auto & constraint : constraints.constraints) + for (const auto & constraint : constraints.getConstraints()) res->children.push_back(constraint->clone()); return res; @@ -489,9 +489,11 @@ ColumnsDescription InterpreterCreateQuery::getColumnsDescription( ConstraintsDescription InterpreterCreateQuery::getConstraintsDescription(const ASTExpressionList * constraints) { ConstraintsDescription res; + auto constraints_data = res.getConstraints(); if (constraints) for (const auto & constraint : constraints->children) - res.constraints.push_back(std::dynamic_pointer_cast(constraint->clone())); + constraints_data.push_back(std::dynamic_pointer_cast(constraint->clone())); + res.updateConstraints(constraints_data); return res; } diff --git a/src/Storages/AlterCommands.cpp b/src/Storages/AlterCommands.cpp index 7043a32760b..19fe490cfee 100644 --- a/src/Storages/AlterCommands.cpp +++ b/src/Storages/AlterCommands.cpp @@ -462,9 +462,10 @@ void AlterCommand::apply(StorageInMemoryMetadata & metadata, const Context & con } else if (type == ADD_CONSTRAINT) { + auto constraints = metadata.constraints.getConstraints(); if (std::any_of( - metadata.constraints.constraints.cbegin(), - metadata.constraints.constraints.cend(), + constraints.cbegin(), + constraints.cend(), [this](const ASTPtr & constraint_ast) { return constraint_ast->as().name == constraint_name; @@ -476,28 +477,31 @@ void AlterCommand::apply(StorageInMemoryMetadata & metadata, const Context & con ErrorCodes::ILLEGAL_COLUMN); } - auto insert_it = metadata.constraints.constraints.end(); + auto insert_it = constraints.end(); - metadata.constraints.constraints.emplace(insert_it, std::dynamic_pointer_cast(constraint_decl)); + constraints.emplace(insert_it, std::dynamic_pointer_cast(constraint_decl)); + metadata.constraints.updateConstraints(constraints); } else if (type == DROP_CONSTRAINT) { + auto constraints = metadata.constraints.getConstraints(); auto erase_it = std::find_if( - metadata.constraints.constraints.begin(), - metadata.constraints.constraints.end(), + constraints.begin(), + constraints.end(), [this](const ASTPtr & constraint_ast) { return constraint_ast->as().name == constraint_name; }); - if (erase_it == metadata.constraints.constraints.end()) + if (erase_it == constraints.end()) { if (if_exists) return; throw Exception("Wrong constraint name. Cannot find constraint `" + constraint_name + "` to drop.", ErrorCodes::BAD_ARGUMENTS); } - metadata.constraints.constraints.erase(erase_it); + constraints.erase(erase_it); + metadata.constraints.updateConstraints(constraints); } else if (type == MODIFY_TTL) { @@ -543,8 +547,10 @@ void AlterCommand::apply(StorageInMemoryMetadata & metadata, const Context & con if (metadata.table_ttl.definition_ast) rename_visitor.visit(metadata.table_ttl.definition_ast); - for (auto & constraint : metadata.constraints.constraints) + auto constraints_data = metadata.constraints.getConstraints(); + for (auto & constraint : constraints_data) rename_visitor.visit(constraint); + metadata.constraints.updateConstraints(constraints_data); if (metadata.isSortingKeyDefined()) rename_visitor.visit(metadata.sorting_key.definition_ast); diff --git a/src/Storages/ConstraintsDescription.cpp b/src/Storages/ConstraintsDescription.cpp index ad36cf6f50b..37af5efcc6e 100644 --- a/src/Storages/ConstraintsDescription.cpp +++ b/src/Storages/ConstraintsDescription.cpp @@ -66,7 +66,7 @@ ASTs ConstraintsDescription::filterConstraints(ConstraintType selection) const return res; } -std::vector> ConstraintsDescription::getConstraintData() const +std::vector> ConstraintsDescription::buildConstraintData() const { std::vector> constraint_data; for (const auto & constraint : filterConstraints(ConstraintsDescription::ConstraintType::ALWAYS_TRUE)) @@ -97,7 +97,7 @@ std::vector ConstraintsDescription::getAtomicConstraint return constraint_data; } -ComparisonGraph ConstraintsDescription::getGraph() const +std::unique_ptr ConstraintsDescription::buildGraph() const { static const std::set relations = { "equals", "less", "lessOrEquals", "greaterOrEquals", "greater"}; @@ -118,7 +118,7 @@ ComparisonGraph ConstraintsDescription::getGraph() const } } - return ComparisonGraph(constraints_for_graph); + return std::make_unique(constraints_for_graph); } ConstraintsExpressions ConstraintsDescription::getExpressionsToCheck(const DB::Context & context, @@ -140,11 +140,33 @@ ConstraintsExpressions ConstraintsDescription::getExpressionsToCheck(const DB::C return res; } +const ComparisonGraph & ConstraintsDescription::getGraph() const +{ + return *graph; +} + +const std::vector> & ConstraintsDescription::getConstraintData() const +{ + return cnf_constraints; +} + +const std::vector & ConstraintsDescription::getConstraints() const +{ + return constraints; +} + +void ConstraintsDescription::updateConstraints(const std::vector & constraints_) +{ + constraints = constraints_; + update(); +} + ConstraintsDescription::ConstraintsDescription(const ConstraintsDescription & other) { constraints.reserve(other.constraints.size()); for (const auto & constraint : other.constraints) constraints.emplace_back(constraint->clone()); + update(); } ConstraintsDescription & ConstraintsDescription::operator=(const ConstraintsDescription & other) @@ -152,7 +174,14 @@ ConstraintsDescription & ConstraintsDescription::operator=(const ConstraintsDesc constraints.resize(other.constraints.size()); for (size_t i = 0; i < constraints.size(); ++i) constraints[i] = other.constraints[i]->clone(); + update(); return *this; } +void ConstraintsDescription::update() +{ + cnf_constraints = buildConstraintData(); + graph = buildGraph(); +} + } diff --git a/src/Storages/ConstraintsDescription.h b/src/Storages/ConstraintsDescription.h index 73d3534976d..e942a221db4 100644 --- a/src/Storages/ConstraintsDescription.h +++ b/src/Storages/ConstraintsDescription.h @@ -12,11 +12,8 @@ using ConstraintsExpressions = std::vector; struct ConstraintsDescription { - std::vector constraints; - //std::vector cnf_constraints; - - // TODO: перенести преобразование в КНФ + get constraitns - ConstraintsDescription() = default; +public: + ConstraintsDescription() { update(); } bool empty() const { return constraints.empty(); } String toString() const; @@ -32,15 +29,27 @@ struct ConstraintsDescription ASTs filterConstraints(ConstraintType selection) const; - std::vector> getConstraintData() const; + const std::vector & getConstraints() const; + void updateConstraints(const std::vector & constraints); + + const std::vector> & getConstraintData() const; std::vector getAtomicConstraintData() const; - ComparisonGraph getGraph() const; + const ComparisonGraph & getGraph() const; ConstraintsExpressions getExpressionsToCheck(const Context & context, const NamesAndTypesList & source_columns_) const; ConstraintsDescription(const ConstraintsDescription & other); ConstraintsDescription & operator=(const ConstraintsDescription & other); + +private: + std::vector> buildConstraintData() const; + std::unique_ptr buildGraph() const; + void update(); + + std::vector constraints; + std::vector> cnf_constraints; + std::unique_ptr graph; }; } diff --git a/src/Storages/MergeTree/registerStorageMergeTree.cpp b/src/Storages/MergeTree/registerStorageMergeTree.cpp index 6cde5245735..b32cd439175 100644 --- a/src/Storages/MergeTree/registerStorageMergeTree.cpp +++ b/src/Storages/MergeTree/registerStorageMergeTree.cpp @@ -658,9 +658,11 @@ static StoragePtr create(const StorageFactory::Arguments & args) for (auto & index : args.query.columns_list->indices->children) metadata.secondary_indices.push_back(IndexDescription::getIndexFromAST(index, args.columns, args.context)); + auto constraints = metadata.constraints.getConstraints(); if (args.query.columns_list && args.query.columns_list->constraints) for (auto & constraint : args.query.columns_list->constraints->children) - metadata.constraints.constraints.push_back(constraint); + constraints.push_back(constraint); + metadata.constraints.updateConstraints(constraints); auto column_ttl_asts = args.columns.getColumnTTLs(); for (const auto & [name, ast] : column_ttl_asts)