Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2dot5
ClickHouse
提交
5f1007a8
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,发现更多精彩内容 >>
提交
5f1007a8
编写于
1月 24, 2019
作者:
N
Nikolai Kochetov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Refactor Join.
上级
e8aa41b6
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
158 addition
and
87 deletion
+158
-87
dbms/src/Common/ColumnsHashing.h
dbms/src/Common/ColumnsHashing.h
+65
-21
dbms/src/Common/ColumnsHashingImpl.h
dbms/src/Common/ColumnsHashingImpl.h
+6
-6
dbms/src/Interpreters/Join.cpp
dbms/src/Interpreters/Join.cpp
+86
-60
dbms/src/Interpreters/Join.h
dbms/src/Interpreters/Join.h
+1
-0
未找到文件。
dbms/src/Common/ColumnsHashing.h
浏览文件 @
5f1007a8
...
...
@@ -36,10 +36,10 @@ using HashMethodContextPtr = std::shared_ptr<HashMethodContext>;
/// For the case where there is one numeric key.
template
<
typename
Value
,
typename
Mapped
,
typename
FieldType
>
/// UInt8/16/32/64 for any type with corresponding bit width.
struct
HashMethodOneNumber
:
public
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
tru
e
>
template
<
typename
Value
,
typename
Mapped
,
typename
FieldType
,
bool
use_cache
=
true
>
/// UInt8/16/32/64 for any type with corresponding bit width.
struct
HashMethodOneNumber
:
public
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
use_cach
e
>
{
using
Base
=
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
tru
e
>
;
using
Base
=
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
use_cach
e
>
;
const
char
*
vec
;
/// If the keys of a fixed length then key_sizes contains their lengths, empty otherwise.
...
...
@@ -90,10 +90,10 @@ protected:
/// For the case where there is one string key.
template
<
typename
Value
,
typename
Mapped
>
struct
HashMethodString
:
public
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
tru
e
>
template
<
typename
Value
,
typename
Mapped
,
bool
use_cache
=
true
>
struct
HashMethodString
:
public
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
use_cach
e
>
{
using
Base
=
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
tru
e
>
;
using
Base
=
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
use_cach
e
>
;
const
IColumn
::
Offset
*
offsets
;
const
UInt8
*
chars
;
...
...
@@ -107,7 +107,7 @@ struct HashMethodString : public columns_hashing_impl::HashMethodBase<Value, Map
static
HashMethodContextPtr
createContext
(
const
HashMethodContext
::
Settings
&
)
{
return
nullptr
;
}
StringRef
getKey
(
size_t
row
)
const
{
return
StringRef
(
chars
+
offsets
[
row
-
1
],
offsets
[
row
]
-
offsets
[
row
-
1
]
-
1
);
}
StringRef
getKey
(
s
s
ize_t
row
)
const
{
return
StringRef
(
chars
+
offsets
[
row
-
1
],
offsets
[
row
]
-
offsets
[
row
-
1
]
-
1
);
}
template
<
typename
Data
>
ALWAYS_INLINE
typename
Base
::
EmplaceResult
emplaceKey
(
Data
&
data
,
size_t
row
,
Arena
&
pool
)
...
...
@@ -150,10 +150,10 @@ protected:
/// For the case where there is one fixed-length string key.
template
<
typename
Value
,
typename
Mapped
>
struct
HashMethodFixedString
:
public
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
tru
e
>
template
<
typename
Value
,
typename
Mapped
,
bool
use_cache
=
true
>
struct
HashMethodFixedString
:
public
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
use_cach
e
>
{
using
Base
=
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
tru
e
>
;
using
Base
=
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
use_cach
e
>
;
size_t
n
;
const
ColumnFixedString
::
Chars
*
chars
;
...
...
@@ -396,10 +396,13 @@ struct HashMethodSingleLowCardinalityColumn : public SingleColumnMethod
if
(
is_nullable
&&
row
==
0
)
{
visit_cache
[
row
]
=
VisitValue
::
Found
;
bool
has_null_key
=
data
.
hasNullKeyData
();
data
.
hasNullKeyData
()
=
true
;
if
constexpr
(
has_mapped
)
return
EmplaceResult
(
data
.
getNullKeyData
(),
mapped_cache
[
0
],
!
data
.
hasNullKeyData
()
);
return
EmplaceResult
(
data
.
getNullKeyData
(),
mapped_cache
[
0
],
!
has_null_key
);
else
return
EmplaceResult
(
!
data
.
hasNullKeyData
()
);
return
EmplaceResult
(
!
has_null_key
);
}
if
(
visit_cache
[
row
]
==
VisitValue
::
Found
)
...
...
@@ -446,7 +449,7 @@ struct HashMethodSingleLowCardinalityColumn : public SingleColumnMethod
if
(
is_nullable
&&
row
==
0
)
{
if
constexpr
(
has_mapped
)
return
FindResult
(
data
.
hasNullKeyData
()
?
data
.
getNullKeyData
()
:
Mapped
()
,
data
.
hasNullKeyData
());
return
FindResult
(
data
.
hasNullKeyData
()
?
&
data
.
getNullKeyData
()
:
nullptr
,
data
.
hasNullKeyData
());
else
return
FindResult
(
data
.
hasNullKeyData
());
}
...
...
@@ -454,7 +457,7 @@ struct HashMethodSingleLowCardinalityColumn : public SingleColumnMethod
if
(
visit_cache
[
row
]
!=
VisitValue
::
Empty
)
{
if
constexpr
(
has_mapped
)
return
FindResult
(
mapped_cache
[
row
],
visit_cache
[
row
]
==
VisitValue
::
Found
);
return
FindResult
(
&
mapped_cache
[
row
],
visit_cache
[
row
]
==
VisitValue
::
Found
);
else
return
FindResult
(
visit_cache
[
row
]
==
VisitValue
::
Found
);
}
...
...
@@ -477,7 +480,7 @@ struct HashMethodSingleLowCardinalityColumn : public SingleColumnMethod
}
if
constexpr
(
has_mapped
)
return
FindResult
(
mapped_cache
[
row
],
found
);
return
FindResult
(
&
mapped_cache
[
row
],
found
);
else
return
FindResult
(
found
);
}
...
...
@@ -507,10 +510,10 @@ template <>
struct
LowCardinalityKeys
<
false
>
{};
/// For the case where all keys are of fixed length, and they fit in N (for example, 128) bits.
template
<
typename
Value
,
typename
Key
,
typename
Mapped
,
bool
has_nullable_keys_
=
false
,
bool
has_low_cardinality_
=
false
>
template
<
typename
Value
,
typename
Key
,
typename
Mapped
,
bool
has_nullable_keys_
=
false
,
bool
has_low_cardinality_
=
false
,
bool
use_cache
=
true
>
struct
HashMethodKeysFixed
:
private
columns_hashing_impl
::
BaseStateKeysFixed
<
Key
,
has_nullable_keys_
>
,
public
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
tru
e
>
,
public
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
use_cach
e
>
{
static
constexpr
bool
has_nullable_keys
=
has_nullable_keys_
;
static
constexpr
bool
has_low_cardinality
=
has_low_cardinality_
;
...
...
@@ -520,7 +523,7 @@ struct HashMethodKeysFixed
size_t
keys_size
;
using
Base
=
columns_hashing_impl
::
BaseStateKeysFixed
<
Key
,
has_nullable_keys
>
;
using
BaseHashed
=
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
tru
e
>
;
using
BaseHashed
=
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
use_cach
e
>
;
HashMethodKeysFixed
(
const
ColumnRawPtrs
&
key_columns
,
const
Sizes
&
key_sizes
,
const
HashMethodContextPtr
&
)
:
key_sizes
(
std
::
move
(
key_sizes
)),
keys_size
(
key_columns
.
size
())
...
...
@@ -590,10 +593,10 @@ struct HashMethodKeysFixed
* That is, for example, for strings, it contains first the serialized length of the string, and then the bytes.
* Therefore, when aggregating by several strings, there is no ambiguity.
*/
template
<
typename
Value
,
typename
Mapped
>
struct
HashMethodSerialized
:
public
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
fals
e
>
template
<
typename
Value
,
typename
Mapped
,
bool
use_cache
=
true
>
struct
HashMethodSerialized
:
public
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
use_cach
e
>
{
using
Base
=
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
fals
e
>
;
using
Base
=
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
use_cach
e
>
;
ColumnRawPtrs
key_columns
;
size_t
keys_size
;
...
...
@@ -641,5 +644,46 @@ protected:
}
};
/// For the case where there is one string key.
template
<
typename
Value
,
typename
Mapped
,
bool
use_cache
=
true
>
struct
HashMethodHashed
:
public
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
use_cache
>
{
using
Base
=
columns_hashing_impl
::
HashMethodBase
<
Value
,
Mapped
,
use_cache
>
;
using
Key
=
UInt128
;
ColumnRawPtrs
key_columns
;
HashMethodHashed
(
ColumnRawPtrs
key_columns
,
const
Sizes
&
,
const
HashMethodContextPtr
&
)
:
key_columns
(
std
::
move
(
key_columns
))
{}
static
HashMethodContextPtr
createContext
(
const
HashMethodContext
::
Settings
&
)
{
return
nullptr
;
}
UInt128
getKey
(
size_t
row
)
const
{
return
hash128
(
row
,
key_columns
.
size
(),
key_columns
);
}
template
<
typename
Data
>
ALWAYS_INLINE
typename
Base
::
EmplaceResult
emplaceKey
(
Data
&
data
,
size_t
row
,
Arena
&
/*pool*/
)
{
typename
Data
::
iterator
it
;
return
Base
::
emplaceKeyImpl
(
getKey
(
row
),
data
,
it
);
}
template
<
typename
Data
>
ALWAYS_INLINE
typename
Base
::
FindResult
findKey
(
Data
&
data
,
size_t
row
,
Arena
&
/*pool*/
)
{
return
Base
::
findKeyImpl
(
getKey
(
row
),
data
);
}
template
<
typename
Data
>
ALWAYS_INLINE
size_t
getHash
(
const
Data
&
data
,
size_t
row
,
Arena
&
/*pool*/
)
{
return
data
.
hash
(
getKey
(
row
));
}
static
StringRef
getValueRef
(
const
Value
&
value
)
{
return
StringRef
(
reinterpret_cast
<
const
char
*>
(
&
value
.
first
),
sizeof
(
value
.
first
));
}
};
}
}
dbms/src/Common/ColumnsHashingImpl.h
浏览文件 @
5f1007a8
...
...
@@ -44,7 +44,7 @@ public:
:
value
(
value
),
cached_value
(
cached_value
),
inserted
(
inserted
)
{}
bool
isInserted
()
const
{
return
inserted
;
}
const
auto
&
getMapped
()
const
{
return
value
;
}
auto
&
getMapped
()
const
{
return
value
;
}
void
setMapped
(
const
Mapped
&
mapped
)
{
value
=
cached_value
=
mapped
;
}
};
...
...
@@ -61,13 +61,13 @@ public:
template
<
typename
Mapped
>
class
FindResultImpl
{
Mapped
value
;
Mapped
*
value
;
bool
found
;
public:
FindResultImpl
(
Mapped
value
,
bool
found
)
:
value
(
value
),
found
(
found
)
{}
FindResultImpl
(
Mapped
*
value
,
bool
found
)
:
value
(
value
),
found
(
found
)
{}
bool
isFound
()
const
{
return
found
;
}
const
Mapped
&
getMapped
()
const
{
return
value
;
}
Mapped
&
getMapped
()
const
{
return
*
value
;
}
};
template
<
>
...
...
@@ -142,7 +142,7 @@ protected:
if
(
cache
.
check
(
key
))
{
if
constexpr
(
has_mapped
)
return
FindResult
(
cache
.
found
?
cache
.
value
.
second
:
Mapped
()
,
cache
.
found
);
return
FindResult
(
&
cache
.
value
.
second
,
cache
.
found
);
else
return
FindResult
(
cache
.
found
);
}
...
...
@@ -168,7 +168,7 @@ protected:
}
if
constexpr
(
has_mapped
)
return
FindResult
(
found
?
it
->
second
:
Mapped
()
,
found
);
return
FindResult
(
found
?
&
it
->
second
:
nullptr
,
found
);
else
return
FindResult
(
found
);
}
...
...
dbms/src/Interpreters/Join.cpp
浏览文件 @
5f1007a8
...
...
@@ -150,18 +150,54 @@ static size_t getTotalByteCountImpl(const Maps & maps, Join::Type type)
}
template
<
Join
::
Type
type
>
struct
KeyGetterForType
;
template
<
Join
::
Type
type
,
typename
Value
,
typename
Mapped
>
struct
KeyGetterForType
Impl
;
template
<
>
struct
KeyGetterForType
<
Join
::
Type
::
key8
>
{
using
Type
=
JoinKeyGetterOneNumber
<
UInt8
>
;
};
template
<
>
struct
KeyGetterForType
<
Join
::
Type
::
key16
>
{
using
Type
=
JoinKeyGetterOneNumber
<
UInt16
>
;
};
template
<
>
struct
KeyGetterForType
<
Join
::
Type
::
key32
>
{
using
Type
=
JoinKeyGetterOneNumber
<
UInt32
>
;
};
template
<
>
struct
KeyGetterForType
<
Join
::
Type
::
key64
>
{
using
Type
=
JoinKeyGetterOneNumber
<
UInt64
>
;
};
template
<
>
struct
KeyGetterForType
<
Join
::
Type
::
key_string
>
{
using
Type
=
JoinKeyGetterString
;
};
template
<
>
struct
KeyGetterForType
<
Join
::
Type
::
key_fixed_string
>
{
using
Type
=
JoinKeyGetterFixedString
;
};
template
<
>
struct
KeyGetterForType
<
Join
::
Type
::
keys128
>
{
using
Type
=
JoinKeyGetterFixed
<
UInt128
>
;
};
template
<
>
struct
KeyGetterForType
<
Join
::
Type
::
keys256
>
{
using
Type
=
JoinKeyGetterFixed
<
UInt256
>
;
};
template
<
>
struct
KeyGetterForType
<
Join
::
Type
::
hashed
>
{
using
Type
=
JoinKeyGetterHashed
;
};
template
<
typename
Value
,
typename
Mapped
>
struct
KeyGetterForTypeImpl
<
Join
::
Type
::
key8
,
Value
,
Mapped
>
{
using
Type
=
ColumnsHashing
::
HashMethodOneNumber
<
Value
,
Mapped
,
UInt8
,
false
>
;
};
template
<
typename
Value
,
typename
Mapped
>
struct
KeyGetterForTypeImpl
<
Join
::
Type
::
key16
,
Value
,
Mapped
>
{
using
Type
=
ColumnsHashing
::
HashMethodOneNumber
<
Value
,
Mapped
,
UInt16
,
false
>
;
};
template
<
typename
Value
,
typename
Mapped
>
struct
KeyGetterForTypeImpl
<
Join
::
Type
::
key32
,
Value
,
Mapped
>
{
using
Type
=
ColumnsHashing
::
HashMethodOneNumber
<
Value
,
Mapped
,
UInt32
,
false
>
;
};
template
<
typename
Value
,
typename
Mapped
>
struct
KeyGetterForTypeImpl
<
Join
::
Type
::
key64
,
Value
,
Mapped
>
{
using
Type
=
ColumnsHashing
::
HashMethodOneNumber
<
Value
,
Mapped
,
UInt64
,
false
>
;
};
template
<
typename
Value
,
typename
Mapped
>
struct
KeyGetterForTypeImpl
<
Join
::
Type
::
key_string
,
Value
,
Mapped
>
{
using
Type
=
ColumnsHashing
::
HashMethodString
<
Value
,
Mapped
,
false
>
;
};
template
<
typename
Value
,
typename
Mapped
>
struct
KeyGetterForTypeImpl
<
Join
::
Type
::
key_fixed_string
,
Value
,
Mapped
>
{
using
Type
=
ColumnsHashing
::
HashMethodFixedString
<
Value
,
Mapped
,
false
>
;
};
template
<
typename
Value
,
typename
Mapped
>
struct
KeyGetterForTypeImpl
<
Join
::
Type
::
keys128
,
Value
,
Mapped
>
{
using
Type
=
ColumnsHashing
::
HashMethodKeysFixed
<
Value
,
UInt128
,
Mapped
,
false
,
false
,
false
>
;
};
template
<
typename
Value
,
typename
Mapped
>
struct
KeyGetterForTypeImpl
<
Join
::
Type
::
keys256
,
Value
,
Mapped
>
{
using
Type
=
ColumnsHashing
::
HashMethodKeysFixed
<
Value
,
UInt256
,
Mapped
,
false
,
false
,
false
>
;
};
template
<
typename
Value
,
typename
Mapped
>
struct
KeyGetterForTypeImpl
<
Join
::
Type
::
hashed
,
Value
,
Mapped
>
{
using
Type
=
ColumnsHashing
::
HashMethodHashed
<
Value
,
Mapped
,
false
>
;
};
template
<
Join
::
Type
type
,
typename
Data
>
struct
KeyGetterForType
{
using
Value
=
typename
Data
::
value_type
;
using
Mapped_t
=
typename
Data
::
mapped_type
;
using
Mapped
=
std
::
conditional_t
<
std
::
is_const_v
<
Data
>
,
const
Mapped_t
,
Mapped_t
>
;
using
Type
=
typename
KeyGetterForTypeImpl
<
type
,
Value
,
Mapped
>::
Type
;
};
/// Do I need to use the hash table maps_*_full, in which we remember whether the row was joined.
...
...
@@ -309,40 +345,30 @@ namespace
template
<
ASTTableJoin
::
Strictness
STRICTNESS
,
typename
Map
,
typename
KeyGetter
>
struct
Inserter
{
static
void
insert
(
Map
&
map
,
const
typename
Map
::
key_type
&
key
,
Block
*
stored_block
,
size_t
i
,
Arena
&
pool
);
static
void
insert
(
Map
&
map
,
KeyGetter
&
key_getter
,
Block
*
stored_block
,
size_t
i
,
Arena
&
pool
);
};
template
<
typename
Map
,
typename
KeyGetter
>
struct
Inserter
<
ASTTableJoin
::
Strictness
::
Any
,
Map
,
KeyGetter
>
{
static
void
insert
(
Map
&
map
,
const
typename
Map
::
key_type
&
key
,
Block
*
stored_block
,
size_t
i
,
Arena
&
pool
)
static
void
insert
(
Map
&
map
,
KeyGetter
&
key_getter
,
Block
*
stored_block
,
size_t
i
,
Arena
&
pool
)
{
typename
Map
::
iterator
it
;
bool
inserted
;
map
.
emplace
(
key
,
it
,
inserted
);
auto
emplace_result
=
key_getter
.
emplaceKey
(
map
,
i
,
pool
);
if
(
inserted
)
{
KeyGetter
::
onNewKey
(
it
->
first
,
pool
);
new
(
&
it
->
second
)
typename
Map
::
mapped_type
(
stored_block
,
i
);
}
if
(
emplace_result
.
isInserted
())
new
(
&
emplace_result
.
getMapped
())
typename
Map
::
mapped_type
(
stored_block
,
i
);
}
};
template
<
typename
Map
,
typename
KeyGetter
>
struct
Inserter
<
ASTTableJoin
::
Strictness
::
All
,
Map
,
KeyGetter
>
{
static
void
insert
(
Map
&
map
,
const
typename
Map
::
key_type
&
key
,
Block
*
stored_block
,
size_t
i
,
Arena
&
pool
)
static
void
insert
(
Map
&
map
,
KeyGetter
&
key_getter
,
Block
*
stored_block
,
size_t
i
,
Arena
&
pool
)
{
typename
Map
::
iterator
it
;
bool
inserted
;
map
.
emplace
(
key
,
it
,
inserted
);
auto
emplace_result
=
key_getter
.
emplaceKey
(
map
,
i
,
pool
);
if
(
inserted
)
{
KeyGetter
::
onNewKey
(
it
->
first
,
pool
);
new
(
&
it
->
second
)
typename
Map
::
mapped_type
(
stored_block
,
i
);
}
if
(
emplace_result
.
isInserted
())
new
(
&
emplace_result
.
getMapped
())
typename
Map
::
mapped_type
(
stored_block
,
i
);
else
{
/** The first element of the list is stored in the value of the hash table, the rest in the pool.
...
...
@@ -350,9 +376,10 @@ namespace
* That is, the former second element, if it was, will be the third, and so on.
*/
auto
elem
=
pool
.
alloc
<
typename
Map
::
mapped_type
>
();
auto
&
mapped
=
emplace_result
.
getMapped
();
elem
->
next
=
it
->
secon
d
.
next
;
it
->
secon
d
.
next
=
elem
;
elem
->
next
=
mappe
d
.
next
;
mappe
d
.
next
=
elem
;
elem
->
block
=
stored_block
;
elem
->
row_num
=
i
;
}
...
...
@@ -363,17 +390,16 @@ namespace
template
<
ASTTableJoin
::
Strictness
STRICTNESS
,
typename
KeyGetter
,
typename
Map
,
bool
has_null_map
>
void
NO_INLINE
insertFromBlockImplTypeCase
(
Map
&
map
,
size_t
rows
,
const
ColumnRawPtrs
&
key_columns
,
size_t
keys_size
,
const
Sizes
&
key_sizes
,
Block
*
stored_block
,
ConstNullMapPtr
null_map
,
Arena
&
pool
)
const
Sizes
&
key_sizes
,
Block
*
stored_block
,
ConstNullMapPtr
null_map
,
Arena
&
pool
)
{
KeyGetter
key_getter
(
key_columns
);
KeyGetter
key_getter
(
key_columns
,
key_sizes
,
nullptr
);
for
(
size_t
i
=
0
;
i
<
rows
;
++
i
)
{
if
(
has_null_map
&&
(
*
null_map
)[
i
])
continue
;
auto
key
=
key_getter
.
getKey
(
key_columns
,
keys_size
,
i
,
key_sizes
);
Inserter
<
STRICTNESS
,
Map
,
KeyGetter
>::
insert
(
map
,
key
,
stored_block
,
i
,
pool
);
Inserter
<
STRICTNESS
,
Map
,
KeyGetter
>::
insert
(
map
,
key_getter
,
stored_block
,
i
,
pool
);
}
}
...
...
@@ -381,19 +407,19 @@ namespace
template
<
ASTTableJoin
::
Strictness
STRICTNESS
,
typename
KeyGetter
,
typename
Map
>
void
insertFromBlockImplType
(
Map
&
map
,
size_t
rows
,
const
ColumnRawPtrs
&
key_columns
,
size_t
keys_size
,
const
Sizes
&
key_sizes
,
Block
*
stored_block
,
ConstNullMapPtr
null_map
,
Arena
&
pool
)
const
Sizes
&
key_sizes
,
Block
*
stored_block
,
ConstNullMapPtr
null_map
,
Arena
&
pool
)
{
if
(
null_map
)
insertFromBlockImplTypeCase
<
STRICTNESS
,
KeyGetter
,
Map
,
true
>
(
map
,
rows
,
key_columns
,
key
s_size
,
key
_sizes
,
stored_block
,
null_map
,
pool
);
insertFromBlockImplTypeCase
<
STRICTNESS
,
KeyGetter
,
Map
,
true
>
(
map
,
rows
,
key_columns
,
key_sizes
,
stored_block
,
null_map
,
pool
);
else
insertFromBlockImplTypeCase
<
STRICTNESS
,
KeyGetter
,
Map
,
false
>
(
map
,
rows
,
key_columns
,
key
s_size
,
key
_sizes
,
stored_block
,
null_map
,
pool
);
insertFromBlockImplTypeCase
<
STRICTNESS
,
KeyGetter
,
Map
,
false
>
(
map
,
rows
,
key_columns
,
key_sizes
,
stored_block
,
null_map
,
pool
);
}
template
<
ASTTableJoin
::
Strictness
STRICTNESS
,
typename
Maps
>
void
insertFromBlockImpl
(
Join
::
Type
type
,
Maps
&
maps
,
size_t
rows
,
const
ColumnRawPtrs
&
key_columns
,
size_t
keys_size
,
const
Sizes
&
key_sizes
,
Block
*
stored_block
,
ConstNullMapPtr
null_map
,
Arena
&
pool
)
const
Sizes
&
key_sizes
,
Block
*
stored_block
,
ConstNullMapPtr
null_map
,
Arena
&
pool
)
{
switch
(
type
)
{
...
...
@@ -402,8 +428,8 @@ namespace
#define M(TYPE) \
case Join::Type::TYPE: \
insertFromBlockImplType<STRICTNESS, typename KeyGetterForType<Join::Type::TYPE>::Type>(\
*maps.TYPE, rows, key_columns, key
s_size, key
_sizes, stored_block, null_map, pool); \
insertFromBlockImplType<STRICTNESS, typename KeyGetterForType<Join::Type::TYPE
, std::remove_reference_t<decltype(*maps.TYPE)>
>::Type>(\
*maps.TYPE, rows, key_columns, key_sizes, stored_block, null_map, pool); \
break;
APPLY_FOR_JOIN_VARIANTS
(
M
)
#undef M
...
...
@@ -486,16 +512,16 @@ bool Join::insertFromBlock(const Block & block)
if
(
!
getFullness
(
kind
))
{
if
(
strictness
==
ASTTableJoin
::
Strictness
::
Any
)
insertFromBlockImpl
<
ASTTableJoin
::
Strictness
::
Any
>
(
type
,
maps_any
,
rows
,
key_columns
,
key
s_size
,
key
_sizes
,
stored_block
,
null_map
,
pool
);
insertFromBlockImpl
<
ASTTableJoin
::
Strictness
::
Any
>
(
type
,
maps_any
,
rows
,
key_columns
,
key_sizes
,
stored_block
,
null_map
,
pool
);
else
insertFromBlockImpl
<
ASTTableJoin
::
Strictness
::
All
>
(
type
,
maps_all
,
rows
,
key_columns
,
key
s_size
,
key
_sizes
,
stored_block
,
null_map
,
pool
);
insertFromBlockImpl
<
ASTTableJoin
::
Strictness
::
All
>
(
type
,
maps_all
,
rows
,
key_columns
,
key_sizes
,
stored_block
,
null_map
,
pool
);
}
else
{
if
(
strictness
==
ASTTableJoin
::
Strictness
::
Any
)
insertFromBlockImpl
<
ASTTableJoin
::
Strictness
::
Any
>
(
type
,
maps_any_full
,
rows
,
key_columns
,
key
s_size
,
key
_sizes
,
stored_block
,
null_map
,
pool
);
insertFromBlockImpl
<
ASTTableJoin
::
Strictness
::
Any
>
(
type
,
maps_any_full
,
rows
,
key_columns
,
key_sizes
,
stored_block
,
null_map
,
pool
);
else
insertFromBlockImpl
<
ASTTableJoin
::
Strictness
::
All
>
(
type
,
maps_all_full
,
rows
,
key_columns
,
key
s_size
,
key
_sizes
,
stored_block
,
null_map
,
pool
);
insertFromBlockImpl
<
ASTTableJoin
::
Strictness
::
All
>
(
type
,
maps_all_full
,
rows
,
key_columns
,
key_sizes
,
stored_block
,
null_map
,
pool
);
}
}
...
...
@@ -511,14 +537,14 @@ namespace
template
<
typename
Map
>
struct
Adder
<
ASTTableJoin
::
Kind
::
Left
,
ASTTableJoin
::
Strictness
::
Any
,
Map
>
{
static
void
addFound
(
const
typename
Map
::
const_iterator
&
it
,
size_t
num_columns_to_add
,
MutableColumns
&
added_columns
,
static
void
addFound
(
const
typename
Map
::
mapped_type
&
mapped
,
size_t
num_columns_to_add
,
MutableColumns
&
added_columns
,
size_t
i
,
IColumn
::
Filter
*
filter
,
IColumn
::
Offset
&
/*current_offset*/
,
IColumn
::
Offsets
*
/*offsets*/
,
const
std
::
vector
<
size_t
>
&
right_indexes
)
{
(
*
filter
)[
i
]
=
1
;
for
(
size_t
j
=
0
;
j
<
num_columns_to_add
;
++
j
)
added_columns
[
j
]
->
insertFrom
(
*
it
->
second
.
block
->
getByPosition
(
right_indexes
[
j
]).
column
.
get
(),
it
->
secon
d
.
row_num
);
added_columns
[
j
]
->
insertFrom
(
*
mapped
.
block
->
getByPosition
(
right_indexes
[
j
]).
column
,
mappe
d
.
row_num
);
}
static
void
addNotFound
(
size_t
num_columns_to_add
,
MutableColumns
&
added_columns
,
...
...
@@ -534,14 +560,14 @@ namespace
template
<
typename
Map
>
struct
Adder
<
ASTTableJoin
::
Kind
::
Inner
,
ASTTableJoin
::
Strictness
::
Any
,
Map
>
{
static
void
addFound
(
const
typename
Map
::
const_iterator
&
it
,
size_t
num_columns_to_add
,
MutableColumns
&
added_columns
,
static
void
addFound
(
const
typename
Map
::
mapped_type
&
mapped
,
size_t
num_columns_to_add
,
MutableColumns
&
added_columns
,
size_t
i
,
IColumn
::
Filter
*
filter
,
IColumn
::
Offset
&
/*current_offset*/
,
IColumn
::
Offsets
*
/*offsets*/
,
const
std
::
vector
<
size_t
>
&
right_indexes
)
{
(
*
filter
)[
i
]
=
1
;
for
(
size_t
j
=
0
;
j
<
num_columns_to_add
;
++
j
)
added_columns
[
j
]
->
insertFrom
(
*
it
->
second
.
block
->
getByPosition
(
right_indexes
[
j
]).
column
.
get
(),
it
->
secon
d
.
row_num
);
added_columns
[
j
]
->
insertFrom
(
*
mapped
.
block
->
getByPosition
(
right_indexes
[
j
]).
column
,
mappe
d
.
row_num
);
}
static
void
addNotFound
(
size_t
/*num_columns_to_add*/
,
MutableColumns
&
/*added_columns*/
,
...
...
@@ -554,14 +580,14 @@ namespace
template
<
ASTTableJoin
::
Kind
KIND
,
typename
Map
>
struct
Adder
<
KIND
,
ASTTableJoin
::
Strictness
::
All
,
Map
>
{
static
void
addFound
(
const
typename
Map
::
const_iterator
&
it
,
size_t
num_columns_to_add
,
MutableColumns
&
added_columns
,
static
void
addFound
(
const
typename
Map
::
mapped_type
&
mapped
,
size_t
num_columns_to_add
,
MutableColumns
&
added_columns
,
size_t
i
,
IColumn
::
Filter
*
filter
,
IColumn
::
Offset
&
current_offset
,
IColumn
::
Offsets
*
offsets
,
const
std
::
vector
<
size_t
>
&
right_indexes
)
{
(
*
filter
)[
i
]
=
1
;
size_t
rows_joined
=
0
;
for
(
auto
current
=
&
static_cast
<
const
typename
Map
::
mapped_type
::
Base_t
&>
(
it
->
secon
d
);
current
!=
nullptr
;
current
=
current
->
next
)
for
(
auto
current
=
&
static_cast
<
const
typename
Map
::
mapped_type
::
Base_t
&>
(
mappe
d
);
current
!=
nullptr
;
current
=
current
->
next
)
{
for
(
size_t
j
=
0
;
j
<
num_columns_to_add
;
++
j
)
added_columns
[
j
]
->
insertFrom
(
*
current
->
block
->
getByPosition
(
right_indexes
[
j
]).
column
.
get
(),
current
->
row_num
);
...
...
@@ -600,10 +626,10 @@ namespace
IColumn
::
Offset
&
current_offset
,
std
::
unique_ptr
<
IColumn
::
Offsets
>
&
offsets_to_replicate
,
const
std
::
vector
<
size_t
>
&
right_indexes
)
{
size_t
keys_size
=
key_columns
.
size
();
size_t
num_columns_to_add
=
right_indexes
.
size
();
KeyGetter
key_getter
(
key_columns
);
Arena
pool
;
KeyGetter
key_getter
(
key_columns
,
key_sizes
,
nullptr
);
for
(
size_t
i
=
0
;
i
<
rows
;
++
i
)
{
...
...
@@ -614,14 +640,14 @@ namespace
}
else
{
auto
key
=
key_getter
.
getKey
(
key_columns
,
keys_size
,
i
,
key_sizes
);
typename
Map
::
const_iterator
it
=
map
.
find
(
key
);
auto
find_result
=
key_getter
.
findKey
(
map
,
i
,
pool
);
if
(
it
!=
map
.
e
nd
())
if
(
find_result
.
isFou
nd
())
{
it
->
second
.
setUsed
();
auto
&
mapped
=
find_result
.
getMapped
();
mapped
.
setUsed
();
Adder
<
KIND
,
STRICTNESS
,
Map
>::
addFound
(
it
,
num_columns_to_add
,
added_columns
,
i
,
filter
.
get
(),
current_offset
,
offsets_to_replicate
.
get
(),
right_indexes
);
mapped
,
num_columns_to_add
,
added_columns
,
i
,
filter
.
get
(),
current_offset
,
offsets_to_replicate
.
get
(),
right_indexes
);
}
else
Adder
<
KIND
,
STRICTNESS
,
Map
>::
addNotFound
(
...
...
@@ -748,7 +774,7 @@ void Join::joinBlockImpl(
{
#define M(TYPE) \
case Join::Type::TYPE: \
joinBlockImplType<KIND, STRICTNESS, typename KeyGetterForType<Join::Type::TYPE>::Type>(\
joinBlockImplType<KIND, STRICTNESS, typename KeyGetterForType<Join::Type::TYPE
, const std::remove_reference_t<decltype(*maps.TYPE)>
>::Type>(\
*maps.TYPE, rows, key_columns, key_sizes, added_columns, null_map, \
filter, current_offset, offsets_to_replicate, right_indexes); \
break;
...
...
dbms/src/Interpreters/Join.h
浏览文件 @
5f1007a8
...
...
@@ -8,6 +8,7 @@
#include <Interpreters/SettingsCommon.h>
#include <Common/Arena.h>
#include <Common/ColumnsHashing.h>
#include <Common/HashTable/HashMap.h>
#include <Columns/ColumnString.h>
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录