Merge pull request #57491 from jkartseva/limit-table-projections

limit merge tree projections
This commit is contained in:
Anton Popov 2023-12-05 12:13:41 +01:00 committed by GitHub
commit 5770def9af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 47 additions and 0 deletions

View File

@ -194,6 +194,7 @@ namespace ErrorCodes
extern const int SERIALIZATION_ERROR;
extern const int TOO_MANY_MUTATIONS;
extern const int CANNOT_SCHEDULE_TASK;
extern const int LIMIT_EXCEEDED;
}
static void checkSuspiciousIndices(const ASTFunction * index_function)
@ -649,6 +650,10 @@ void MergeTreeData::checkProperties(
if (projections_names.find(projection.name) != projections_names.end())
throw Exception(ErrorCodes::LOGICAL_ERROR, "Projection with name {} already exists", backQuote(projection.name));
const auto settings = getSettings();
if (projections_names.size() >= settings->max_projections)
throw Exception(ErrorCodes::LIMIT_EXCEEDED, "Maximum limit of {} projection(s) exceeded", settings->max_projections);
/// We cannot alter a projection so far. So here we do not try to find a projection in old metadata.
bool is_aggregate = projection.type == ProjectionDescription::Type::Aggregate;
checkProperties(*projection.metadata, *projection.metadata, attach, is_aggregate, true /* allow_nullable_key */, local_context);

View File

@ -186,6 +186,9 @@ struct Settings;
M(String, primary_key_compression_codec, "ZSTD(3)", "Compression encoding used by primary, primary key is small enough and cached, so the default compression is ZSTD(3).", 0) \
M(UInt64, marks_compress_block_size, 65536, "Mark compress block size, the actual size of the block to compress.", 0) \
M(UInt64, primary_key_compress_block_size, 65536, "Primary compress block size, the actual size of the block to compress.", 0) \
\
/** Projection settings. */ \
M(UInt64, max_projections, 25, "The maximum number of merge tree projections.", 0) \
#define MAKE_OBSOLETE_MERGE_TREE_SETTING(M, TYPE, NAME, DEFAULT) \
M(TYPE, NAME, DEFAULT, "Obsolete setting, does nothing.", BaseSettingsHelpers::Flags::OBSOLETE)

View File

@ -0,0 +1,39 @@
DROP TABLE IF EXISTS test_max_mt_projections_alter;
CREATE TABLE test_max_mt_projections_alter (c1 UInt32, c2 UInt32, c3 UInt32)
ENGINE = MergeTree ORDER BY c1
SETTINGS max_projections = 3;
ALTER TABLE test_max_mt_projections_alter ADD PROJECTION p1 (SELECT c2 ORDER BY c2);
ALTER TABLE test_max_mt_projections_alter ADD PROJECTION p2 (SELECT c3 ORDER BY c3);
ALTER TABLE test_max_mt_projections_alter ADD PROJECTION p3 (SELECT c1, c2 ORDER BY c1, c2);
ALTER TABLE test_max_mt_projections_alter
ADD PROJECTION p4 (SELECT c2, c3 ORDER BY c2, c3); -- { serverError LIMIT_EXCEEDED }
ALTER TABLE test_max_mt_projections_alter DROP PROJECTION p3;
ALTER TABLE test_max_mt_projections_alter ADD PROJECTION p4 (SELECT c2, c3 ORDER BY c2, c3);
DROP TABLE IF EXISTS test_max_mt_projections_alter;
DROP TABLE IF EXISTS test_max_mt_projections_create;
CREATE TABLE test_max_mt_projections_create (c1 UInt32, c2 UInt32,
PROJECTION p1 (SELECT c1, c2 ORDER BY c2),
PROJECTION p2 (SELECT c2 ORDER BY c2))
ENGINE = MergeTree ORDER BY c1
SETTINGS max_projections = 1; -- { serverError LIMIT_EXCEEDED }
CREATE TABLE test_max_mt_projections_create (c1 UInt32, c2 UInt32,
PROJECTION p (SELECT c1, c2 ORDER BY c2))
ENGINE = MergeTree ORDER BY c1
SETTINGS max_projections = 0; -- { serverError LIMIT_EXCEEDED }
CREATE TABLE test_max_mt_projections_create (c1 UInt32, c2 UInt32,
PROJECTION p (SELECT c1, c2 ORDER BY c2))
ENGINE = MergeTree ORDER BY c1
SETTINGS max_projections = 1;
ALTER TABLE test_max_mt_projections_create
ADD PROJECTION p2 (SELECT c2 ORDER BY c2); -- { serverError LIMIT_EXCEEDED }
DROP TABLE IF EXISTS test_max_mt_projections_create;