From 32e8c11cab7ec5c222073a767d65cceffbd0d3b4 Mon Sep 17 00:00:00 2001 From: vdimir Date: Tue, 14 Sep 2021 15:04:45 +0300 Subject: [PATCH 1/2] Check left join strictness in tryInitDictJoin --- src/Interpreters/TableJoin.cpp | 10 +++++++++- .../0_stateless/01115_join_with_dictionary.reference | 6 ++++++ .../queries/0_stateless/01115_join_with_dictionary.sql | 2 ++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Interpreters/TableJoin.cpp b/src/Interpreters/TableJoin.cpp index 9194de3073a..b0c89adee45 100644 --- a/src/Interpreters/TableJoin.cpp +++ b/src/Interpreters/TableJoin.cpp @@ -339,8 +339,16 @@ static std::optional getDictKeyName(const String & dict_name , ContextPt bool TableJoin::tryInitDictJoin(const Block & sample_block, ContextPtr context) { + using Strictness = ASTTableJoin::Strictness; + + bool allowed_inner = isInner(kind()) && strictness() == Strictness::All; + bool allowed_left = isLeft(kind()) && (strictness() == Strictness::Any || + strictness() == Strictness::All || + strictness() == Strictness::Semi || + strictness() == Strictness::Anti); + /// Support ALL INNER, [ANY | ALL | SEMI | ANTI] LEFT - if (!isLeft(kind()) && !(isInner(kind()) && strictness() == ASTTableJoin::Strictness::All)) + if (!allowed_inner && !allowed_left) return false; const Names & right_keys = keyNamesRight(); diff --git a/tests/queries/0_stateless/01115_join_with_dictionary.reference b/tests/queries/0_stateless/01115_join_with_dictionary.reference index 77f7ba193c0..76337bdfc0b 100644 --- a/tests/queries/0_stateless/01115_join_with_dictionary.reference +++ b/tests/queries/0_stateless/01115_join_with_dictionary.reference @@ -16,6 +16,12 @@ flat: any left 2 2 2 2 3 3 3 3 4 0 0 +flat: any left + any_join_distinct_right_table_keys +0 0 0 0 +1 1 1 1 +2 2 2 2 +3 3 3 3 +4 0 0 flat: semi left 0 0 0 0 1 1 1 1 diff --git a/tests/queries/0_stateless/01115_join_with_dictionary.sql b/tests/queries/0_stateless/01115_join_with_dictionary.sql index 0c84d372f6d..8d8589d6085 100644 --- a/tests/queries/0_stateless/01115_join_with_dictionary.sql +++ b/tests/queries/0_stateless/01115_join_with_dictionary.sql @@ -33,6 +33,8 @@ SELECT 'flat: left'; SELECT * FROM (SELECT number AS key FROM numbers(5)) s1 LEFT JOIN dict_flat d USING(key) ORDER BY key; SELECT 'flat: any left'; SELECT * FROM (SELECT number AS key FROM numbers(5)) s1 ANY LEFT JOIN dict_flat d USING(key) ORDER BY key; +SELECT 'flat: any left + any_join_distinct_right_table_keys'; -- falls back to regular join +SELECT * FROM (SELECT number AS key FROM numbers(5)) s1 ANY LEFT JOIN dict_flat d USING(key) ORDER BY key SETTINGS any_join_distinct_right_table_keys = '1'; SELECT 'flat: semi left'; SELECT * FROM (SELECT number AS key FROM numbers(5)) s1 SEMI JOIN dict_flat d USING(key) ORDER BY key; SELECT 'flat: anti left'; From 2aef13e8027d1434f02cc8b60cb29605657bec9b Mon Sep 17 00:00:00 2001 From: vdimir Date: Tue, 14 Sep 2021 15:05:09 +0300 Subject: [PATCH 2/2] Update error messages for logical errors in HashJoin --- src/Interpreters/HashJoin.cpp | 10 +++++----- src/Parsers/ASTTablesInSelectQuery.h | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Interpreters/HashJoin.cpp b/src/Interpreters/HashJoin.cpp index 1c450d531d6..2ea9369f476 100644 --- a/src/Interpreters/HashJoin.cpp +++ b/src/Interpreters/HashJoin.cpp @@ -1095,7 +1095,7 @@ IColumn::Filter dictionaryJoinRightColumns(const TableJoin & table_join, AddedCo std::move(key_getter), nullptr, added_columns, null_map, flags); } - throw Exception("Logical error: wrong JOIN combination", ErrorCodes::LOGICAL_ERROR); + throw Exception(ErrorCodes::LOGICAL_ERROR, "Wrong JOIN combination: {} {}", STRICTNESS, KIND); } } /// nameless @@ -1414,13 +1414,13 @@ void HashJoin::joinBlock(Block & block, ExtraBlockPtr & not_processed) joinBlockImpl(block, key_names_left, sample_block_with_columns_to_add, map); break; default: - throw Exception("Logical error: wrong JOIN combination", ErrorCodes::LOGICAL_ERROR); + throw Exception(ErrorCodes::LOGICAL_ERROR, "Wrong JOIN combination: dictionary + {} {}", strictness, kind); } } else if (kind == Kind::Inner && strictness == Strictness::All) joinBlockImpl(block, key_names_left, sample_block_with_columns_to_add, map); else - throw Exception("Logical error: wrong JOIN combination", ErrorCodes::LOGICAL_ERROR); + throw Exception(ErrorCodes::LOGICAL_ERROR, "Wrong JOIN combination: dictionary + {} {}", strictness, kind); } else if (joinDispatch(kind, strictness, data->maps, [&](auto kind_, auto strictness_, auto & map) { @@ -1432,7 +1432,7 @@ void HashJoin::joinBlock(Block & block, ExtraBlockPtr & not_processed) else if (kind == ASTTableJoin::Kind::Cross) joinBlockImplCross(block, not_processed); else - throw Exception("Logical error: unknown combination of JOIN", ErrorCodes::LOGICAL_ERROR); + throw Exception(ErrorCodes::LOGICAL_ERROR, "Wrong JOIN combination: {} {}", strictness, kind); } template @@ -1494,7 +1494,7 @@ public: }; if (!joinDispatch(parent.kind, parent.strictness, parent.data->maps, fill_callback)) - throw Exception("Logical error: unknown JOIN strictness (must be on of: ANY, ALL, ASOF)", ErrorCodes::LOGICAL_ERROR); + throw Exception(ErrorCodes::LOGICAL_ERROR, "Unknown JOIN strictness '{}' (must be on of: ANY, ALL, ASOF)", parent.strictness); fillNullsFromBlocks(columns_right, rows_added); return rows_added; diff --git a/src/Parsers/ASTTablesInSelectQuery.h b/src/Parsers/ASTTablesInSelectQuery.h index 8b489974804..9d31ca6f653 100644 --- a/src/Parsers/ASTTablesInSelectQuery.h +++ b/src/Parsers/ASTTablesInSelectQuery.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace DB