Check projection metadata the same way we check ordinary metadata. (#52361)

* Check projection metadata the same way we check ordinary metadata.

* Allow aggregate projection to have empty PK

---------

Co-authored-by: Alexander Tokmakov <tavplubix@clickhouse.com>
This commit is contained in:
Nikolai Kochetov 2023-07-21 15:23:04 +02:00 committed by GitHub
parent 0db9c79886
commit b5cf644668
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 13 additions and 31 deletions

View File

@ -465,9 +465,10 @@ void MergeTreeData::checkProperties(
const StorageInMemoryMetadata & new_metadata,
const StorageInMemoryMetadata & old_metadata,
bool attach,
bool allow_empty_sorting_key,
ContextPtr local_context) const
{
if (!new_metadata.sorting_key.definition_ast)
if (!new_metadata.sorting_key.definition_ast && !allow_empty_sorting_key)
throw Exception(ErrorCodes::BAD_ARGUMENTS, "ORDER BY cannot be empty");
KeyDescription new_sorting_key = new_metadata.sorting_key;
@ -580,6 +581,9 @@ 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));
/// 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, local_context);
projections_names.insert(projection.name);
}
}
@ -593,7 +597,7 @@ void MergeTreeData::setProperties(
bool attach,
ContextPtr local_context)
{
checkProperties(new_metadata, old_metadata, attach, local_context);
checkProperties(new_metadata, old_metadata, attach, false, local_context);
setInMemoryMetadata(new_metadata);
}
@ -3286,7 +3290,7 @@ void MergeTreeData::checkAlterIsPossible(const AlterCommands & commands, Context
}
}
checkProperties(new_metadata, old_metadata, false, local_context);
checkProperties(new_metadata, old_metadata, false, false, local_context);
checkTTLExpressions(new_metadata, old_metadata);
if (!columns_to_check_conversion.empty())

View File

@ -1229,7 +1229,7 @@ protected:
/// The same for clearOldTemporaryDirectories.
std::mutex clear_old_temporary_directories_mutex;
void checkProperties(const StorageInMemoryMetadata & new_metadata, const StorageInMemoryMetadata & old_metadata, bool attach = false, ContextPtr local_context = nullptr) const;
void checkProperties(const StorageInMemoryMetadata & new_metadata, const StorageInMemoryMetadata & old_metadata, bool attach, bool allow_empty_sorting_key, ContextPtr local_context) const;
void setProperties(const StorageInMemoryMetadata & new_metadata, const StorageInMemoryMetadata & old_metadata, bool attach = false, ContextPtr local_context = nullptr);

View File

@ -86,20 +86,4 @@ CREATE TABLE test
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(coverage)
ORDER BY (coverage, situation_name, NAME_toe, NAME_cockroach);
insert into test select * from generateRandom() limit 10;
with dissonance as (
Select cast(toStartOfInterval(coverage, INTERVAL 1 day) as Date) as flour, count() as regulation
from test
group by flour having flour >= toDate(now())-100
),
cheetah as (
Select flour, regulation from dissonance
union distinct
Select toDate(now())-1, ifnull((select regulation from dissonance where flour = toDate(now())-1),0) as regulation
)
Select flour, regulation from cheetah order by flour with fill step 1 limit 100 format Null;
drop table test;
ORDER BY (coverage, situation_name, NAME_toe, NAME_cockroach); -- { serverError BAD_ARGUMENTS }

View File

@ -88,12 +88,4 @@ CREATE TABLE test
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(timestamp)
ORDER BY (xxxx17, xxxx14, xxxx16, toStartOfDay(timestamp), left(xxxx19, 10), timestamp);
INSERT INTO test SELECT * replace 1 as xxxx16 replace 1 as xxxx1 replace '2022-02-02 01:00:00' as timestamp replace 'Airtel' as xxxx14 FROM generateRandom() LIMIT 100;
INSERT INTO test SELECT * replace 1 as xxxx16 replace 1 as xxxx1 replace '2022-02-02 01:00:00' as timestamp replace 'BSNL' as xxxx14 FROM generateRandom() LIMIT 100;
INSERT INTO test SELECT * replace 1 as xxxx16 replace 1 as xxxx1 replace '2022-02-02 01:00:00' as timestamp replace 'xxx' as xxxx14 FROM generateRandom() LIMIT 100;
select sum(1) from test where toStartOfInterval(timestamp, INTERVAL 1 day) >= TIMESTAMP '2022-02-01 01:00:00' and xxxx14 in ('Airtel', 'BSNL') and xxxx1 = 1 GROUP BY xxxx16;
drop table test;
ORDER BY (xxxx17, xxxx14, xxxx16, toStartOfDay(timestamp), left(xxxx19, 10), timestamp); -- { serverError BAD_ARGUMENTS}

View File

@ -0,0 +1,3 @@
create table kek (uuid FixedString(16), id int, ns String, dt DateTime64(6), projection null_pk (select * order by ns, 1, 4)) engine=MergeTree order by (id, dt, uuid); -- {serverError ILLEGAL_COLUMN }
-- this query could segfault or throw LOGICAL_ERROR previously, when we did not check projection PK
-- insert into kek select * from generageRandom(10000);