Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2dot5
ClickHouse
提交
1b891e04
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 搜索 >>
提交
1b891e04
编写于
1月 28, 2021
作者:
A
Alexander Kuzmenkov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix a bug
上级
b508fab8
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
54 addition
and
10 deletion
+54
-10
src/Processors/Transforms/WindowTransform.cpp
src/Processors/Transforms/WindowTransform.cpp
+37
-10
tests/queries/0_stateless/01591_window_functions.reference
tests/queries/0_stateless/01591_window_functions.reference
+13
-0
tests/queries/0_stateless/01591_window_functions.sql
tests/queries/0_stateless/01591_window_functions.sql
+4
-0
未找到文件。
src/Processors/Transforms/WindowTransform.cpp
浏览文件 @
1b891e04
...
...
@@ -211,6 +211,8 @@ bool WindowTransform::arePeers(const RowNumber & x, const RowNumber & y) const
void
WindowTransform
::
advanceFrameEndCurrentRow
()
{
// fmt::print(stderr, "starting from frame_end {}\n", frame_end);
// We only process one block here, and frame_end must be already in it: if
// we didn't find the end in the previous block, frame_end is now the first
// row of the current block. We need this knowledge to write a simpler loop
...
...
@@ -229,24 +231,46 @@ void WindowTransform::advanceFrameEndCurrentRow()
return
;
}
const
auto
block_rows
=
blockRowsNumber
(
frame_end
);
// We advance until the partition end. It's either in the current block or
// in the next one, which is also the past-the-end block. Figure out how
// many rows we have to process.
uint64_t
rows_end
;
if
(
partition_end
.
row
==
0
)
{
assert
(
partition_end
==
blocksEnd
());
rows_end
=
blockRowsNumber
(
frame_end
);
}
else
{
assert
(
frame_end
.
block
==
partition_end
.
block
);
rows_end
=
partition_end
.
row
;
}
// Equality would mean "no data to process", for which we checked above.
assert
(
frame_end
.
row
<
rows_end
);
// fmt::print(stderr, "first row {} last {}\n", frame_end.row, rows_end);
// We could retreat the frame_end here, but for some reason I am reluctant
// to do this... It would have better data locality.
auto
reference
=
current_row
;
for
(;
frame_end
.
row
<
block_rows
;
++
frame_end
.
row
)
for
(;
frame_end
.
row
<
rows_end
;
++
frame_end
.
row
)
{
if
(
!
arePeers
(
reference
,
frame_end
))
{
//
fmt::print(stderr, "{} and {} don't match\n", reference, frame_end);
//
fmt::print(stderr, "{} and {} don't match\n", reference, frame_end);
frame_ended
=
true
;
return
;
}
reference
=
frame_end
;
}
// Got to the end of current block, have to properly update the row number.
++
frame_end
.
block
;
frame_end
.
row
=
0
;
// Might have gotten to the end of the current block, have to properly
// update the row number.
if
(
frame_end
.
row
==
blockRowsNumber
(
frame_end
))
{
++
frame_end
.
block
;
frame_end
.
row
=
0
;
}
// Got to the end of partition (frame ended as well then) or end of data.
assert
(
frame_end
==
partition_end
);
...
...
@@ -263,6 +287,8 @@ void WindowTransform::advanceFrameEnd()
// The only frame end we have for now is CURRENT ROW.
advanceFrameEndCurrentRow
();
// fmt::print(stderr, "frame_end {} -> {}\n", frame_end_before, frame_end);
// We might not have advanced the frame end if we found out we reached the
// end of input or the partition, or if we still don't know the frame start.
if
(
frame_end_before
==
frame_end
)
...
...
@@ -273,17 +299,18 @@ void WindowTransform::advanceFrameEnd()
// Add the columns over which we advanced the frame to the aggregate function
// states.
// We could have advanced over at most the entire last block.
uint64_t
last_row
=
frame_end
.
row
;
uint64_t
rows_end
=
frame_end
.
row
;
if
(
frame_end
.
row
==
0
)
{
assert
(
frame_end
==
blocksEnd
());
last_row
=
blockRowsNumber
(
frame_end_before
);
rows_end
=
blockRowsNumber
(
frame_end_before
);
}
else
{
assert
(
frame_end_before
.
block
==
frame_end
.
block
);
}
assert
(
frame_end_before
.
row
<
last_row
);
// Equality would mean "no data to process", for which we checked above.
assert
(
frame_end_before
.
row
<
rows_end
);
for
(
auto
&
ws
:
workspaces
)
{
...
...
@@ -302,7 +329,7 @@ void WindowTransform::advanceFrameEnd()
const
auto
*
a
=
ws
.
window_function
.
aggregate_function
.
get
();
auto
*
buf
=
ws
.
aggregate_function_state
.
data
();
auto
*
columns
=
ws
.
argument_columns
.
data
();
for
(
auto
row
=
frame_end_before
.
row
;
row
<
last_row
;
++
row
)
for
(
auto
row
=
frame_end_before
.
row
;
row
<
rows_end
;
++
row
)
{
a
->
add
(
buf
,
columns
,
row
,
arena
.
get
());
}
...
...
tests/queries/0_stateless/01591_window_functions.reference
浏览文件 @
1b891e04
...
...
@@ -459,3 +459,16 @@ settings max_block_size = 5
28 14 1 1
29 14 2 2
30 15 0 1
-- A case where the partition end is in the current block, and the frame end
-- is triggered by the partition end.
select min(number) over (partition by p) from (select number, intDiv(number, 3) p from numbers(10));
0
0
0
3
3
3
6
6
6
9
tests/queries/0_stateless/01591_window_functions.sql
浏览文件 @
1b891e04
...
...
@@ -144,3 +144,7 @@ window w as (partition by p order by o range unbounded preceding)
order
by
number
settings
max_block_size
=
5
;
-- A case where the partition end is in the current block, and the frame end
-- is triggered by the partition end.
select
min
(
number
)
over
(
partition
by
p
)
from
(
select
number
,
intDiv
(
number
,
3
)
p
from
numbers
(
10
));
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录