Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2dot5
ClickHouse
提交
73dafaa2
C
ClickHouse
项目概览
2dot5
/
ClickHouse
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
ClickHouse
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
73dafaa2
编写于
9月 11, 2019
作者:
C
chertus
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
better required-right-keys logic
上级
8afa48fa
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
39 addition
and
50 deletion
+39
-50
dbms/src/Interpreters/AnalyzedJoin.cpp
dbms/src/Interpreters/AnalyzedJoin.cpp
+5
-9
dbms/src/Interpreters/AnalyzedJoin.h
dbms/src/Interpreters/AnalyzedJoin.h
+1
-1
dbms/src/Interpreters/Join.cpp
dbms/src/Interpreters/Join.cpp
+26
-35
dbms/src/Interpreters/Join.h
dbms/src/Interpreters/Join.h
+5
-3
dbms/src/Storages/StorageJoin.cpp
dbms/src/Storages/StorageJoin.cpp
+2
-2
未找到文件。
dbms/src/Interpreters/AnalyzedJoin.cpp
浏览文件 @
73dafaa2
...
...
@@ -142,17 +142,13 @@ Names AnalyzedJoin::requiredJoinedNames() const
return
Names
(
required_columns_set
.
begin
(),
required_columns_set
.
end
());
}
std
::
unordered_map
<
String
,
DataTypePtr
>
AnalyzedJoin
::
requiredRightKeys
()
const
NameSet
AnalyzedJoin
::
requiredRightKeys
()
const
{
NameSet
r
ight_keys
;
NameSet
r
equired
;
for
(
const
auto
&
name
:
key_names_right
)
right_keys
.
insert
(
name
);
std
::
unordered_map
<
String
,
DataTypePtr
>
required
;
for
(
const
auto
&
column
:
columns_added_by_join
)
if
(
right_keys
.
count
(
column
.
name
))
required
.
insert
({
column
.
name
,
column
.
type
});
for
(
const
auto
&
column
:
columns_added_by_join
)
if
(
name
==
column
.
name
)
required
.
insert
(
name
);
return
required
;
}
...
...
dbms/src/Interpreters/AnalyzedJoin.h
浏览文件 @
73dafaa2
...
...
@@ -92,7 +92,7 @@ public:
void
deduplicateAndQualifyColumnNames
(
const
NameSet
&
left_table_columns
,
const
String
&
right_table_prefix
);
size_t
rightKeyInclusion
(
const
String
&
name
)
const
;
std
::
unordered_map
<
String
,
DataTypePtr
>
requiredRightKeys
()
const
;
NameSet
requiredRightKeys
()
const
;
void
addJoinedColumn
(
const
NameAndTypePair
&
joined_column
);
void
addJoinedColumnsAndCorrectNullability
(
Block
&
sample_block
)
const
;
...
...
dbms/src/Interpreters/Join.cpp
浏览文件 @
73dafaa2
...
...
@@ -75,6 +75,7 @@ Join::Join(const AnalyzedJoin & join_options_, const Block & right_sample_block,
,
kind
(
join_options_
.
kind
())
,
strictness
(
join_options_
.
strictness
())
,
key_names_right
(
join_options_
.
keyNamesRight
())
,
required_right_keys
(
join_options_
.
requiredRightKeys
())
,
use_nulls
(
join_options_
.
joinUseNulls
())
,
any_take_last_row
(
any_take_last_row_
)
,
log
(
&
Logger
::
get
(
"Join"
))
...
...
@@ -263,7 +264,7 @@ void Join::setSampleBlock(const Block & block)
if
(
!
empty
())
return
;
ColumnRawPtrs
key_columns
=
extractKeysForJoin
(
key_names_right
,
block
,
sample_block_with
_keys
,
sample_block_with_columns_to_add
);
ColumnRawPtrs
key_columns
=
extractKeysForJoin
(
key_names_right
,
block
,
right_table
_keys
,
sample_block_with_columns_to_add
);
if
(
strictness
==
ASTTableJoin
::
Strictness
::
Asof
)
{
...
...
@@ -783,7 +784,7 @@ void Join::joinBlockImpl(
*/
ColumnsWithTypeAndName
extras
;
if
constexpr
(
STRICTNESS
==
ASTTableJoin
::
Strictness
::
Asof
)
extras
.
push_back
(
sample_block_with
_keys
.
getByName
(
key_names_right
.
back
()));
extras
.
push_back
(
right_table
_keys
.
getByName
(
key_names_right
.
back
()));
AddedColumns
added
(
sample_block_with_columns_to_add
,
block_with_columns_to_add
,
block
,
blocklist_sample
,
extras
);
std
::
unique_ptr
<
IColumn
::
Offsets
>
offsets_to_replicate
;
...
...
@@ -795,8 +796,6 @@ void Join::joinBlockImpl(
block
.
insert
(
added
.
moveColumn
(
i
));
/// Filter & insert missing rows
auto
right_keys
=
join_options
.
requiredRightKeys
();
constexpr
bool
is_all_join
=
STRICTNESS
==
ASTTableJoin
::
Strictness
::
All
;
constexpr
bool
inner_or_right
=
static_in_v
<
KIND
,
ASTTableJoin
::
Kind
::
Inner
,
ASTTableJoin
::
Kind
::
Right
>
;
constexpr
bool
left_or_full
=
static_in_v
<
KIND
,
ASTTableJoin
::
Kind
::
Left
,
ASTTableJoin
::
Kind
::
Full
>
;
...
...
@@ -810,17 +809,16 @@ void Join::joinBlockImpl(
block
.
safeGetByPosition
(
i
).
column
=
block
.
safeGetByPosition
(
i
).
column
->
filter
(
row_filter
,
-
1
);
/// Add join key columns from right block if they has different name.
for
(
size_t
i
=
0
;
i
<
key_names_right
.
size
();
++
i
)
for
(
size_t
i
=
0
;
i
<
right_table_keys
.
columns
();
++
i
)
{
auto
&
right_name
=
key_names_right
[
i
]
;
const
auto
&
right_key
=
right_table_keys
.
getByPosition
(
i
)
;
auto
&
left_name
=
key_names_left
[
i
];
auto
it
=
right_keys
.
find
(
right_name
);
if
(
it
!=
right_keys
.
end
()
&&
!
block
.
has
(
right_name
))
if
(
required_right_keys
.
count
(
right_key
.
name
)
&&
!
block
.
has
(
right_key
.
name
))
{
const
auto
&
col
=
block
.
getByName
(
left_name
);
bool
is_nullable
=
it
->
second
->
isNullable
();
block
.
insert
(
correctNullability
({
col
.
column
,
col
.
type
,
right_name
},
is_nullable
));
bool
is_nullable
=
(
use_nulls
&&
left_or_full
)
||
right_key
.
type
->
isNullable
();
block
.
insert
(
correctNullability
({
col
.
column
,
col
.
type
,
right_
key
.
name
},
is_nullable
));
}
}
}
...
...
@@ -833,13 +831,12 @@ void Join::joinBlockImpl(
const
IColumn
::
Filter
&
filter
=
null_map_filter
.
getData
();
/// Add join key columns from right block if they has different name.
for
(
size_t
i
=
0
;
i
<
key_names_right
.
size
();
++
i
)
for
(
size_t
i
=
0
;
i
<
right_table_keys
.
columns
();
++
i
)
{
auto
&
right_name
=
key_names_right
[
i
]
;
const
auto
&
right_key
=
right_table_keys
.
getByPosition
(
i
)
;
auto
&
left_name
=
key_names_left
[
i
];
auto
it
=
right_keys
.
find
(
right_name
);
if
(
it
!=
right_keys
.
end
()
&&
!
block
.
has
(
right_name
))
if
(
required_right_keys
.
count
(
right_key
.
name
)
&&
!
block
.
has
(
right_key
.
name
))
{
const
auto
&
col
=
block
.
getByName
(
left_name
);
ColumnPtr
column
=
col
.
column
->
convertToFullColumnIfConst
();
...
...
@@ -854,11 +851,11 @@ void Join::joinBlockImpl(
mut_column
->
insertDefault
();
}
bool
is_nullable
=
(
use_nulls
&&
left_or_full
)
||
it
->
second
->
isNullable
();
block
.
insert
(
correctNullability
({
std
::
move
(
mut_column
),
col
.
type
,
right_name
},
is_nullable
,
null_map_filter
));
bool
is_nullable
=
(
use_nulls
&&
left_or_full
)
||
right_key
.
type
->
isNullable
();
block
.
insert
(
correctNullability
({
std
::
move
(
mut_column
),
col
.
type
,
right_
key
.
name
},
is_nullable
,
null_map_filter
));
if
constexpr
(
is_all_join
)
right_keys_to_replicate
.
push_back
(
block
.
getPositionByName
(
right_name
));
right_keys_to_replicate
.
push_back
(
block
.
getPositionByName
(
right_
key
.
name
));
}
}
}
...
...
@@ -992,7 +989,7 @@ void Join::joinGet(Block & block, const String & column_name) const
if
(
key_names_right
.
size
()
!=
1
)
throw
Exception
(
"joinGet only supports StorageJoin containing exactly one key"
,
ErrorCodes
::
LOGICAL_ERROR
);
checkTypeOfKey
(
block
,
sample_block_with
_keys
);
checkTypeOfKey
(
block
,
right_table
_keys
);
if
(
kind
==
ASTTableJoin
::
Kind
::
Left
&&
strictness
==
ASTTableJoin
::
Strictness
::
Any
)
{
...
...
@@ -1009,7 +1006,7 @@ void Join::joinBlock(Block & block)
std
::
shared_lock
lock
(
rwlock
);
checkTypesOfKeys
(
block
,
key_names_left
,
sample_block_with
_keys
);
checkTypesOfKeys
(
block
,
key_names_left
,
right_table
_keys
);
if
(
joinDispatch
(
kind
,
strictness
,
maps
,
[
&
](
auto
kind_
,
auto
strictness_
,
auto
&
map
)
{
...
...
@@ -1115,7 +1112,6 @@ public:
,
max_block_size
(
max_block_size_
)
{
const
Names
&
key_names_left
=
parent_
.
join_options
.
keyNamesLeft
();
std
::
unordered_map
<
String
,
DataTypePtr
>
required_right_keys
=
parent_
.
join_options
.
requiredRightKeys
();
/** left_sample_block contains keys and "left" columns.
* result_sample_block - keys, "left" columns, and "right" columns.
...
...
@@ -1135,10 +1131,9 @@ public:
const
Block
&
right_sample_block
=
parent
.
sample_block_with_columns_to_add
;
std
::
unordered_map
<
size_t
,
size_t
>
left_to_right_key_map
;
makeResultSampleBlock
(
left_sample_block
,
right_sample_block
,
required_right_keys
,
key_positions_left
,
left_to_right_key_map
);
makeResultSampleBlock
(
left_sample_block
,
right_sample_block
,
key_positions_left
,
left_to_right_key_map
);
auto
nullability_changes
=
getNullabilityChanges
(
parent
.
sample_block_with
_keys
,
result_sample_block
,
auto
nullability_changes
=
getNullabilityChanges
(
parent
.
right_table
_keys
,
result_sample_block
,
key_positions_left
,
left_to_right_key_map
);
column_indices_left
.
reserve
(
left_sample_block
.
columns
()
-
key_names_left
.
size
());
...
...
@@ -1204,7 +1199,6 @@ private:
void
makeResultSampleBlock
(
const
Block
&
left_sample_block
,
const
Block
&
right_sample_block
,
const
std
::
unordered_map
<
String
,
DataTypePtr
>
&
right_keys
,
const
std
::
vector
<
size_t
>
&
key_positions_left
,
std
::
unordered_map
<
size_t
,
size_t
>
&
left_to_right_key_map
)
{
...
...
@@ -1223,22 +1217,19 @@ private:
result_sample_block
.
insert
(
src_column
.
cloneEmpty
());
}
const
auto
&
key_names_right
=
parent
.
key_names_right
;
/// Add join key columns from right block if they has different name.
for
(
size_t
i
=
0
;
i
<
key_names_right
.
size
();
++
i
)
for
(
size_t
i
=
0
;
i
<
parent
.
right_table_keys
.
columns
();
++
i
)
{
auto
&
right_name
=
key_names_right
[
i
]
;
const
auto
&
right_key
=
parent
.
right_table_keys
.
getByPosition
(
i
)
;
size_t
left_key_pos
=
key_positions_left
[
i
];
auto
it
=
right_keys
.
find
(
right_name
);
if
(
it
!=
right_keys
.
end
()
&&
!
result_sample_block
.
has
(
right_name
))
if
(
parent
.
required_right_keys
.
count
(
right_key
.
name
)
&&
!
result_sample_block
.
has
(
right_key
.
name
))
{
const
auto
&
col
=
result_sample_block
.
getByPosition
(
left_key_pos
);
bool
is_nullable
=
(
parent
.
use_nulls
&&
isFull
(
parent
.
kind
))
||
it
->
second
->
isNullable
();
result_sample_block
.
insert
(
correctNullability
({
col
.
column
,
col
.
type
,
right_name
},
is_nullable
));
bool
is_nullable
=
(
parent
.
use_nulls
&&
isFull
(
parent
.
kind
))
||
right_key
.
type
->
isNullable
();
result_sample_block
.
insert
(
correctNullability
({
col
.
column
,
col
.
type
,
right_
key
.
name
},
is_nullable
));
size_t
right_key_pos
=
result_sample_block
.
getPositionByName
(
right_name
);
size_t
right_key_pos
=
result_sample_block
.
getPositionByName
(
right_
key
.
name
);
left_to_right_key_map
[
left_key_pos
]
=
right_key_pos
;
}
}
...
...
@@ -1372,7 +1363,7 @@ private:
}
}
static
std
::
unordered_set
<
size_t
>
getNullabilityChanges
(
const
Block
&
sample_block_with
_keys
,
const
Block
&
out_block
,
static
std
::
unordered_set
<
size_t
>
getNullabilityChanges
(
const
Block
&
right_table
_keys
,
const
Block
&
out_block
,
const
std
::
vector
<
size_t
>
&
key_positions
,
const
std
::
unordered_map
<
size_t
,
size_t
>
&
left_to_right_key_map
)
{
...
...
@@ -1387,7 +1378,7 @@ private:
key_pos
=
it
->
second
;
const
auto
&
dst
=
out_block
.
getByPosition
(
key_pos
).
column
;
const
auto
&
src
=
sample_block_with
_keys
.
getByPosition
(
i
).
column
;
const
auto
&
src
=
right_table
_keys
.
getByPosition
(
i
).
column
;
if
(
dst
->
isNullable
()
!=
src
->
isNullable
())
nullability_changes
.
insert
(
key_pos
);
}
...
...
dbms/src/Interpreters/Join.h
浏览文件 @
73dafaa2
...
...
@@ -280,8 +280,10 @@ private:
ASTTableJoin
::
Kind
kind
;
ASTTableJoin
::
Strictness
strictness
;
/// Names of key columns
(columns for equi-JOIN) in "right" table (in the order they appear in USING clause)
.
/// Names of key columns
in right-side table (in the order they appear in ON/USING clause). @note It could contain duplicates
.
const
Names
key_names_right
;
/// Names right-side table keys that are needed in result (would be attached after joined columns).
const
NameSet
required_right_keys
;
/// Substitute NULLs for non-JOINed rows.
bool
use_nulls
;
...
...
@@ -310,8 +312,8 @@ private:
/// Block with columns from the right-side table except key columns.
Block
sample_block_with_columns_to_add
;
/// Block with key columns in the same order they appear in the right-side table.
Block
sample_block_with
_keys
;
/// Block with key columns in the same order they appear in the right-side table
(duplicates appear once)
.
Block
right_table
_keys
;
/// Block as it would appear in the BlockList
Block
blocklist_sample
;
...
...
dbms/src/Storages/StorageJoin.cpp
浏览文件 @
73dafaa2
...
...
@@ -209,10 +209,10 @@ public:
for
(
size_t
i
=
0
;
i
<
sample_block
.
columns
();
++
i
)
{
auto
&
[
_
,
type
,
name
]
=
sample_block
.
getByPosition
(
i
);
if
(
parent
.
sample_block_with
_keys
.
has
(
name
))
if
(
parent
.
right_table
_keys
.
has
(
name
))
{
key_pos
=
i
;
column_with_null
[
i
]
=
parent
.
sample_block_with
_keys
.
getByName
(
name
).
type
->
isNullable
();
column_with_null
[
i
]
=
parent
.
right_table
_keys
.
getByName
(
name
).
type
->
isNullable
();
}
else
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录