Skip to content

Conversation

hawkfish
Copy link
Contributor

There is no need to copy the old partitioned data when repartitioning.
But if we have started to combine, then repartitioning will duplicate data,
so don't resize then.

Richard Wesley added 2 commits February 19, 2023 16:19
There is no need to copy the old partitioned data when repartitioning.
But if we have started to combine, then repartitioning will duplicate data,
so don't resize then.
@hawkfish hawkfish requested a review from lnkuiper February 19, 2023 03:22
@Mytherin Mytherin linked an issue Feb 20, 2023 that may be closed by this pull request
2 tasks
@Mytherin
Copy link
Collaborator

Mytherin commented Feb 20, 2023

Thanks for the PR!

This still does not seem to solve the problem completely, though.

If I add a loop to the test:

# name: test/sql/window/test_window_repartition.test_slow
# description: Window reparitioning at scale
# group: [window]

statement ok
PRAGMA enable_verification

statement ok
create table df as 
	select d, i v1 
	from 
		range(date '2017-01-01', date '2020-12-31', interval '1' day) t(d), 
		range(3000) i
	;

loop i 0 100

query I
select count(*) 
from (
	select percent_rank() over (partition by d order by v1) as rank_v1 
	from df
);
----
4380000

endloop

Then running it I eventually get an off-by-a small amount still.

[0/1] (0%): test/sql/window/test_window_repartition.test_slow                   ================================================================================
Wrong result in query! (test/sql/window/test_window_repartition.test_slow:18)!
================================================================================
select count(*) 
from (
	select percent_rank() over (partition by d order by v1) as rank_v1 
	from df
);
================================================================================
Mismatch on row 1, column 1
4380253 <> 4380000
================================================================================
Expected result:
================================================================================
4380000
================================================================================
Actual result:
================================================================================
4380253

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
unittest is a Catch v2.13.7 host application.
Run with -? for options

-------------------------------------------------------------------------------
test/sql/window/test_window_repartition.test_slow
-------------------------------------------------------------------------------
/Users/myth/Programs/duckdb-bugfix/test/sqlite/test_sqllogictest.cpp:178
...............................................................................

test/sql/window/test_window_repartition.test_slow:18: FAILED:
explicitly with message:
  0

[1/1] (100%): test/sql/window/test_window_repartition.test_slow                 
===============================================================================
test cases:  1 |  0 passed | 1 failed
assertions: 21 | 20 passed | 1 failed

This amount always seems to be less than the vector size, so perhaps something happening with a resize while a vector is already in-flight?

@Mytherin
Copy link
Collaborator

Disabling all in-flight resizing seems to fix the issue, but this may be too heavy-handed of a solution:

diff --git a/src/execution/operator/aggregate/physical_window.cpp b/src/execution/operator/aggregate/physical_window.cpp
index fbd7865f02..958c574efe 100644
--- a/src/execution/operator/aggregate/physical_window.cpp
+++ b/src/execution/operator/aggregate/physical_window.cpp
@@ -170,7 +170,7 @@ private:
 
 void WindowGlobalSinkState::ResizeGroupingData(idx_t cardinality) {
        //      Have we started to combine? Then just live with it.
-       if (grouping_data && !grouping_data->GetPartitions().empty()) {
+       if (grouping_data) {
                return;
        }
        //      Is the average partition size too large?

@lnkuiper
Copy link
Contributor

I was able to reproduce this locally, and this seems to fix it:

void PartitionedColumnData::FlushAppendState(PartitionedColumnDataAppendState &state) {
        for (idx_t i = 0; i < state.partition_buffers.size(); i++) {
                auto &partition_buffer = *state.partition_buffers[i];
                if (partition_buffer.size() > 0) {
                        partitions[i]->Append(partition_buffer);
                        partition_buffer.Reset(); // Add this line!
                }
        }
}       

The buffer needed to be reset. Nowhere else in the codebase did we use the append state after flushing it, so this was not a problem before.

@Mytherin Mytherin merged commit d58ab18 into duckdb:master Feb 23, 2023
@hawkfish hawkfish deleted the window-pct-range branch March 3, 2023 21:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

percent_rank bugs
3 participants