From b76779797af4a7684a973ed9b3b4b3c4acb27ba0 Mon Sep 17 00:00:00 2001 From: vdimir Date: Wed, 18 Jan 2023 12:17:30 +0000 Subject: [PATCH] Do not move to prewhere in select with joins --- src/Interpreters/InterpreterSelectQuery.cpp | 5 ++- .../02534_join_prewhere_bug_44062.reference | 38 ++++++++++++++++ .../02534_join_prewhere_bug_44062.sql | 43 +++++++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 tests/queries/0_stateless/02534_join_prewhere_bug_44062.reference create mode 100644 tests/queries/0_stateless/02534_join_prewhere_bug_44062.sql diff --git a/src/Interpreters/InterpreterSelectQuery.cpp b/src/Interpreters/InterpreterSelectQuery.cpp index 48326afda45..6477188ec59 100644 --- a/src/Interpreters/InterpreterSelectQuery.cpp +++ b/src/Interpreters/InterpreterSelectQuery.cpp @@ -560,7 +560,10 @@ InterpreterSelectQuery::InterpreterSelectQuery( view = nullptr; } - if (try_move_to_prewhere && storage && storage->canMoveConditionsToPrewhere() && query.where() && !query.prewhere()) + if (try_move_to_prewhere + && storage && storage->canMoveConditionsToPrewhere() + && query.where() && !query.prewhere() + && !query.hasJoin()) /// Join may produce rows with nulls or default values, it's difficult to analyze if they affected or not. { /// PREWHERE optimization: transfer some condition from WHERE to PREWHERE if enabled and viable if (const auto & column_sizes = storage->getColumnSizes(); !column_sizes.empty()) diff --git a/tests/queries/0_stateless/02534_join_prewhere_bug_44062.reference b/tests/queries/0_stateless/02534_join_prewhere_bug_44062.reference new file mode 100644 index 00000000000..aaef17371d8 --- /dev/null +++ b/tests/queries/0_stateless/02534_join_prewhere_bug_44062.reference @@ -0,0 +1,38 @@ +-- { echoOn } + +SELECT * FROM test1 LEFT JOIN test2 ON test1.col1 = test2.col1 +WHERE test2.col1 IS NULL +ORDER BY test2.col1 +; +12321 -30 \N \N +SELECT * FROM test2 RIGHT JOIN test1 ON test2.col1 = test1.col1 +WHERE test2.col1 IS NULL +ORDER BY test2.col1 +; +\N \N 12321 -30 +SELECT * FROM test1 LEFT JOIN test2 ON test1.col1 = test2.col1 +WHERE test2.col1 IS NOT NULL +ORDER BY test2.col1 +; +123 123 123 5600 +321 -32 321 5601 +SELECT * FROM test2 RIGHT JOIN test1 ON test2.col1 = test1.col1 +WHERE test2.col1 IS NOT NULL +ORDER BY test2.col1 +; +123 5600 123 123 +321 5601 321 -32 +SELECT test2.col1, test1.* FROM test2 RIGHT JOIN test1 ON test2.col1 = test1.col1 +WHERE test2.col1 IS NOT NULL +ORDER BY test2.col1 +; +123 123 123 +321 321 -32 +SELECT test2.col3, test1.* FROM test2 RIGHT JOIN test1 ON test2.col1 = test1.col1 +WHERE test2.col1 IS NOT NULL +ORDER BY test2.col1 +; +5600 123 123 +5601 321 -32 +DROP TABLE IF EXISTS test1; +DROP TABLE IF EXISTS test2; diff --git a/tests/queries/0_stateless/02534_join_prewhere_bug_44062.sql b/tests/queries/0_stateless/02534_join_prewhere_bug_44062.sql new file mode 100644 index 00000000000..d68800b0f75 --- /dev/null +++ b/tests/queries/0_stateless/02534_join_prewhere_bug_44062.sql @@ -0,0 +1,43 @@ + +CREATE OR REPLACE TABLE test1 ( `col1` UInt64, `col2` Int8 ) ENGINE = MergeTree ORDER BY col1; +CREATE OR REPLACE TABLE test2 ( `col1` UInt64, `col3` Int16 ) ENGINE = MergeTree ORDER BY col1; + +INSERT INTO test1 VALUES (123, 123), (12321, -30), (321, -32); +INSERT INTO test2 VALUES (123, 5600), (321, 5601); + +SET join_use_nulls = 1; + +-- { echoOn } + +SELECT * FROM test1 LEFT JOIN test2 ON test1.col1 = test2.col1 +WHERE test2.col1 IS NULL +ORDER BY test2.col1 +; + +SELECT * FROM test2 RIGHT JOIN test1 ON test2.col1 = test1.col1 +WHERE test2.col1 IS NULL +ORDER BY test2.col1 +; + +SELECT * FROM test1 LEFT JOIN test2 ON test1.col1 = test2.col1 +WHERE test2.col1 IS NOT NULL +ORDER BY test2.col1 +; + +SELECT * FROM test2 RIGHT JOIN test1 ON test2.col1 = test1.col1 +WHERE test2.col1 IS NOT NULL +ORDER BY test2.col1 +; + +SELECT test2.col1, test1.* FROM test2 RIGHT JOIN test1 ON test2.col1 = test1.col1 +WHERE test2.col1 IS NOT NULL +ORDER BY test2.col1 +; + +SELECT test2.col3, test1.* FROM test2 RIGHT JOIN test1 ON test2.col1 = test1.col1 +WHERE test2.col1 IS NOT NULL +ORDER BY test2.col1 +; + +DROP TABLE IF EXISTS test1; +DROP TABLE IF EXISTS test2;