Analyzer: Storage Join support joining with nullable columns

This commit is contained in:
vdimir 2024-07-23 10:36:08 +00:00
parent 77c253634a
commit 383221b04d
No known key found for this signature in database
GPG Key ID: 6EE4CE2BEDC51862
3 changed files with 114 additions and 1 deletions

View File

@ -494,6 +494,12 @@ JoinClausesAndActions buildJoinClausesAndActions(
necessary_names.push_back(name);
};
bool is_join_with_special_storage = false;
if (const auto * right_table_node = join_node.getRightTableExpression()->as<TableNode>())
{
is_join_with_special_storage = dynamic_cast<const StorageJoin *>(right_table_node->getStorage().get());
}
for (auto & join_clause : result.join_clauses)
{
const auto & left_filter_condition_nodes = join_clause.getLeftFilterConditionNodes();
@ -561,7 +567,7 @@ JoinClausesAndActions buildJoinClausesAndActions(
if (!left_key_node->result_type->equals(*common_type))
left_key_node = &left_join_actions->addCast(*left_key_node, common_type, {});
if (!right_key_node->result_type->equals(*common_type))
if (!is_join_with_special_storage && !right_key_node->result_type->equals(*common_type))
right_key_node = &right_join_actions->addCast(*right_key_node, common_type, {});
}

View File

@ -0,0 +1,23 @@
-----
1 1 1 a 1 A 1 A
2 2 2 b 2 B 2 B
-----
\N \N \N 0 3 B
1 1 1 a 1 A 1 A
2 2 2 b 2 B 2 B
-----
1 1 1 a 1 A 1 A
2 2 2 b 2 B 2 B
\N \N \N \N 3 B \N \N
\N \N \N \N \N \N 3 B
-----
\N \N \N 3 3 B 0 0
\N \N \N 0 0 3 3 B
1 1 1 a 1 1 A 1 1 A
2 2 2 b 2 2 B 2 2 B
-----
3 3 \N B B
1 1 1 a A A
2 2 2 b B B
-----
7

View File

@ -0,0 +1,84 @@
#!/usr/bin/env -S ${HOME}/clickhouse-client --queries-file
DROP TABLE IF EXISTS tab;
CREATE TABLE tab ( `k` Nullable(UInt32), `k1` Nullable(UInt32), `k2` Nullable(UInt32), `v` String ) ENGINE = Memory;
INSERT INTO tab VALUES (1, 1, 1, 'a'), (2, 2, 2, 'b');
DROP TABLE IF EXISTS mem;
CREATE TABLE mem ( `k` UInt64, `v` String ) ENGINE = Join(ANY, LEFT, k);
INSERT INTO mem VALUES (1, 'A'), (2, 'B'), (3, 'B');
DROP TABLE IF EXISTS mem2;
CREATE TABLE mem2 ( `k` UInt64, `v` String ) ENGINE = Join(ANY, RIGHT, k);
INSERT INTO mem2 VALUES (1, 'A'), (2, 'B'), (3, 'B');
DROP TABLE IF EXISTS mem3;
CREATE TABLE mem3 ( `k` UInt64, `v` String ) ENGINE = Join(ALL, FULL, k) SETTINGS join_use_nulls = 1;
INSERT INTO mem3 VALUES (1, 'A'), (2, 'B'), (3, 'B');
DROP TABLE IF EXISTS mem4;
CREATE TABLE mem4 ( `k1` UInt64, `k2` UInt64, `v` String ) ENGINE = Join(ALL, FULL, k1, k2);
INSERT INTO mem4 VALUES (1, 1, 'A'), (2, 2, 'B'), (3, 3, 'B');
SET allow_experimental_analyzer = 1;
SELECT '-----';
SELECT *
FROM tab
ANY LEFT JOIN mem ON k1 = mem.k
ANY LEFT JOIN mem AS t ON k2 = t.k
ORDER BY tab.v
;
SELECT '-----';
SELECT *
FROM tab
ANY LEFT JOIN mem ON k1 = mem.k
ANY RIGHT JOIN mem2 ON k2 = mem2.k
ORDER BY tab.v
;
SELECT '-----';
SELECT *
FROM tab
FULL JOIN mem3 AS t1 ON k1 = t1.k
FULL JOIN mem3 AS t2 ON k2 = t2.k
ORDER BY tab.v
SETTINGS join_use_nulls = 1
;
SELECT '-----';
SELECT *
FROM tab
FULL JOIN mem4 AS t1 ON tab.k1 = t1.k1 AND tab.k2 = t1.k2
FULL JOIN mem4 AS t2 ON tab.k1 = t2.k1 AND tab.k2 = t2.k2
ORDER BY tab.v
;
SELECT '-----';
SELECT *
FROM tab
FULL JOIN mem4 AS t1 USING (k1, k2)
FULL JOIN mem4 AS t2 USING (k1, k2)
ORDER BY tab.v
;
SELECT '-----';
SELECT count() FROM (
EXPLAIN PLAN
SELECT * FROM tab
ANY LEFT JOIN mem AS t1 ON tab.k = t1.k
ANY LEFT JOIN mem AS t2 ON tab.k = t2.k
ANY LEFT JOIN mem AS t3 ON tab.k = t3.k
ANY LEFT JOIN mem AS t4 ON tab.k = t4.k
ANY RIGHT JOIN mem2 AS t5 ON tab.k = t5.k
ANY LEFT JOIN mem AS t6 ON tab.k = t6.k
ANY LEFT JOIN mem AS t7 ON tab.k = t7.k
)
WHERE explain like '%FilledJoin%'
;