the reference was correct after all, I just confused the sides of the

diff
This commit is contained in:
Alexander Kuzmenkov 2021-07-29 15:49:37 +03:00
parent 7c9467d7a7
commit 55e1d1b592
2 changed files with 173 additions and 169 deletions

View File

@ -315,7 +315,7 @@ void WindowTransform::advancePartitionEnd()
const RowNumber end = blocksEnd();
// fmt::print(stderr, "end {}, partition_end {}\n", end, partition_end);
// fmt::print(stderr, "end {}, partition_end {}\n", end, partition_end);
// If we're at the total end of data, we must end the partition. This is one
// of the few places in calculations where we need special handling for end
@ -361,31 +361,31 @@ void WindowTransform::advancePartitionEnd()
// The partition ends when the PARTITION BY columns change. We need
// some reference columns for comparison. We might have already
// dropped the blocks where the partition starts, but any other row in the
// partition will do. We can't use current_row for this (the next row for
// which we are calculating the window functions), because it might be past
// the partition end. The frame pointers are more suitable because they are
// always inside the partition and we keep the frame in memory. Use
// frame_end because it's closer to the partition_end and will give better
// data locality.
// partition will do. We can't use frame_start or frame_end or current_row (the next row
// for which we are calculating the window functions), because they all might be
// past the end of the partition. prev_frame_start is suitable, because it
// is a pointer to the first row of the previous frame that must have been
// valid, or to the first row of the partition, and we make sure not do drop
// its block.
const auto block_rows = blockRowsNumber(partition_end);
for (; partition_end.row < block_rows; ++partition_end.row)
{
// fmt::print(stderr, "compare reference '{}' to compared '{}'\n",
// frame_end, partition_end);
// prev_frame_start, partition_end);
size_t i = 0;
for (; i < partition_by_columns; i++)
{
const auto * reference_column
= inputAt(frame_end)[partition_by_indices[i]].get();
= inputAt(prev_frame_start)[partition_by_indices[i]].get();
const auto * compared_column
= inputAt(partition_end)[partition_by_indices[i]].get();
// fmt::print(stderr, "reference '{}', compared '{}'\n",
// (*reference_column)[frame_end.row],
// (*reference_column)[prev_frame_start.row],
// (*compared_column)[partition_end.row]);
if (compared_column->compareAt(partition_end.row,
frame_end.row, *reference_column,
prev_frame_start.row, *reference_column,
1 /* nan_direction_hint */) != 0)
{
break;
@ -1373,13 +1373,16 @@ void WindowTransform::work()
}
// We don't really have to keep the entire partition, and it can be big, so
// we want to drop the starting blocks to save memory.
// We can drop the old blocks if we already returned them as output, and the
// frame and the current row are already past them. Note that the frame
// start can be further than current row for some frame specs (e.g. EXCLUDE
// CURRENT ROW), so we have to check both.
// we want to drop the starting blocks to save memory. We can drop the old
// blocks if we already returned them as output, and the frame and the
// current row are already past them. We also need to keep the previous
// frame start because we use it as the partition etalon. It is always less
// than the current frame start, so we don't have to check the latter. Note
// that the frame start can be further than current row for some frame specs
// (e.g. EXCLUDE CURRENT ROW), so we have to check both.
assert(prev_frame_start <= frame_start);
const auto first_used_block = std::min(next_output_block_number,
std::min(frame_start.block, current_row.block));
std::min(prev_frame_start.block, current_row.block));
if (first_block_number < first_used_block)
{
@ -1392,6 +1395,7 @@ void WindowTransform::work()
assert(next_output_block_number >= first_block_number);
assert(frame_start.block >= first_block_number);
assert(prev_frame_start.block >= first_block_number);
assert(current_row.block >= first_block_number);
assert(peer_group_start.block >= first_block_number);
}

View File

@ -127,27 +127,27 @@ select number, max(number) over (partition by intDiv(number, 3) order by number
7 8 3
8 8 4
9 11 5
10 11 6
11 11 7
12 14 8
13 14 9
14 14 10
10 11 1
11 11 2
12 14 3
13 14 4
14 14 5
15 17 1
16 17 2
17 17 3
18 20 4
19 20 5
20 20 6
21 23 7
22 23 8
23 23 9
24 26 10
20 20 1
21 23 2
22 23 3
23 23 4
24 26 5
25 26 1
26 26 2
27 29 3
28 29 4
29 29 5
30 30 6
30 30 1
-- two functions over the same window
-- an explain test would also be helpful, but it's too immature now and I don't
-- want to change reference all the time
@ -158,7 +158,7 @@ select number, max(number) over (partition by intDiv(number, 3) order by number
3 5 3
4 5 2
5 5 1
6 6 4
6 6 1
-- check that we can work with constant columns
select median(x) over (partition by x) from (select 1 x);
1
@ -258,9 +258,9 @@ settings max_block_size = 5
12 4 0 2
13 4 1 3
14 4 0 2
15 5 1 6
16 5 0 4
17 5 1 6
15 5 1 3
16 5 0 1
17 5 1 3
18 6 0 2
19 6 1 3
20 6 0 2
@ -273,7 +273,7 @@ settings max_block_size = 5
27 9 1 3
28 9 0 1
29 9 1 3
30 10 0 4
30 10 0 1
select number, intDiv(number, 5) p, mod(number, 3) o, count(number) over w as c
from numbers(31)
window w as (partition by p order by o range unbounded preceding)
@ -290,27 +290,27 @@ settings max_block_size = 2
7 1 1 3
8 1 2 5
9 1 0 2
10 2 1 8
11 2 2 10
12 2 0 6
13 2 1 8
14 2 2 10
10 2 1 3
11 2 2 5
12 2 0 1
13 2 1 3
14 2 2 5
15 3 0 2
16 3 1 4
17 3 2 5
18 3 0 2
19 3 1 4
20 4 2 10
21 4 0 7
22 4 1 8
23 4 2 10
24 4 0 7
20 4 2 5
21 4 0 2
22 4 1 3
23 4 2 5
24 4 0 2
25 5 1 3
26 5 2 5
27 5 0 1
28 5 1 3
29 5 2 5
30 6 0 6
30 6 0 1
select number, intDiv(number, 5) p, mod(number, 2) o, count(number) over w as c
from numbers(31)
window w as (partition by p order by o range unbounded preceding)
@ -332,11 +332,11 @@ settings max_block_size = 3
12 2 0 3
13 2 1 5
14 2 0 3
15 3 1 10
16 3 0 7
17 3 1 10
18 3 0 7
19 3 1 10
15 3 1 5
16 3 0 2
17 3 1 5
18 3 0 2
19 3 1 5
20 4 0 3
21 4 1 5
22 4 0 3
@ -347,7 +347,7 @@ settings max_block_size = 3
27 5 1 5
28 5 0 2
29 5 1 5
30 6 0 6
30 6 0 1
select number, intDiv(number, 3) p, mod(number, 5) o, count(number) over w as c
from numbers(31)
window w as (partition by p order by o range unbounded preceding)
@ -360,31 +360,31 @@ settings max_block_size = 2
3 1 3 2
4 1 4 3
5 1 0 1
6 2 1 4
7 2 2 5
8 2 3 6
6 2 1 1
7 2 2 2
8 2 3 3
9 3 4 3
10 3 0 1
11 3 1 2
12 4 2 4
13 4 3 5
14 4 4 6
12 4 2 1
13 4 3 2
14 4 4 3
15 5 0 1
16 5 1 2
17 5 2 3
18 6 3 5
19 6 4 6
20 6 0 4
18 6 3 2
19 6 4 3
20 6 0 1
21 7 1 1
22 7 2 2
23 7 3 3
24 8 4 6
25 8 0 4
26 8 1 5
24 8 4 3
25 8 0 1
26 8 1 2
27 9 2 1
28 9 3 2
29 9 4 3
30 10 0 4
30 10 0 1
select number, intDiv(number, 2) p, mod(number, 5) o, count(number) over w as c
from numbers(31)
window w as (partition by p order by o range unbounded preceding)
@ -397,31 +397,31 @@ settings max_block_size = 3
3 1 3 2
4 2 4 2
5 2 0 1
6 3 1 3
7 3 2 4
6 3 1 1
7 3 2 2
8 4 3 1
9 4 4 2
10 5 0 1
11 5 1 2
12 6 2 3
13 6 3 4
12 6 2 1
13 6 3 2
14 7 4 2
15 7 0 1
16 8 1 1
17 8 2 2
18 9 3 3
19 9 4 4
18 9 3 1
19 9 4 2
20 10 0 1
21 10 1 2
22 11 2 1
23 11 3 2
24 12 4 4
25 12 0 3
24 12 4 2
25 12 0 1
26 13 1 1
27 13 2 2
28 14 3 1
29 14 4 2
30 15 0 3
30 15 0 1
select number, intDiv(number, 2) p, mod(number, 3) o, count(number) over w as c
from numbers(31)
window w as (partition by p order by o range unbounded preceding)
@ -438,8 +438,8 @@ settings max_block_size = 5
7 3 1 2
8 4 2 2
9 4 0 1
10 5 1 3
11 5 2 4
10 5 1 1
11 5 2 2
12 6 0 1
13 6 1 2
14 7 2 2
@ -448,8 +448,8 @@ settings max_block_size = 5
17 8 2 2
18 9 0 1
19 9 1 2
20 10 2 4
21 10 0 3
20 10 2 2
21 10 0 1
22 11 1 1
23 11 2 2
24 12 0 1
@ -458,7 +458,7 @@ settings max_block_size = 5
27 13 0 1
28 14 1 1
29 14 2 2
30 15 0 3
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));
@ -488,34 +488,34 @@ settings max_block_size = 2;
0 0 2 2
0 0 2 2
0 0 2 2
3 3 8 8
3 3 8 8
3 3 8 8
3 3 8 8
3 3 8 8
3 3 8 8
9 9 14 14
9 9 14 14
9 9 14 14
9 9 14 14
9 9 14 14
9 9 14 14
15 15 20 20
15 15 20 20
15 15 20 20
15 15 20 20
15 15 20 20
15 15 20 20
21 21 26 26
21 21 26 26
21 21 26 26
21 21 26 26
21 21 26 26
21 21 26 26
27 27 30 30
27 27 30 30
27 27 30 30
27 27 30 30
3 3 5 5
3 3 5 5
3 3 5 5
6 6 8 8
6 6 8 8
6 6 8 8
9 9 11 11
9 9 11 11
9 9 11 11
12 12 14 14
12 12 14 14
12 12 14 14
15 15 17 17
15 15 17 17
15 15 17 17
18 18 20 20
18 18 20 20
18 18 20 20
21 21 23 23
21 21 23 23
21 21 23 23
24 24 26 26
24 24 26 26
24 24 26 26
27 27 29 29
27 27 29 29
27 27 29 29
30 30 30 30
-- ROWS offset frame start
select number, p,
count(*) over (partition by p order by number
@ -532,32 +532,32 @@ settings max_block_size = 2;
2 0 4 3 2
3 0 3 2 1
4 0 2 1 0
5 1 10 10 9
6 1 10 9 8
7 1 9 8 7
8 1 8 7 6
9 1 7 6 5
10 2 6 5 4
5 1 5 5 4
6 1 5 4 3
7 1 4 3 2
8 1 3 2 1
9 1 2 1 0
10 2 5 5 4
11 2 5 4 3
12 2 4 3 2
13 2 3 2 1
14 2 2 1 0
15 3 10 10 9
16 3 10 9 8
17 3 9 8 7
18 3 8 7 6
19 3 7 6 5
20 4 6 5 4
15 3 5 5 4
16 3 5 4 3
17 3 4 3 2
18 3 3 2 1
19 3 2 1 0
20 4 5 5 4
21 4 5 4 3
22 4 4 3 2
23 4 3 2 1
24 4 2 1 0
25 5 6 6 5
26 5 6 5 4
27 5 5 4 3
28 5 4 3 2
29 5 3 2 1
30 6 2 1 0
25 5 5 5 4
26 5 5 4 3
27 5 4 3 2
28 5 3 2 1
29 5 2 1 0
30 6 1 1 0
-- ROWS offset frame start and end
select number, p,
count(*) over (partition by p order by number
@ -577,10 +577,10 @@ settings max_block_size = 2;
9 1 5
10 1 5
11 1 5
12 1 5
13 1 5
14 2 5
15 2 5
12 1 4
13 1 3
14 2 3
15 2 4
16 2 5
17 2 5
18 2 5
@ -591,10 +591,10 @@ settings max_block_size = 2;
23 3 5
24 3 5
25 3 5
26 3 5
27 3 5
28 4 5
29 4 5
26 3 4
27 3 3
28 4 3
29 4 4
30 4 5
31 4 5
32 4 5
@ -605,10 +605,10 @@ settings max_block_size = 2;
37 5 5
38 5 5
39 5 5
40 5 5
41 5 5
42 6 5
43 6 5
40 5 4
41 5 3
42 6 3
43 6 4
44 6 5
45 6 5
46 6 5
@ -619,10 +619,10 @@ settings max_block_size = 2;
51 7 5
52 7 5
53 7 5
54 7 5
55 7 5
56 8 5
57 8 5
54 7 4
55 7 3
56 8 3
57 8 4
58 8 5
59 8 5
60 8 5
@ -633,9 +633,9 @@ settings max_block_size = 2;
65 9 5
66 9 5
67 9 5
68 9 5
69 9 4
70 10 3
68 9 4
69 9 3
70 10 1
SELECT count(*) OVER (ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) FROM numbers(4);
1
2
@ -676,31 +676,31 @@ settings max_block_size = 2;
1 0 1 3
4 0 1 3
2 0 2 1
6 1 0 10
9 1 0 10
7 1 1 8
5 1 2 7
8 1 2 7
6 1 0 5
9 1 0 5
7 1 1 3
5 1 2 2
8 1 2 2
12 2 0 5
10 2 1 4
13 2 1 4
11 2 2 2
14 2 2 2
15 3 0 10
18 3 0 10
16 3 1 8
19 3 1 8
17 3 2 6
15 3 0 5
18 3 0 5
16 3 1 3
19 3 1 3
17 3 2 1
21 4 0 5
24 4 0 5
22 4 1 3
20 4 2 2
23 4 2 2
27 5 0 6
25 5 1 5
28 5 1 5
26 5 2 3
29 5 2 3
27 5 0 5
25 5 1 4
28 5 1 4
26 5 2 2
29 5 2 2
30 6 0 1
select
count(*) over (rows between current row and current row),
@ -993,27 +993,27 @@ settings max_block_size = 2;
7 1 1 3 3 2 3
5 1 2 5 4 3 4
8 1 2 5 4 3 5
12 2 0 6 6 4 6
10 2 1 8 7 5 7
13 2 1 8 7 5 8
11 2 2 10 9 6 9
14 2 2 10 9 6 10
12 2 0 1 1 1 1
10 2 1 3 2 2 2
13 2 1 3 2 2 3
11 2 2 5 4 3 4
14 2 2 5 4 3 5
15 3 0 2 1 1 2
18 3 0 2 1 1 1
16 3 1 4 3 2 3
19 3 1 4 3 2 4
17 3 2 5 5 3 5
21 4 0 7 6 4 6
24 4 0 7 6 4 7
22 4 1 8 8 5 8
20 4 2 10 9 6 10
23 4 2 10 9 6 9
21 4 0 2 1 1 1
24 4 0 2 1 1 2
22 4 1 3 3 2 3
20 4 2 5 4 3 5
23 4 2 5 4 3 4
27 5 0 1 1 1 1
25 5 1 3 2 2 2
28 5 1 3 2 2 3
26 5 2 5 4 3 4
29 5 2 5 4 3 5
30 6 0 6 6 4 6
30 6 0 1 1 1 1
-- our replacement for lag/lead
select
anyOrNull(number)
@ -1053,7 +1053,7 @@ settings max_block_size = 3;
12 2 10 11 10 10 14
13 2 10 12 10 10 143
14 2 10 13 10 10 154
15 3 15 14 15 15 15
15 3 15 0 15 15 15
-- careful with auto-application of Null combinator
select lagInFrame(toNullable(1)) over ();
\N