From 593675a7c519bdea15f14fad21cfe6d1b8f38320 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 26 Dec 2022 22:31:41 +0100 Subject: [PATCH] Disable projections in presense of any grouping sets, including WITH ROLLUP, WITH CUBE and WITH TOTALS --- src/Storages/MergeTree/MergeTreeData.cpp | 11 +- src/Storages/SelectQueryInfo.h | 1 - .../02515_projections_with_totals.reference | 3 + .../02515_projections_with_totals.sql | 6 + .../02516_projections_with_rollup.reference | 0 .../02516_projections_with_rollup.sql | 120 ++++++++++++++++++ 6 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 tests/queries/0_stateless/02515_projections_with_totals.reference create mode 100644 tests/queries/0_stateless/02515_projections_with_totals.sql create mode 100644 tests/queries/0_stateless/02516_projections_with_rollup.reference create mode 100644 tests/queries/0_stateless/02516_projections_with_rollup.sql diff --git a/src/Storages/MergeTree/MergeTreeData.cpp b/src/Storages/MergeTree/MergeTreeData.cpp index a8cfc72ad22..0089d06e8d9 100644 --- a/src/Storages/MergeTree/MergeTreeData.cpp +++ b/src/Storages/MergeTree/MergeTreeData.cpp @@ -5982,20 +5982,25 @@ std::optional MergeTreeData::getQueryProcessingStageWithAgg if (select_query->interpolate() && !select_query->interpolate()->children.empty()) return std::nullopt; - // Currently projections don't support GROUPING SET yet. - if (select_query->group_by_with_grouping_sets) + // Projections don't support grouping sets yet. + if (select_query->group_by_with_grouping_sets + || select_query->group_by_with_totals + || select_query->group_by_with_rollup + || select_query->group_by_with_cube) return std::nullopt; auto query_options = SelectQueryOptions( QueryProcessingStage::WithMergeableState, /* depth */ 1, /* is_subquery_= */ true - ).ignoreProjections().ignoreAlias(); + ).ignoreProjections().ignoreAlias(); + InterpreterSelectQuery select( query_ptr, query_context, query_options, query_info.prepared_sets); + const auto & analysis_result = select.getAnalysisResult(); query_info.prepared_sets = select.getQueryAnalyzer()->getPreparedSets(); diff --git a/src/Storages/SelectQueryInfo.h b/src/Storages/SelectQueryInfo.h index bad2539ef07..c93531973b8 100644 --- a/src/Storages/SelectQueryInfo.h +++ b/src/Storages/SelectQueryInfo.h @@ -171,7 +171,6 @@ struct ProjectionCandidate */ struct SelectQueryInfo { - SelectQueryInfo() : prepared_sets(std::make_shared()) {} diff --git a/tests/queries/0_stateless/02515_projections_with_totals.reference b/tests/queries/0_stateless/02515_projections_with_totals.reference new file mode 100644 index 00000000000..c6359cae032 --- /dev/null +++ b/tests/queries/0_stateless/02515_projections_with_totals.reference @@ -0,0 +1,3 @@ +0 + +0 diff --git a/tests/queries/0_stateless/02515_projections_with_totals.sql b/tests/queries/0_stateless/02515_projections_with_totals.sql new file mode 100644 index 00000000000..4d43d5381da --- /dev/null +++ b/tests/queries/0_stateless/02515_projections_with_totals.sql @@ -0,0 +1,6 @@ +DROP TABLE IF EXISTS t; +CREATE TABLE t (x UInt8, PROJECTION p (SELECT x GROUP BY x)) ENGINE = MergeTree ORDER BY (); +INSERT INTO t VALUES (0); +SET group_by_overflow_mode = 'any', max_rows_to_group_by = 1000, totals_mode = 'after_having_auto'; +SELECT x FROM t GROUP BY x WITH TOTALS; +DROP TABLE t; diff --git a/tests/queries/0_stateless/02516_projections_with_rollup.reference b/tests/queries/0_stateless/02516_projections_with_rollup.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/queries/0_stateless/02516_projections_with_rollup.sql b/tests/queries/0_stateless/02516_projections_with_rollup.sql new file mode 100644 index 00000000000..e670fbb7827 --- /dev/null +++ b/tests/queries/0_stateless/02516_projections_with_rollup.sql @@ -0,0 +1,120 @@ +DROP TABLE IF EXISTS video_log; +DROP TABLE IF EXISTS video_log_result__fuzz_0; +DROP TABLE IF EXISTS rng; + +CREATE TABLE video_log +( + `datetime` DateTime, + `user_id` UInt64, + `device_id` UInt64, + `domain` LowCardinality(String), + `bytes` UInt64, + `duration` UInt64 +) +ENGINE = MergeTree +PARTITION BY toDate(datetime) +ORDER BY (user_id, device_id); + +CREATE TABLE video_log_result__fuzz_0 +( + `hour` Nullable(DateTime), + `sum_bytes` UInt64, + `avg_duration` Float64 +) +ENGINE = MergeTree +PARTITION BY toDate(hour) +ORDER BY sum_bytes +SETTINGS allow_nullable_key = 1; + +CREATE TABLE rng +( + `user_id_raw` UInt64, + `device_id_raw` UInt64, + `domain_raw` UInt64, + `bytes_raw` UInt64, + `duration_raw` UInt64 +) +ENGINE = GenerateRandom(1024); + +INSERT INTO video_log SELECT + toUnixTimestamp('2022-07-22 01:00:00') + (rowNumberInAllBlocks() / 20000), + user_id_raw % 100000000 AS user_id, + device_id_raw % 200000000 AS device_id, + domain_raw % 100, + (bytes_raw % 1024) + 128, + (duration_raw % 300) + 100 +FROM rng +LIMIT 1728000; + +INSERT INTO video_log SELECT + toUnixTimestamp('2022-07-22 01:00:00') + (rowNumberInAllBlocks() / 20000), + user_id_raw % 100000000 AS user_id, + 100 AS device_id, + domain_raw % 100, + (bytes_raw % 1024) + 128, + (duration_raw % 300) + 100 +FROM rng +LIMIT 10; + +ALTER TABLE video_log + ADD PROJECTION p_norm + ( + SELECT + datetime, + device_id, + bytes, + duration + ORDER BY device_id + ); + +ALTER TABLE video_log + MATERIALIZE PROJECTION p_norm +SETTINGS mutations_sync = 1; + +ALTER TABLE video_log + ADD PROJECTION p_agg + ( + SELECT + toStartOfHour(datetime) AS hour, + domain, + sum(bytes), + avg(duration) + GROUP BY + hour, + domain + ); + +ALTER TABLE video_log + MATERIALIZE PROJECTION p_agg +SETTINGS mutations_sync = 1; + +-- We are not interested in the result of this query, but it should not produce a logical error. +SELECT + avg_duration1, + avg_duration1 = avg_duration2 +FROM +( + SELECT + sum(bytes), + hour, + toStartOfHour(datetime) AS hour, + avg(duration) AS avg_duration1 + FROM video_log + GROUP BY hour + WITH ROLLUP + WITH TOTALS +) +LEFT JOIN +( + SELECT + hour, + sum_bytes AS sum_bytes2, + avg_duration AS avg_duration2 + FROM video_log_result__fuzz_0 +) USING (hour) +SETTINGS joined_subquery_requires_alias = 0 +FORMAT Null; + +DROP TABLE video_log; +DROP TABLE video_log_result__fuzz_0; +DROP TABLE rng;