Fix JOIN over LC and Nullable in key (#11414)

This commit is contained in:
Artem Zuikov 2020-06-04 13:07:22 +03:00 committed by GitHub
parent dad84af70f
commit 6cdeb060fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 90 additions and 4 deletions

View File

@ -512,7 +512,8 @@ void ActionsMatcher::visit(const ASTFunction & node, const ASTPtr & ast, Data &
if (data.only_consts) if (data.only_consts)
arguments_present = false; arguments_present = false;
else else
throw Exception("Unknown identifier: " + child_column_name, ErrorCodes::UNKNOWN_IDENTIFIER); throw Exception("Unknown identifier: " + child_column_name + " there are columns: " + data.getSampleBlock().dumpNames(),
ErrorCodes::UNKNOWN_IDENTIFIER);
} }
} }
} }

View File

@ -107,7 +107,7 @@ static ColumnWithTypeAndName correctNullability(ColumnWithTypeAndName && column,
{ {
if (nullable) if (nullable)
{ {
JoinCommon::convertColumnToNullable(column); JoinCommon::convertColumnToNullable(column, true);
if (column.type->isNullable() && !negative_null_map.empty()) if (column.type->isNullable() && !negative_null_map.empty())
{ {
MutableColumnPtr mutable_column = IColumn::mutate(std::move(column.column)); MutableColumnPtr mutable_column = IColumn::mutate(std::move(column.column));

View File

@ -16,8 +16,14 @@ namespace ErrorCodes
namespace JoinCommon namespace JoinCommon
{ {
void convertColumnToNullable(ColumnWithTypeAndName & column) void convertColumnToNullable(ColumnWithTypeAndName & column, bool low_card_nullability)
{ {
if (low_card_nullability && column.type->lowCardinality())
{
column.column = recursiveRemoveLowCardinality(column.column);
column.type = recursiveRemoveLowCardinality(column.type);
}
if (column.type->isNullable() || !column.type->canBeInsideNullable()) if (column.type->isNullable() || !column.type->canBeInsideNullable())
return; return;

View File

@ -13,7 +13,7 @@ using ColumnRawPtrs = std::vector<const IColumn *>;
namespace JoinCommon namespace JoinCommon
{ {
void convertColumnToNullable(ColumnWithTypeAndName & column); void convertColumnToNullable(ColumnWithTypeAndName & column, bool low_card_nullability = false);
void convertColumnsToNullable(Block & block, size_t starting_pos = 0); void convertColumnsToNullable(Block & block, size_t starting_pos = 0);
void removeColumnNullability(ColumnWithTypeAndName & column); void removeColumnNullability(ColumnWithTypeAndName & column);
Columns materializeColumns(const Block & block, const Names & names); Columns materializeColumns(const Block & block, const Names & names);

View File

@ -0,0 +1,29 @@
1 l \N Nullable(String)
2 \N Nullable(String)
1 l \N Nullable(String)
2 \N Nullable(String)
-
1 l \N Nullable(String)
0 \N Nullable(String)
0 \N Nullable(String)
1 l \N Nullable(String)
-
1 l \N Nullable(String)
0 \N Nullable(String)
0 \N Nullable(String)
1 l \N Nullable(String)
-
1 l \N Nullable(String)
2 \N Nullable(String)
1 l \N Nullable(String)
2 \N Nullable(String)
-
1 l \N Nullable(String)
\N \N Nullable(String)
1 l \N Nullable(String)
\N \N Nullable(String)
-
1 l \N Nullable(String)
\N \N Nullable(String)
1 l \N Nullable(String)
\N \N Nullable(String)

View File

@ -0,0 +1,50 @@
DROP TABLE IF EXISTS t;
DROP TABLE IF EXISTS nr;
CREATE TABLE t (`x` UInt32, `lc` LowCardinality(String)) ENGINE = Memory;
CREATE TABLE nr (`x` Nullable(UInt32), `lc` Nullable(String)) ENGINE = Memory;
INSERT INTO t VALUES (1, 'l');
INSERT INTO nr VALUES (2, NULL);
SET join_use_nulls = 0;
SELECT x, lc, r.lc, toTypeName(r.lc) FROM t AS l LEFT JOIN nr AS r USING (x) ORDER BY x;
SELECT x, lc, r.lc, toTypeName(r.lc) FROM t AS l RIGHT JOIN nr AS r USING (x) ORDER BY x;
SELECT x, lc, r.lc, toTypeName(r.lc) FROM t AS l FULL JOIN nr AS r USING (x) ORDER BY x;
SELECT '-';
SELECT x, lc, r.lc, toTypeName(r.lc) FROM t AS l LEFT JOIN nr AS r USING (lc) ORDER BY x;
SELECT x, lc, r.lc, toTypeName(r.lc) FROM t AS l RIGHT JOIN nr AS r USING (lc) ORDER BY x;
SELECT x, lc, r.lc, toTypeName(r.lc) FROM t AS l FULL JOIN nr AS r USING (lc) ORDER BY x;
SELECT '-';
SELECT x, lc, materialize(r.lc) y, toTypeName(y) FROM t AS l LEFT JOIN nr AS r USING (lc) ORDER BY x;
SELECT x, lc, materialize(r.lc) y, toTypeName(y) FROM t AS l RIGHT JOIN nr AS r USING (lc) ORDER BY x;
SELECT x, lc, materialize(r.lc) y, toTypeName(y) FROM t AS l FULL JOIN nr AS r USING (lc) ORDER BY x;
SELECT '-';
SET join_use_nulls = 1;
SELECT x, lc, r.lc, toTypeName(r.lc) FROM t AS l LEFT JOIN nr AS r USING (x) ORDER BY x;
SELECT x, lc, r.lc, toTypeName(r.lc) FROM t AS l RIGHT JOIN nr AS r USING (x) ORDER BY x;
SELECT x, lc, r.lc, toTypeName(r.lc) FROM t AS l FULL JOIN nr AS r USING (x) ORDER BY x;
SELECT '-';
SELECT x, lc, r.lc, toTypeName(r.lc) FROM t AS l LEFT JOIN nr AS r USING (lc) ORDER BY x;
SELECT x, lc, r.lc, toTypeName(r.lc) FROM t AS l RIGHT JOIN nr AS r USING (lc) ORDER BY x;
SELECT x, lc, r.lc, toTypeName(r.lc) FROM t AS l FULL JOIN nr AS r USING (lc) ORDER BY x;
SELECT '-';
SELECT x, lc, materialize(r.lc) y, toTypeName(y) FROM t AS l LEFT JOIN nr AS r USING (lc) ORDER BY x;
SELECT x, lc, materialize(r.lc) y, toTypeName(y) FROM t AS l RIGHT JOIN nr AS r USING (lc) ORDER BY x;
SELECT x, lc, materialize(r.lc) y, toTypeName(y) FROM t AS l FULL JOIN nr AS r USING (lc) ORDER BY x;
DROP TABLE t;
DROP TABLE nr;