Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix crash in StorageJoin (add restriction) #8479

Merged
merged 4 commits into from Dec 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 7 additions & 1 deletion dbms/src/Storages/StorageJoin.cpp
Expand Up @@ -10,6 +10,7 @@
#include <Interpreters/joinDispatch.h>
#include <Interpreters/AnalyzedJoin.h>
#include <Common/assert_cast.h>
#include <Common/quoteString.h>

#include <Poco/String.h> /// toLower
#include <Poco/File.h>
Expand Down Expand Up @@ -71,7 +72,12 @@ void StorageJoin::truncate(const ASTPtr &, const Context &, TableStructureWriteL
HashJoinPtr StorageJoin::getJoin(std::shared_ptr<AnalyzedJoin> analyzed_join) const
{
if (kind != analyzed_join->kind() || strictness != analyzed_join->strictness())
throw Exception("Table " + table_name + " has incompatible type of JOIN.", ErrorCodes::INCOMPATIBLE_TYPE_OF_JOIN);
throw Exception("Table " + backQuote(table_name) + " has incompatible type of JOIN.", ErrorCodes::INCOMPATIBLE_TYPE_OF_JOIN);

if ((analyzed_join->forceNullableRight() && !use_nulls) ||
(!analyzed_join->forceNullableRight() && isLeftOrFull(analyzed_join->kind()) && use_nulls))
throw Exception("Table " + backQuote(table_name) + " needs the same join_use_nulls setting as present in LEFT or FULL JOIN.",
ErrorCodes::INCOMPATIBLE_TYPE_OF_JOIN);

/// TODO: check key columns

Expand Down
58 changes: 58 additions & 0 deletions dbms/tests/queries/0_stateless/01051_all_join_engine.reference
Expand Up @@ -30,3 +30,61 @@ full
4 a5 b4
4 a5 b5
5 b6
inner (join_use_nulls mix)
2 a3 b1
2 a3 b2
4 a5 b3
4 a5 b4
4 a5 b5
right (join_use_nulls mix)
2 a3 b1
2 a3 b2
4 a5 b3
4 a5 b4
4 a5 b5
5 \N b6
left (join_use_nulls)
0 a1 \N
1 a2 \N
2 a3 b1
2 a3 b2
3 a4 \N
4 a5 b3
4 a5 b4
4 a5 b5
inner (join_use_nulls)
2 a3 b1
2 a3 b2
4 a5 b3
4 a5 b4
4 a5 b5
right (join_use_nulls)
2 a3 b1
2 a3 b2
4 a5 b3
4 a5 b4
4 a5 b5
5 \N b6
full (join_use_nulls)
0 a1 \N
1 a2 \N
2 a3 b1
2 a3 b2
3 a4 \N
4 a5 b3
4 a5 b4
4 a5 b5
5 \N b6
inner (join_use_nulls mix2)
2 a3 b1
2 a3 b2
4 a5 b3
4 a5 b4
4 a5 b5
right (join_use_nulls mix2)
2 a3 b1
2 a3 b2
4 a5 b3
4 a5 b4
4 a5 b5
5 b6
62 changes: 48 additions & 14 deletions dbms/tests/queries/0_stateless/01051_all_join_engine.sql
Expand Up @@ -33,20 +33,54 @@ SELECT * FROM t1 RIGHT JOIN right_join j USING(x) ORDER BY x, str, s;
SELECT 'full';
SELECT * FROM t1 FULL JOIN full_join j USING(x) ORDER BY x, str, s;

-- TODO
-- SET join_use_nulls = 1;
--
-- SELECT 'left (join_use_nulls)';
-- SELECT * FROM t1 LEFT JOIN left_join j USING(x) ORDER BY x, str, s;
--
-- SELECT 'inner (join_use_nulls)';
-- SELECT * FROM t1 INNER JOIN inner_join j USING(x) ORDER BY x, str, s;
--
-- SELECT 'right (join_use_nulls)';
-- SELECT * FROM t1 RIGHT JOIN right_join j USING(x) ORDER BY x, str, s;
--
-- SELECT 'full (join_use_nulls)';
-- SELECT * FROM t1 FULL JOIN full_join j USING(x) ORDER BY x, str, s;
SET join_use_nulls = 1;

SELECT * FROM t1 LEFT JOIN left_join j USING(x) ORDER BY x, str, s; -- { serverError 264 }
SELECT * FROM t1 FULL JOIN full_join j USING(x) ORDER BY x, str, s; -- { serverError 264 }

SELECT 'inner (join_use_nulls mix)';
SELECT * FROM t1 INNER JOIN inner_join j USING(x) ORDER BY x, str, s;

SELECT 'right (join_use_nulls mix)';
SELECT * FROM t1 RIGHT JOIN right_join j USING(x) ORDER BY x, str, s;

DROP TABLE left_join;
DROP TABLE inner_join;
DROP TABLE right_join;
DROP TABLE full_join;

CREATE TABLE left_join (x UInt32, s String) engine = Join(ALL, LEFT, x) SETTINGS join_use_nulls = 1;
CREATE TABLE inner_join (x UInt32, s String) engine = Join(ALL, INNER, x) SETTINGS join_use_nulls = 1;
CREATE TABLE right_join (x UInt32, s String) engine = Join(ALL, RIGHT, x) SETTINGS join_use_nulls = 1;
CREATE TABLE full_join (x UInt32, s String) engine = Join(ALL, FULL, x) SETTINGS join_use_nulls = 1;

INSERT INTO left_join (x, s) VALUES (2, 'b1'), (2, 'b2'), (4, 'b3'), (4, 'b4'), (4, 'b5'), (5, 'b6');
INSERT INTO inner_join (x, s) VALUES (2, 'b1'), (2, 'b2'), (4, 'b3'), (4, 'b4'), (4, 'b5'), (5, 'b6');
INSERT INTO right_join (x, s) VALUES (2, 'b1'), (2, 'b2'), (4, 'b3'), (4, 'b4'), (4, 'b5'), (5, 'b6');
INSERT INTO full_join (x, s) VALUES (2, 'b1'), (2, 'b2'), (4, 'b3'), (4, 'b4'), (4, 'b5'), (5, 'b6');

SELECT 'left (join_use_nulls)';
SELECT * FROM t1 LEFT JOIN left_join j USING(x) ORDER BY x, str, s;

SELECT 'inner (join_use_nulls)';
SELECT * FROM t1 INNER JOIN inner_join j USING(x) ORDER BY x, str, s;

SELECT 'right (join_use_nulls)';
SELECT * FROM t1 RIGHT JOIN right_join j USING(x) ORDER BY x, str, s;

SELECT 'full (join_use_nulls)';
SELECT * FROM t1 FULL JOIN full_join j USING(x) ORDER BY x, str, s;

SET join_use_nulls = 0;

SELECT * FROM t1 LEFT JOIN left_join j USING(x) ORDER BY x, str, s; -- { serverError 264 }
SELECT * FROM t1 FULL JOIN full_join j USING(x) ORDER BY x, str, s; -- { serverError 264 }

SELECT 'inner (join_use_nulls mix2)';
SELECT * FROM t1 INNER JOIN inner_join j USING(x) ORDER BY x, str, s;

SELECT 'right (join_use_nulls mix2)';
SELECT * FROM t1 RIGHT JOIN right_join j USING(x) ORDER BY x, str, s;

DROP TABLE t1;

Expand Down