support MergeJoin nullable convertion (right side)

This commit is contained in:
chertus 2019-09-17 19:55:11 +03:00
parent da5d35b34e
commit 58fad78980
5 changed files with 166 additions and 13 deletions

View File

@ -156,6 +156,18 @@ void ColumnNullable::insertFrom(const IColumn & src, size_t n)
getNullMapData().push_back(src_concrete.getNullMapData()[n]); getNullMapData().push_back(src_concrete.getNullMapData()[n]);
} }
void ColumnNullable::insertFromNotNullable(const IColumn & src, size_t n)
{
getNestedColumn().insertFrom(src, n);
getNullMapData().push_back(0);
}
void ColumnNullable::insertRangeFromNotNullable(const IColumn & src, size_t start, size_t length)
{
getNestedColumn().insertRangeFrom(src, start, length);
getNullMapData().resize_fill(getNullMapData().size() + length, 0);
}
void ColumnNullable::popBack(size_t n) void ColumnNullable::popBack(size_t n)
{ {
getNestedColumn().popBack(n); getNestedColumn().popBack(n);

View File

@ -61,6 +61,9 @@ public:
void insert(const Field & x) override; void insert(const Field & x) override;
void insertFrom(const IColumn & src, size_t n) override; void insertFrom(const IColumn & src, size_t n) override;
void insertFromNotNullable(const IColumn & src, size_t n);
void insertRangeFromNotNullable(const IColumn & src, size_t start, size_t length);
void insertDefault() override void insertDefault() override
{ {
getNestedColumn().insertDefault(); getNestedColumn().insertDefault();

View File

@ -1,5 +1,6 @@
#include <Core/NamesAndTypes.h> #include <Core/NamesAndTypes.h>
#include <Core/SortCursor.h> #include <Core/SortCursor.h>
#include <Columns/ColumnNullable.h>
#include <Interpreters/MergeJoin.h> #include <Interpreters/MergeJoin.h>
#include <Interpreters/AnalyzedJoin.h> #include <Interpreters/AnalyzedJoin.h>
#include <Interpreters/sortBlock.h> #include <Interpreters/sortBlock.h>
@ -104,13 +105,16 @@ private:
namespace namespace
{ {
MutableColumns makeMutableColumns(const Block & block) MutableColumns makeMutableColumns(const Block & block, size_t rows_to_reserve = 0)
{ {
MutableColumns columns; MutableColumns columns;
columns.reserve(block.columns()); columns.reserve(block.columns());
for (const auto & src_column : block) for (const auto & src_column : block)
{
columns.push_back(src_column.column->cloneEmpty()); columns.push_back(src_column.column->cloneEmpty());
columns.back()->reserve(rows_to_reserve);
}
return columns; return columns;
} }
@ -133,12 +137,8 @@ void copyLeftRange(const Block & block, MutableColumns & columns, size_t start,
{ {
for (size_t i = 0; i < block.columns(); ++i) for (size_t i = 0; i < block.columns(); ++i)
{ {
const auto & src_column = block.getByPosition(i); const auto & src_column = block.getByPosition(i).column;
auto & dst_column = columns[i]; columns[i]->insertRangeFrom(*src_column, start, rows_to_add);
size_t row_pos = start;
for (size_t row = 0; row < rows_to_add; ++row, ++row_pos)
dst_column->insertFrom(*src_column.column, row_pos);
} }
} }
@ -147,11 +147,14 @@ void copyRightRange(const Block & right_block, const Block & right_columns_to_ad
{ {
for (size_t i = 0; i < right_columns_to_add.columns(); ++i) for (size_t i = 0; i < right_columns_to_add.columns(); ++i)
{ {
const auto & src_column = right_block.getByName(right_columns_to_add.getByPosition(i).name); const auto & src_column = right_block.getByName(right_columns_to_add.getByPosition(i).name).column;
auto & dst_column = columns[i]; auto & dst_column = columns[i];
auto * dst_nullable = typeid_cast<ColumnNullable *>(dst_column.get());
for (size_t row = 0; row < rows_to_add; ++row) if (dst_nullable && !isColumnNullable(*src_column))
dst_column->insertFrom(*src_column.column, row_position); dst_nullable->insertRangeFromNotNullable(*src_column, row_position, rows_to_add);
else
dst_column->insertRangeFrom(*src_column, row_position, rows_to_add);
} }
} }
@ -270,8 +273,9 @@ void MergeJoin::joinBlock(Block & block)
std::shared_lock lock(rwlock); std::shared_lock lock(rwlock);
MutableColumns left_columns = makeMutableColumns(block); size_t rows_to_reserve = is_left ? block.rows() : 0;
MutableColumns right_columns = makeMutableColumns(right_columns_to_add); MutableColumns left_columns = makeMutableColumns(block, (is_all ? rows_to_reserve : 0));
MutableColumns right_columns = makeMutableColumns(right_columns_to_add, rows_to_reserve);
MergeJoinCursor left_cursor(block, left_merge_description); MergeJoinCursor left_cursor(block, left_merge_description);
if (is_left) if (is_left)

View File

@ -122,3 +122,97 @@ all inner
2 20 2 22 2 20 2 22
4 40 4 41 4 40 4 41
4 40 4 42 4 40 4 42
any left
0 0 0
1 10 \N
2 20 2
3 30 \N
4 40 4
-
0 0 0
1 10 \N
2 20 \N
3 30 \N
4 40 \N
-
0 0 0
1 10 \N
2 20 2
3 30 \N
4 40 4
-
0 0 0
1 10 \N
2 20 \N
3 30 \N
4 40 \N
all left
0 0 0 0
1 10 \N \N
2 20 2 21
2 20 2 22
3 30 \N \N
4 40 4 41
4 40 4 42
-
0 0 0 0
1 10 \N \N
2 20 \N \N
3 30 \N \N
4 40 \N \N
-
0 0 0 0
1 10 \N \N
2 20 \N \N
3 30 \N \N
4 40 \N \N
-
0 0 0 0
1 10 \N \N
2 20 2 21
2 20 2 22
3 30 \N \N
4 40 4 41
4 40 4 42
-
0 0 0 0
1 10 \N \N
2 20 2 21
2 20 2 22
3 30 \N \N
4 40 4 41
4 40 4 42
any inner
0 0 0
2 20 2
4 40 4
-
0 0 0
-
0 0 0
2 20 2
4 40 4
-
0 0 0
all inner
0 0 0 0
2 20 2 21
2 20 2 22
4 40 4 41
4 40 4 42
-
0 0 0 0
-
0 0 0 0
-
0 0 0 0
2 20 2 21
2 20 2 22
4 40 4 41
4 40 4 42
-
0 0 0 0
2 20 2 21
2 20 2 22
4 40 4 41
4 40 4 42

View File

@ -117,7 +117,47 @@ SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ON t1.x = t2.x AND toUInt32(intDiv(t1.y,
SELECT '-'; SELECT '-';
SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ON t1.x = t2.x AND toUInt64(t1.x) = intDiv(t2.y,10) ORDER BY x, t2.y; SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ON t1.x = t2.x AND toUInt64(t1.x) = intDiv(t2.y,10) ORDER BY x, t2.y;
-- TODO: SET join_use_nulls = 1; SET join_use_nulls = 1;
SELECT 'any left';
SELECT t1.*, t2.x FROM t1 ANY LEFT JOIN t2 USING (x) ORDER BY x;
SELECT '-';
SELECT t1.*, t2.x FROM t1 ANY LEFT JOIN t2 USING (x,y) ORDER BY x;
SELECT '-';
SELECT t1.*, t2.x FROM t1 ANY LEFT JOIN t2 USING (x) ORDER BY x;
SELECT '-';
SELECT t1.*, t2.x FROM t1 ANY LEFT JOIN t2 USING (x,y) ORDER BY x;
SELECT 'all left';
SELECT t1.*, t2.* FROM t1 LEFT JOIN t2 ON t1.x = t2.x ORDER BY x, t2.y;
SELECT '-';
SELECT t1.*, t2.* FROM t1 LEFT JOIN t2 ON t1.y = t2.y ORDER BY x;
SELECT '-';
SELECT t1.*, t2.* FROM t1 LEFT JOIN t2 ON t1.x = t2.x AND t1.y = t2.y ORDER BY x;
SELECT '-';
SELECT t1.*, t2.* FROM t1 LEFT JOIN t2 ON t1.x = t2.x AND toUInt32(intDiv(t1.y,10)) = t2.x ORDER BY x, t2.y;
SELECT '-';
SELECT t1.*, t2.* FROM t1 LEFT JOIN t2 ON t1.x = t2.x AND toUInt64(t1.x) = intDiv(t2.y,10) ORDER BY x, t2.y;
SELECT 'any inner';
SELECT t1.*, t2.x FROM t1 ANY INNER JOIN t2 USING (x) ORDER BY x;
SELECT '-';
SELECT t1.*, t2.x FROM t1 ANY INNER JOIN t2 USING (x,y) ORDER BY x;
SELECT '-';
SELECT t1.*, t2.x FROM t1 ANY INNER JOIN t2 USING (x) ORDER BY x;
SELECT '-';
SELECT t1.*, t2.x FROM t1 ANY INNER JOIN t2 USING (x,y) ORDER BY x;
SELECT 'all inner';
SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ON t1.x = t2.x ORDER BY x, t2.y;
SELECT '-';
SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ON t1.y = t2.y ORDER BY x;
SELECT '-';
SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ON t1.x = t2.x AND t1.y = t2.y ORDER BY x;
SELECT '-';
SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ON t1.x = t2.x AND toUInt32(intDiv(t1.y,10)) = t2.x ORDER BY x, t2.y;
SELECT '-';
SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ON t1.x = t2.x AND toUInt64(t1.x) = intDiv(t2.y,10) ORDER BY x, t2.y;
DROP TABLE t0; DROP TABLE t0;
DROP TABLE t1; DROP TABLE t1;