Merge pull request #25288 from amosbird/fixjoingetornull

This commit is contained in:
Vladimir 2021-06-17 21:54:21 +03:00 committed by GitHub
commit 9e5ef95677
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 18 deletions

View File

@ -680,7 +680,6 @@ namespace
class AddedColumns class AddedColumns
{ {
public: public:
struct TypeAndName struct TypeAndName
{ {
DataTypePtr type; DataTypePtr type;
@ -688,24 +687,26 @@ public:
String qualified_name; String qualified_name;
TypeAndName(DataTypePtr type_, const String & name_, const String & qualified_name_) TypeAndName(DataTypePtr type_, const String & name_, const String & qualified_name_)
: type(type_) : type(type_), name(name_), qualified_name(qualified_name_)
, name(name_) {
, qualified_name(qualified_name_) }
{}
}; };
AddedColumns(const Block & block_with_columns_to_add, AddedColumns(
const Block & block, const Block & block_with_columns_to_add,
const Block & saved_block_sample, const Block & block,
const HashJoin & join, const Block & saved_block_sample,
const ColumnRawPtrs & key_columns_, const HashJoin & join,
const Sizes & key_sizes_, const ColumnRawPtrs & key_columns_,
bool is_asof_join) const Sizes & key_sizes_,
bool is_asof_join,
bool is_join_get_)
: key_columns(key_columns_) : key_columns(key_columns_)
, key_sizes(key_sizes_) , key_sizes(key_sizes_)
, rows_to_add(block.rows()) , rows_to_add(block.rows())
, asof_type(join.getAsofType()) , asof_type(join.getAsofType())
, asof_inequality(join.getAsofInequality()) , asof_inequality(join.getAsofInequality())
, is_join_get(is_join_get_)
{ {
size_t num_columns_to_add = block_with_columns_to_add.columns(); size_t num_columns_to_add = block_with_columns_to_add.columns();
if (is_asof_join) if (is_asof_join)
@ -749,8 +750,25 @@ public:
if constexpr (has_defaults) if constexpr (has_defaults)
applyLazyDefaults(); applyLazyDefaults();
for (size_t j = 0, size = right_indexes.size(); j < size; ++j) if (is_join_get)
columns[j]->insertFrom(*block.getByPosition(right_indexes[j]).column, row_num); {
/// If it's joinGetOrNull, we need to wrap not-nullable columns in StorageJoin.
for (size_t j = 0, size = right_indexes.size(); j < size; ++j)
{
const auto & column = *block.getByPosition(right_indexes[j]).column;
if (auto * nullable_col = typeid_cast<ColumnNullable *>(columns[j].get()); nullable_col && !column.isNullable())
nullable_col->insertFromNotNullable(column, row_num);
else
columns[j]->insertFrom(column, row_num);
}
}
else
{
for (size_t j = 0, size = right_indexes.size(); j < size; ++j)
{
columns[j]->insertFrom(*block.getByPosition(right_indexes[j]).column, row_num);
}
}
} }
void appendDefaultRow() void appendDefaultRow()
@ -787,6 +805,7 @@ private:
std::optional<TypeIndex> asof_type; std::optional<TypeIndex> asof_type;
ASOF::Inequality asof_inequality; ASOF::Inequality asof_inequality;
const IColumn * left_asof_key = nullptr; const IColumn * left_asof_key = nullptr;
bool is_join_get;
void addColumn(const ColumnWithTypeAndName & src_column, const std::string & qualified_name) void addColumn(const ColumnWithTypeAndName & src_column, const std::string & qualified_name)
{ {
@ -1021,7 +1040,8 @@ void HashJoin::joinBlockImpl(
Block & block, Block & block,
const Names & key_names_left, const Names & key_names_left,
const Block & block_with_columns_to_add, const Block & block_with_columns_to_add,
const Maps & maps_) const const Maps & maps_,
bool is_join_get) const
{ {
constexpr bool is_any_join = STRICTNESS == ASTTableJoin::Strictness::Any; constexpr bool is_any_join = STRICTNESS == ASTTableJoin::Strictness::Any;
constexpr bool is_all_join = STRICTNESS == ASTTableJoin::Strictness::All; constexpr bool is_all_join = STRICTNESS == ASTTableJoin::Strictness::All;
@ -1065,7 +1085,7 @@ void HashJoin::joinBlockImpl(
* For ASOF, the last column is used as the ASOF column * For ASOF, the last column is used as the ASOF column
*/ */
AddedColumns added_columns(block_with_columns_to_add, block, savedBlockSample(), *this, left_key_columns, key_sizes, is_asof_join); AddedColumns added_columns(block_with_columns_to_add, block, savedBlockSample(), *this, left_key_columns, key_sizes, is_asof_join, is_join_get);
bool has_required_right_keys = (required_right_keys.columns() != 0); bool has_required_right_keys = (required_right_keys.columns() != 0);
added_columns.need_filter = need_filter || has_required_right_keys; added_columns.need_filter = need_filter || has_required_right_keys;
@ -1274,7 +1294,7 @@ ColumnWithTypeAndName HashJoin::joinGet(const Block & block, const Block & block
static_assert(!MapGetter<ASTTableJoin::Kind::Left, ASTTableJoin::Strictness::Any>::flagged, static_assert(!MapGetter<ASTTableJoin::Kind::Left, ASTTableJoin::Strictness::Any>::flagged,
"joinGet are not protected from hash table changes between block processing"); "joinGet are not protected from hash table changes between block processing");
joinBlockImpl<ASTTableJoin::Kind::Left, ASTTableJoin::Strictness::Any>( joinBlockImpl<ASTTableJoin::Kind::Left, ASTTableJoin::Strictness::Any>(
keys, key_names_right, block_with_columns_to_add, std::get<MapsOne>(data->maps)); keys, key_names_right, block_with_columns_to_add, std::get<MapsOne>(data->maps), /* is_join_get */ true);
return keys.getByPosition(keys.columns() - 1); return keys.getByPosition(keys.columns() - 1);
} }

View File

@ -400,7 +400,8 @@ private:
Block & block, Block & block,
const Names & key_names_left, const Names & key_names_left,
const Block & block_with_columns_to_add, const Block & block_with_columns_to_add,
const Maps & maps) const; const Maps & maps,
bool is_join_get = false) const;
void joinBlockImplCross(Block & block, ExtraBlockPtr & not_processed) const; void joinBlockImplCross(Block & block, ExtraBlockPtr & not_processed) const;

View File

@ -1,2 +1,7 @@
\N \N
\N \N
1396-01-12
1396-01-13
\N
\N
\N

View File

@ -11,3 +11,14 @@ DROP TABLE join_test;
CREATE TABLE join_test (id UInt16, num Array(UInt16)) engine = Join(ANY, LEFT, id); CREATE TABLE join_test (id UInt16, num Array(UInt16)) engine = Join(ANY, LEFT, id);
SELECT joinGetOrNull('join_test', 'num', 500); -- { serverError 43 } SELECT joinGetOrNull('join_test', 'num', 500); -- { serverError 43 }
DROP TABLE join_test; DROP TABLE join_test;
drop table if exists test;
create table test (x Date, y String) engine Join(ANY, LEFT, x);
insert into test values ('2017-04-01', '1396-01-12') ,('2017-04-02', '1396-01-13');
WITH
A as (SELECT rowNumberInAllBlocks() R, addDays(toDate('2017-04-01'), R) TVV from numbers(5)),
B as (SELECT rowNumberInAllBlocks() R, toDateTime(NULL) TVV from numbers(1))
SELECT
joinGetOrNull('test', 'y', toDate(A.TVV) ) TV1
from A LEFT JOIN B USING (R) order by TV1;