Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2dot5
ClickHouse
提交
11b4bc71
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,体验更适合开发者的 AI 搜索 >>
未验证
提交
11b4bc71
编写于
5月 15, 2020
作者:
A
Anton Popov
提交者:
GitHub
5月 15, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #10889 from CurtizJ/tuple-literal
Fix backward compatibility with tuples and distributed.
上级
aa17da6b
4c0cbc78
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
101 addition
and
5 deletion
+101
-5
src/Parsers/ASTLiteral.cpp
src/Parsers/ASTLiteral.cpp
+36
-5
tests/integration/test_distributed_backward_compatability/__init__.py
...ation/test_distributed_backward_compatability/__init__.py
+0
-0
tests/integration/test_distributed_backward_compatability/configs/remote_servers.xml
...ributed_backward_compatability/configs/remote_servers.xml
+18
-0
tests/integration/test_distributed_backward_compatability/test.py
...tegration/test_distributed_backward_compatability/test.py
+47
-0
未找到文件。
src/Parsers/ASTLiteral.cpp
浏览文件 @
11b4bc71
...
...
@@ -2,6 +2,8 @@
#include <Common/FieldVisitors.h>
#include <Parsers/ASTLiteral.h>
#include <IO/WriteHelpers.h>
#include <IO/WriteBufferFromString.h>
#include <IO/Operators.h>
namespace
DB
...
...
@@ -14,30 +16,59 @@ void ASTLiteral::updateTreeHashImpl(SipHash & hash_state) const
applyVisitor
(
FieldVisitorHash
(
hash_state
),
value
);
}
/// Writes 'tuple' word before tuple literals for backward compatibility reasons.
/// TODO: remove, when versions lower than 20.3 will be rearely used.
class
FieldVisitorToColumnName
:
public
StaticVisitor
<
String
>
{
public:
template
<
typename
T
>
String
operator
()
(
const
T
&
x
)
const
{
return
visitor
(
x
);
}
private:
FieldVisitorToString
visitor
;
};
template
<
>
String
FieldVisitorToColumnName
::
operator
()
(
const
Tuple
&
x
)
const
{
WriteBufferFromOwnString
wb
;
wb
<<
"tuple("
;
for
(
auto
it
=
x
.
begin
();
it
!=
x
.
end
();
++
it
)
{
if
(
it
!=
x
.
begin
())
wb
<<
", "
;
wb
<<
applyVisitor
(
*
this
,
*
it
);
}
wb
<<
')'
;
return
wb
.
str
();
}
void
ASTLiteral
::
appendColumnNameImpl
(
WriteBuffer
&
ostr
)
const
{
/// 100 - just arbitrary value.
constexpr
auto
min_elements_for_hashing
=
100
;
/// Special case for very large arrays
and tuples
. Instead of listing all elements, will use hash of them.
/// Special case for very large arrays. Instead of listing all elements, will use hash of them.
/// (Otherwise column name will be too long, that will lead to significant slowdown of expression analysis.)
/// TODO: Also do hashing for large tuples, when versions lower than 20.3 will be rarely used, because it breaks backward compatibility.
auto
type
=
value
.
getType
();
if
((
type
==
Field
::
Types
::
Array
&&
value
.
get
<
const
Array
&>
().
size
()
>
min_elements_for_hashing
)
||
(
type
==
Field
::
Types
::
Tuple
&&
value
.
get
<
const
Tuple
&>
().
size
()
>
min_elements_for_hashing
))
if
((
type
==
Field
::
Types
::
Array
&&
value
.
get
<
const
Array
&>
().
size
()
>
min_elements_for_hashing
))
{
SipHash
hash
;
applyVisitor
(
FieldVisitorHash
(
hash
),
value
);
UInt64
low
,
high
;
hash
.
get128
(
low
,
high
);
writeCString
(
type
==
Field
::
Types
::
Array
?
"__array_"
:
"__tuple
_"
,
ostr
);
writeCString
(
"__array
_"
,
ostr
);
writeText
(
low
,
ostr
);
ostr
.
write
(
'_'
);
writeText
(
high
,
ostr
);
}
else
{
String
column_name
=
applyVisitor
(
FieldVisitorTo
String
(),
value
);
String
column_name
=
applyVisitor
(
FieldVisitorTo
ColumnName
(),
value
);
writeString
(
column_name
,
ostr
);
}
}
...
...
tests/integration/test_distributed_backward_compatability/__init__.py
0 → 100644
浏览文件 @
11b4bc71
tests/integration/test_distributed_backward_compatability/configs/remote_servers.xml
0 → 100644
浏览文件 @
11b4bc71
<yandex>
<remote_servers>
<test_cluster>
<shard>
<replica>
<host>
node1
</host>
<port>
9000
</port>
</replica>
</shard>
<shard>
<replica>
<host>
node2
</host>
<port>
9000
</port>
</replica>
</shard>
</test_cluster>
</remote_servers>
</yandex>
tests/integration/test_distributed_backward_compatability/test.py
0 → 100644
浏览文件 @
11b4bc71
import
pytest
import
time
from
helpers.cluster
import
ClickHouseCluster
from
helpers.network
import
PartitionManager
from
helpers.test_tools
import
TSV
cluster
=
ClickHouseCluster
(
__file__
)
node_old
=
cluster
.
add_instance
(
'node1'
,
main_configs
=
[
'configs/remote_servers.xml'
],
image
=
'yandex/clickhouse-server:19.17.8.54'
,
stay_alive
=
True
,
with_installed_binary
=
True
)
node_new
=
cluster
.
add_instance
(
'node2'
,
main_configs
=
[
'configs/remote_servers.xml'
])
@
pytest
.
fixture
(
scope
=
"module"
)
def
started_cluster
():
try
:
cluster
.
start
()
for
node
in
(
node_old
,
node_new
):
node
.
query
(
"CREATE TABLE local_table(id UInt32, val String) ENGINE = MergeTree ORDER BY id"
)
node_old
.
query
(
"INSERT INTO local_table VALUES (1, 'node1')"
)
node_new
.
query
(
"INSERT INTO local_table VALUES (2, 'node2')"
)
node_old
.
query
(
"CREATE TABLE distributed(id UInt32, val String) ENGINE = Distributed(test_cluster, default, local_table)"
)
node_new
.
query
(
"CREATE TABLE distributed(id UInt32, val String) ENGINE = Distributed(test_cluster, default, local_table)"
)
yield
cluster
finally
:
cluster
.
shutdown
()
def
test_distributed_in_tuple
(
started_cluster
):
query1
=
"SELECT count() FROM distributed WHERE (id, val) IN ((1, 'node1'), (2, 'a'), (3, 'b'))"
query2
=
"SELECT sum((id, val) IN ((1, 'node1'), (2, 'a'), (3, 'b'))) FROM distributed"
assert
node_old
.
query
(
query1
)
==
"1
\n
"
assert
node_old
.
query
(
query2
)
==
"1
\n
"
assert
node_new
.
query
(
query1
)
==
"1
\n
"
assert
node_new
.
query
(
query2
)
==
"1
\n
"
large_set
=
'('
+
','
.
join
([
str
(
i
)
for
i
in
range
(
1000
)])
+
')'
query3
=
"SELECT count() FROM distributed WHERE id IN "
+
large_set
query4
=
"SELECT sum(id IN {}) FROM distributed"
.
format
(
large_set
)
assert
node_old
.
query
(
query3
)
==
"2
\n
"
assert
node_old
.
query
(
query4
)
==
"2
\n
"
assert
node_new
.
query
(
query3
)
==
"2
\n
"
assert
node_new
.
query
(
query4
)
==
"2
\n
"
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录