From 7a5cfc7a6d22f3152d58dfc5ed1272b1e5245a2d Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Tue, 6 Nov 2018 16:55:41 +0300 Subject: [PATCH] Skip columns from prewhere_info->remove_columns_actions in prewhere result for alias source columns. [#CLICKHOUSE-4111] --- dbms/src/Interpreters/InterpreterSelectQuery.cpp | 11 +++++++++-- dbms/src/Interpreters/InterpreterSelectQuery.h | 6 +++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.cpp b/dbms/src/Interpreters/InterpreterSelectQuery.cpp index 223f6ba2f08..3a381e3f05f 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.cpp +++ b/dbms/src/Interpreters/InterpreterSelectQuery.cpp @@ -323,6 +323,8 @@ InterpreterSelectQuery::AnalysisResult InterpreterSelectQuery::analyzeExpression res.prewhere_info->remove_columns_actions = std::move(actions); } + + res.columns_to_remove_after_prewhere = std::move(columns_to_remove); } if (has_where) res.remove_where_filter = chain.steps.at(where_step_num).can_remove_required_output.at(0); @@ -495,7 +497,7 @@ void InterpreterSelectQuery::executeImpl(Pipeline & pipeline, const BlockInputSt throw Exception("Distributed on Distributed is not supported", ErrorCodes::NOT_IMPLEMENTED); /** Read the data from Storage. from_stage - to what stage the request was completed in Storage. */ - executeFetchColumns(from_stage, pipeline, expressions.prewhere_info); + executeFetchColumns(from_stage, pipeline, expressions.prewhere_info, expressions.columns_to_remove_after_prewhere); LOG_TRACE(log, QueryProcessingStage::toString(from_stage) << " -> " << QueryProcessingStage::toString(to_stage)); } @@ -686,7 +688,8 @@ static void getLimitLengthAndOffset(ASTSelectQuery & query, size_t & length, siz void InterpreterSelectQuery::executeFetchColumns( - QueryProcessingStage::Enum processing_stage, Pipeline & pipeline, const PrewhereInfoPtr & prewhere_info) + QueryProcessingStage::Enum processing_stage, Pipeline & pipeline, + const PrewhereInfoPtr & prewhere_info, const Names & columns_to_remove_after_prewhere) { const Settings & settings = context.getSettingsRef(); @@ -751,11 +754,15 @@ void InterpreterSelectQuery::executeFetchColumns( /// Columns which we will get after prewhere execution. NamesAndTypesList additional_source_columns; /// Add columns which will be added by prewhere (otherwise we will remove them in project action). + NameSet columns_to_remove(columns_to_remove_after_prewhere.begin(), columns_to_remove_after_prewhere.end()); for (const auto & column : prewhere_actions_result) { if (prewhere_info->remove_prewhere_column && column.name == prewhere_info->prewhere_column_name) continue; + if (columns_to_remove.count(column.name)) + continue; + required_columns_expr_list->children.emplace_back(std::make_shared(column.name)); additional_source_columns.emplace_back(column.name, column.type); } diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.h b/dbms/src/Interpreters/InterpreterSelectQuery.h index 7ae577979d1..d593c49e4ae 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.h +++ b/dbms/src/Interpreters/InterpreterSelectQuery.h @@ -150,6 +150,9 @@ private: /// Columns from the SELECT list, before renaming them to aliases. Names selected_columns; + /// Columns will be removed after prewhere actions execution. + Names columns_to_remove_after_prewhere; + /// Do I need to perform the first part of the pipeline - running on remote servers during distributed processing. bool first_stage = false; /// Do I need to execute the second part of the pipeline - running on the initiating server during distributed processing. @@ -171,7 +174,8 @@ private: /// dry_run - don't read from table, use empty header block instead. void executeWithMultipleStreamsImpl(Pipeline & pipeline, const BlockInputStreamPtr & input, bool dry_run); - void executeFetchColumns(QueryProcessingStage::Enum processing_stage, Pipeline & pipeline, const PrewhereInfoPtr & prewhere_info); + void executeFetchColumns(QueryProcessingStage::Enum processing_stage, Pipeline & pipeline, + const PrewhereInfoPtr & prewhere_info, const Names & columns_to_remove_after_prewhere); void executeWhere(Pipeline & pipeline, const ExpressionActionsPtr & expression, bool remove_filter); void executeAggregation(Pipeline & pipeline, const ExpressionActionsPtr & expression, bool overflow_row, bool final);