diff --git a/src/Interpreters/IJoin.h b/src/Interpreters/IJoin.h index c2cf007d823..8fa85de4951 100644 --- a/src/Interpreters/IJoin.h +++ b/src/Interpreters/IJoin.h @@ -37,7 +37,7 @@ public: virtual size_t getTotalRowCount() const = 0; virtual size_t getTotalByteCount() const = 0; - virtual bool alwaysReturnsEmptySet() const { return false; } + virtual bool alwaysReturnsEmptySet() const = 0; /// StorageJoin/Dictionary is already filled. No need to call addJoinedBlock. /// Different query plan is used for such joins. diff --git a/src/Interpreters/MergeJoin.h b/src/Interpreters/MergeJoin.h index 11e5dc86dc2..844c730de4f 100644 --- a/src/Interpreters/MergeJoin.h +++ b/src/Interpreters/MergeJoin.h @@ -32,6 +32,8 @@ public: size_t getTotalRowCount() const override { return right_blocks.row_count; } size_t getTotalByteCount() const override { return right_blocks.bytes; } + /// Has to be called only after setTotals()/mergeRightBlocks() + bool alwaysReturnsEmptySet() const override { return (is_right || is_inner) && min_max_right_blocks.empty(); } BlockInputStreamPtr createStreamWithNonJoinedRows(const Block & result_sample_block, UInt64 max_block_size) const override; diff --git a/tests/queries/0_stateless/01015_empty_in_inner_right_join.reference b/tests/queries/0_stateless/01015_empty_in_inner_right_join.reference index f41483b25da..1aa2f963bd7 100644 --- a/tests/queries/0_stateless/01015_empty_in_inner_right_join.reference +++ b/tests/queries/0_stateless/01015_empty_in_inner_right_join.reference @@ -15,3 +15,20 @@ multiple sets INNER JOIN empty set AND IN non-empty set 0 multiple sets INNER JOIN non-empty set AND IN non-empty set 1 IN empty set equals 0 10 IN empty set sum if 10 +IN empty set 0 +IN non-empty set 1 +NOT IN empty set 10 +INNER JOIN empty set 0 +INNER JOIN non-empty set 1 +RIGHT JOIN empty set 0 +RIGHT JOIN non-empty set 1 +LEFT JOIN empty set 10 +LEFT JOIN non-empty set 10 +multiple sets IN empty set OR IN non-empty set 1 +multiple sets IN empty set OR NOT IN non-empty set 9 +multiple sets NOT IN empty set AND IN non-empty set 1 +multiple sets INNER JOIN empty set AND IN empty set 0 +multiple sets INNER JOIN empty set AND IN non-empty set 0 +multiple sets INNER JOIN non-empty set AND IN non-empty set 1 +IN empty set equals 0 10 +IN empty set sum if 10 diff --git a/tests/queries/0_stateless/01015_empty_in_inner_right_join.sql b/tests/queries/0_stateless/01015_empty_in_inner_right_join.sql.j2 similarity index 96% rename from tests/queries/0_stateless/01015_empty_in_inner_right_join.sql rename to tests/queries/0_stateless/01015_empty_in_inner_right_join.sql.j2 index e0d06a7e3b6..6c13654598e 100644 --- a/tests/queries/0_stateless/01015_empty_in_inner_right_join.sql +++ b/tests/queries/0_stateless/01015_empty_in_inner_right_join.sql.j2 @@ -1,5 +1,9 @@ SET joined_subquery_requires_alias = 0; +{% for join_algorithm in ['partial_merge', 'hash'] -%} + +SET join_algorithm = '{{ join_algorithm }}'; + SELECT 'IN empty set',count() FROM system.numbers WHERE number IN (SELECT toUInt64(1) WHERE 0); SELECT 'IN non-empty set',count() FROM (SELECT number FROM system.numbers LIMIT 10) t1 WHERE t1.number IN (SELECT toUInt64(1) WHERE 1); SELECT 'NOT IN empty set',count() FROM (SELECT number FROM system.numbers LIMIT 10) WHERE number NOT IN (SELECT toUInt64(1) WHERE 0); @@ -22,3 +26,5 @@ SELECT 'multiple sets INNER JOIN non-empty set AND IN non-empty set',count() FRO SELECT 'IN empty set equals 0', count() FROM numbers(10) WHERE (number IN (SELECT toUInt64(1) WHERE 0)) = 0; SELECT 'IN empty set sum if', sum(if(number IN (SELECT toUInt64(1) WHERE 0), 2, 1)) FROM numbers(10); + +{% endfor -%}