Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2dot5
ClickHouse
提交
9a1c286a
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,发现更多精彩内容 >>
提交
9a1c286a
编写于
5月 16, 2018
作者:
N
Nikolai Kochetov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Changed prepared set indexation from AST* to StringRange. [#CLICKHOUSE-3734]
上级
d31b897b
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
38 addition
and
51 deletion
+38
-51
dbms/src/Interpreters/ExpressionAnalyzer.cpp
dbms/src/Interpreters/ExpressionAnalyzer.cpp
+9
-9
dbms/src/Interpreters/ExpressionAnalyzer.h
dbms/src/Interpreters/ExpressionAnalyzer.h
+4
-4
dbms/src/Parsers/IAST.h
dbms/src/Parsers/IAST.h
+1
-1
dbms/src/Parsers/StringRange.h
dbms/src/Parsers/StringRange.h
+18
-2
dbms/src/Storages/MergeTree/KeyCondition.cpp
dbms/src/Storages/MergeTree/KeyCondition.cpp
+3
-3
dbms/src/Storages/MergeTree/MergeTreeWhereOptimizer.cpp
dbms/src/Storages/MergeTree/MergeTreeWhereOptimizer.cpp
+1
-1
dbms/src/Storages/SelectQueryInfo.h
dbms/src/Storages/SelectQueryInfo.h
+2
-2
dbms/src/Storages/StorageMerge.cpp
dbms/src/Storages/StorageMerge.cpp
+0
-29
未找到文件。
dbms/src/Interpreters/ExpressionAnalyzer.cpp
浏览文件 @
9a1c286a
...
...
@@ -1486,7 +1486,7 @@ void ExpressionAnalyzer::tryMakeSetFromSubquery(const ASTPtr & subquery_or_table
return
;
}
prepared_sets
[
subquery_or_table_name
.
get
()
]
=
std
::
move
(
set
);
prepared_sets
[
subquery_or_table_name
->
range
]
=
std
::
move
(
set
);
}
...
...
@@ -1515,7 +1515,7 @@ void ExpressionAnalyzer::makeSetsForIndexImpl(const ASTPtr & node, const Block &
{
const
ASTPtr
&
arg
=
args
.
children
.
at
(
1
);
if
(
!
prepared_sets
.
count
(
arg
.
get
()
))
/// Not already prepared.
if
(
!
prepared_sets
.
count
(
arg
->
range
))
/// Not already prepared.
{
if
(
typeid_cast
<
ASTSubquery
*>
(
arg
.
get
())
||
typeid_cast
<
ASTIdentifier
*>
(
arg
.
get
()))
{
...
...
@@ -1550,7 +1550,7 @@ void ExpressionAnalyzer::makeSet(const ASTFunction * node, const Block & sample_
const
ASTPtr
&
arg
=
args
.
children
.
at
(
1
);
/// Already converted.
if
(
prepared_sets
.
count
(
arg
.
get
()
))
if
(
prepared_sets
.
count
(
arg
->
range
))
return
;
/// If the subquery or table name for SELECT.
...
...
@@ -1573,7 +1573,7 @@ void ExpressionAnalyzer::makeSet(const ASTFunction * node, const Block & sample_
if
(
storage_set
)
{
prepared_sets
[
arg
.
get
()
]
=
storage_set
->
getSet
();
prepared_sets
[
arg
->
range
]
=
storage_set
->
getSet
();
return
;
}
}
...
...
@@ -1584,7 +1584,7 @@ void ExpressionAnalyzer::makeSet(const ASTFunction * node, const Block & sample_
/// If you already created a Set with the same subquery / table.
if
(
subquery_for_set
.
set
)
{
prepared_sets
[
arg
.
get
()
]
=
subquery_for_set
.
set
;
prepared_sets
[
arg
->
range
]
=
subquery_for_set
.
set
;
return
;
}
...
...
@@ -1630,7 +1630,7 @@ void ExpressionAnalyzer::makeSet(const ASTFunction * node, const Block & sample_
}
subquery_for_set
.
set
=
set
;
prepared_sets
[
arg
.
get
()
]
=
set
;
prepared_sets
[
arg
->
range
]
=
set
;
}
else
{
...
...
@@ -1712,7 +1712,7 @@ void ExpressionAnalyzer::makeExplicitSet(const ASTFunction * node, const Block &
SetPtr
set
=
std
::
make_shared
<
Set
>
(
SizeLimits
(
settings
.
max_rows_in_set
,
settings
.
max_bytes_in_set
,
settings
.
set_overflow_mode
));
set
->
createFromAST
(
set_element_types
,
elements_ast
,
context
,
create_ordered_set
);
prepared_sets
[
right_arg
.
get
()
]
=
std
::
move
(
set
);
prepared_sets
[
right_arg
->
range
]
=
std
::
move
(
set
);
}
...
...
@@ -2102,12 +2102,12 @@ void ExpressionAnalyzer::getActionsImpl(const ASTPtr & ast, bool no_subqueries,
/// Select the name in the next cycle.
argument_names
.
emplace_back
();
}
else
if
(
prepared_sets
.
count
(
child
.
get
()
)
&&
functionIsInOrGlobalInOperator
(
node
->
name
)
&&
arg
==
1
)
else
if
(
prepared_sets
.
count
(
child
->
range
)
&&
functionIsInOrGlobalInOperator
(
node
->
name
)
&&
arg
==
1
)
{
ColumnWithTypeAndName
column
;
column
.
type
=
std
::
make_shared
<
DataTypeSet
>
();
const
SetPtr
&
set
=
prepared_sets
[
child
.
get
()
];
const
SetPtr
&
set
=
prepared_sets
[
child
->
range
];
/// If the argument is a set given by an enumeration of values (so, the set was already built), give it a unique name,
/// so that sets with the same literal representation do not fuse together (they can have different types).
...
...
dbms/src/Interpreters/ExpressionAnalyzer.h
浏览文件 @
9a1c286a
...
...
@@ -3,9 +3,9 @@
#include <Interpreters/AggregateDescription.h>
#include <Interpreters/Settings.h>
#include <Core/Block.h>
#include
"ExpressionActions.h"
#include
"ProjectionManipulation.h"
#include
<Interpreters/ExpressionActions.h>
#include
<Interpreters/ProjectionManipulation.h>
#include <Parsers/StringRange.h>
namespace
DB
{
...
...
@@ -23,7 +23,7 @@ using ASTPtr = std::shared_ptr<IAST>;
class
Set
;
using
SetPtr
=
std
::
shared_ptr
<
Set
>
;
using
PreparedSets
=
std
::
unordered_map
<
IAST
*
,
SetPtr
>
;
using
PreparedSets
=
std
::
unordered_map
<
StringRange
,
SetPtr
,
StringRangeHash
>
;
class
IBlockInputStream
;
using
BlockInputStreamPtr
=
std
::
shared_ptr
<
IBlockInputStream
>
;
...
...
dbms/src/Parsers/IAST.h
浏览文件 @
9a1c286a
...
...
@@ -65,7 +65,7 @@ public:
ASTPtr
ptr
()
{
return
shared_from_this
();
}
/** Get a deep copy of the tree. */
/** Get a deep copy of the tree.
Cloned object must have the same range.
*/
virtual
ASTPtr
clone
()
const
=
0
;
/** Get hash code, identifying this element and its subtree.
...
...
dbms/src/Parsers/StringRange.h
浏览文件 @
9a1c286a
...
...
@@ -4,6 +4,7 @@
#include <Parsers/TokenIterator.h>
#include <map>
#include <memory>
#include <Common/SipHash.h>
namespace
DB
...
...
@@ -14,9 +15,10 @@ struct StringRange
const
char
*
first
=
nullptr
;
const
char
*
second
=
nullptr
;
StringRange
()
{}
StringRange
()
=
default
;
StringRange
(
const
StringRange
&
other
)
=
default
;
StringRange
(
const
char
*
begin
,
const
char
*
end
)
:
first
(
begin
),
second
(
end
)
{}
StringRange
(
TokenIterator
token
)
:
first
(
token
->
begin
),
second
(
token
->
end
)
{}
explicit
StringRange
(
TokenIterator
token
)
:
first
(
token
->
begin
),
second
(
token
->
end
)
{}
StringRange
(
TokenIterator
token_begin
,
TokenIterator
token_end
)
{
...
...
@@ -34,6 +36,8 @@ struct StringRange
first
=
token_begin
->
begin
;
second
=
token_last
->
end
;
}
bool
operator
==
(
const
StringRange
&
rhs
)
const
{
return
std
::
tie
(
first
,
second
)
==
std
::
tie
(
rhs
.
first
,
rhs
.
second
);
}
};
using
StringPtr
=
std
::
shared_ptr
<
String
>
;
...
...
@@ -44,4 +48,16 @@ inline String toString(const StringRange & range)
return
range
.
first
?
String
(
range
.
first
,
range
.
second
)
:
String
();
}
struct
StringRangeHash
{
UInt64
operator
()(
const
StringRange
&
range
)
const
{
SipHash
hash
;
hash
.
update
(
range
.
first
);
hash
.
update
(
range
.
second
);
return
hash
.
get64
();
}
};
}
dbms/src/Storages/MergeTree/KeyCondition.cpp
浏览文件 @
9a1c286a
...
...
@@ -641,8 +641,8 @@ bool KeyCondition::atomFromAST(const ASTPtr & node, const Context & context, Blo
bool
is_set_const
=
false
;
bool
is_constant_transformed
=
false
;
if
(
prepared_sets
.
count
(
args
[
1
]
.
get
()
)
&&
isTupleIndexable
(
args
[
0
],
context
,
out
,
prepared_sets
[
args
[
1
]
.
get
()
],
key_column_num
))
if
(
prepared_sets
.
count
(
args
[
1
]
->
range
)
&&
isTupleIndexable
(
args
[
0
],
context
,
out
,
prepared_sets
[
args
[
1
]
->
range
],
key_column_num
))
{
key_arg_pos
=
0
;
is_set_const
=
true
;
...
...
@@ -1016,7 +1016,7 @@ bool KeyCondition::mayBeTrueInRangeImpl(const std::vector<Range> & key_ranges, c
{
auto
in_func
=
typeid_cast
<
const
ASTFunction
*>
(
element
.
in_function
.
get
());
const
ASTs
&
args
=
typeid_cast
<
const
ASTExpressionList
&>
(
*
in_func
->
arguments
).
children
;
PreparedSets
::
const_iterator
it
=
prepared_sets
.
find
(
args
[
1
]
.
get
()
);
PreparedSets
::
const_iterator
it
=
prepared_sets
.
find
(
args
[
1
]
->
range
);
if
(
in_func
&&
it
!=
prepared_sets
.
end
())
{
rpn_stack
.
emplace_back
(
element
.
set_index
->
mayBeTrueInRange
(
key_ranges
,
data_types
));
...
...
dbms/src/Storages/MergeTree/MergeTreeWhereOptimizer.cpp
浏览文件 @
9a1c286a
...
...
@@ -334,7 +334,7 @@ bool MergeTreeWhereOptimizer::isPrimaryKeyAtom(const IAST * const ast) const
if
((
primary_key_columns
.
count
(
first_arg_name
)
&&
isConstant
(
args
[
1
]))
||
(
primary_key_columns
.
count
(
second_arg_name
)
&&
isConstant
(
args
[
0
]))
||
(
primary_key_columns
.
count
(
first_arg_name
)
&&
(
prepared_sets
.
count
(
args
[
1
]
.
get
()
)
||
typeid_cast
<
const
ASTSubquery
*>
(
args
[
1
].
get
()))))
&&
(
prepared_sets
.
count
(
args
[
1
]
->
range
)
||
typeid_cast
<
const
ASTSubquery
*>
(
args
[
1
].
get
()))))
return
true
;
}
...
...
dbms/src/Storages/SelectQueryInfo.h
浏览文件 @
9a1c286a
...
...
@@ -2,7 +2,7 @@
#include <memory>
#include <unordered_map>
#include <Parsers/StringRange.h>
namespace
DB
{
...
...
@@ -14,7 +14,7 @@ class Set;
using
SetPtr
=
std
::
shared_ptr
<
Set
>
;
/// Information about calculated sets in right hand side of IN.
using
PreparedSets
=
std
::
unordered_map
<
IAST
*
,
SetPtr
>
;
using
PreparedSets
=
std
::
unordered_map
<
StringRange
,
SetPtr
,
StringRangeHash
>
;
/** Query along with some additional data,
...
...
dbms/src/Storages/StorageMerge.cpp
浏览文件 @
9a1c286a
...
...
@@ -84,33 +84,6 @@ bool StorageMerge::isRemote() const
}
namespace
{
using
NodeHashToSet
=
std
::
map
<
IAST
::
Hash
,
SetPtr
>
;
void
relinkSetsImpl
(
const
ASTPtr
&
query
,
const
NodeHashToSet
&
node_hash_to_set
,
PreparedSets
&
new_sets
)
{
auto
hash
=
query
->
getTreeHash
();
auto
it
=
node_hash_to_set
.
find
(
hash
);
if
(
node_hash_to_set
.
end
()
!=
it
)
new_sets
[
query
.
get
()]
=
it
->
second
;
for
(
const
auto
&
child
:
query
->
children
)
relinkSetsImpl
(
child
,
node_hash_to_set
,
new_sets
);
}
/// Re-link prepared sets onto cloned and modified AST.
void
relinkSets
(
const
ASTPtr
&
query
,
const
PreparedSets
&
old_sets
,
PreparedSets
&
new_sets
)
{
NodeHashToSet
node_hash_to_set
;
for
(
const
auto
&
node_set
:
old_sets
)
node_hash_to_set
.
emplace
(
node_set
.
first
->
getTreeHash
(),
node_set
.
second
);
relinkSetsImpl
(
query
,
node_hash_to_set
,
new_sets
);
}
}
bool
StorageMerge
::
mayBenefitFromIndexForIn
(
const
ASTPtr
&
left_in_operand
)
const
{
/// It's beneficial if it is true for at least one table.
...
...
@@ -211,8 +184,6 @@ BlockInputStreams StorageMerge::read(
SelectQueryInfo
modified_query_info
;
modified_query_info
.
query
=
modified_query_ast
;
relinkSets
(
modified_query_info
.
query
,
query_info
.
sets
,
modified_query_info
.
sets
);
BlockInputStreams
source_streams
;
if
(
curr_table_number
<
num_streams
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录