mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 15:42:02 +00:00
Merge pull request #25288 from amosbird/fixjoingetornull
This commit is contained in:
commit
9e5ef95677
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -1,2 +1,7 @@
|
|||||||
\N
|
\N
|
||||||
\N
|
\N
|
||||||
|
1396-01-12
|
||||||
|
1396-01-13
|
||||||
|
\N
|
||||||
|
\N
|
||||||
|
\N
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user