Merge pull request #15933 from ClickHouse/fix-global-in-result

Fix wrong result in case of GLOBAL IN and PREWHERE
This commit is contained in:
alexey-milovidov 2020-10-19 21:21:57 +03:00 committed by GitHub
commit be7776608d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 27 additions and 6 deletions

View File

@ -117,11 +117,14 @@ ExpressionAnalyzer::ExpressionAnalyzer(
const TreeRewriterResultPtr & syntax_analyzer_result_,
const Context & context_,
size_t subquery_depth_,
bool do_global)
bool do_global,
SubqueriesForSets subqueries_for_sets_)
: query(query_), context(context_), settings(context.getSettings())
, subquery_depth(subquery_depth_)
, syntax(syntax_analyzer_result_)
{
subqueries_for_sets = std::move(subqueries_for_sets_);
/// external_tables, subqueries_for_sets for global subqueries.
/// Replaces global subqueries with the generated names of temporary tables that will be sent to remote servers.
initGlobalSubqueriesAndExternalTables(do_global);

View File

@ -93,7 +93,7 @@ public:
const ASTPtr & query_,
const TreeRewriterResultPtr & syntax_analyzer_result_,
const Context & context_)
: ExpressionAnalyzer(query_, syntax_analyzer_result_, context_, 0, false)
: ExpressionAnalyzer(query_, syntax_analyzer_result_, context_, 0, false, {})
{}
void appendExpression(ExpressionActionsChain & chain, const ASTPtr & expr, bool only_types);
@ -124,7 +124,8 @@ protected:
const TreeRewriterResultPtr & syntax_analyzer_result_,
const Context & context_,
size_t subquery_depth_,
bool do_global_);
bool do_global_,
SubqueriesForSets subqueries_for_sets_);
ASTPtr query;
const Context & context;
@ -244,8 +245,9 @@ public:
const StorageMetadataPtr & metadata_snapshot_,
const NameSet & required_result_columns_ = {},
bool do_global_ = false,
const SelectQueryOptions & options_ = {})
: ExpressionAnalyzer(query_, syntax_analyzer_result_, context_, options_.subquery_depth, do_global_)
const SelectQueryOptions & options_ = {},
SubqueriesForSets subqueries_for_sets_ = {})
: ExpressionAnalyzer(query_, syntax_analyzer_result_, context_, options_.subquery_depth, do_global_, std::move(subqueries_for_sets_))
, metadata_snapshot(metadata_snapshot_)
, required_result_columns(required_result_columns_)
, query_options(options_)

View File

@ -304,6 +304,8 @@ InterpreterSelectQuery::InterpreterSelectQuery(
if (storage)
view = dynamic_cast<StorageView *>(storage.get());
SubqueriesForSets subquery_for_sets;
auto analyze = [&] (bool try_move_to_prewhere)
{
/// Allow push down and other optimizations for VIEW: replace with subquery and rewrite it.
@ -344,7 +346,7 @@ InterpreterSelectQuery::InterpreterSelectQuery(
query_analyzer = std::make_unique<SelectQueryExpressionAnalyzer>(
query_ptr, syntax_analyzer_result, *context, metadata_snapshot,
NameSet(required_result_column_names.begin(), required_result_column_names.end()),
!options.only_analyze, options);
!options.only_analyze, options, std::move(subquery_for_sets));
if (!options.only_analyze)
{
@ -430,6 +432,7 @@ InterpreterSelectQuery::InterpreterSelectQuery(
if (need_analyze_again)
{
subquery_for_sets = std::move(query_analyzer->getSubqueriesForSets());
/// Do not try move conditions to PREWHERE for the second time.
/// Otherwise, we won't be able to fallback from inefficient PREWHERE to WHERE later.
analyze(/* try_move_to_prewhere = */ false);

View File

@ -0,0 +1 @@
100000

View File

@ -0,0 +1,12 @@
drop table if exists xp;
drop table if exists xp_d;
create table xp(A Date, B Int64, S String) Engine=MergeTree partition by toYYYYMM(A) order by B;
insert into xp select '2020-01-01', number , '' from numbers(100000);
create table xp_d as xp Engine=Distributed(test_shard_localhost, currentDatabase(), xp);
select count() from xp_d prewhere toYYYYMM(A) global in (select toYYYYMM(min(A)) from xp_d) where B > -1;
drop table if exists xp;
drop table if exists xp_d;