@@ -8,17 +8,19 @@ namespace duckdb {
88
99WindowSegmentTree::WindowSegmentTree (AggregateFunction &aggregate, FunctionData *bind_info,
1010 const LogicalType &result_type_p, ChunkCollection *input,
11- WindowAggregationMode mode_p)
11+ const ValidityMask &filter_mask_p, WindowAggregationMode mode_p)
1212 : aggregate(aggregate), bind_info(bind_info), result_type(result_type_p), state(aggregate.state_size()),
1313 statep (Value::POINTER((idx_t )state.data())), frame(0 , 0 ), active(0 , 1 ),
14- statev(Value::POINTER((idx_t )state.data())), internal_nodes(0 ), input_ref(input), mode(mode_p) {
14+ statev(Value::POINTER((idx_t )state.data())), internal_nodes(0 ), input_ref(input), filter_mask(filter_mask_p),
15+ mode(mode_p) {
1516#if STANDARD_VECTOR_SIZE < 512
1617 throw NotImplementedException (" Window functions are not supported for vector sizes < 512" );
1718#endif
1819 statep.Normalify (STANDARD_VECTOR_SIZE);
1920 statev.SetVectorType (VectorType::FLAT_VECTOR); // Prevent conversion of results to constants
2021
2122 if (input_ref && input_ref->ColumnCount () > 0 ) {
23+ filter_sel.Initialize (STANDARD_VECTOR_SIZE);
2224 inputs.Initialize (input_ref->Types ());
2325 // if we have a frame-by-frame method, share the single state
2426 if (aggregate.window && UseWindowAPI ()) {
@@ -99,6 +101,19 @@ void WindowSegmentTree::ExtractFrame(idx_t begin, idx_t end) {
99101 VectorOperations::Copy (chunk_b.data [i], v, chunk_b_count, 0 , chunk_a_count);
100102 }
101103 }
104+
105+ // Slice to any filtered rows
106+ if (!filter_mask.AllValid ()) {
107+ idx_t filtered = 0 ;
108+ for (idx_t i = begin; i < end; ++i) {
109+ if (filter_mask.RowIsValid (i)) {
110+ filter_sel.set_index (filtered++, i - begin);
111+ }
112+ }
113+ if (filtered != inputs.size ()) {
114+ inputs.Slice (filter_sel, filtered);
115+ }
116+ }
102117}
103118
104119void WindowSegmentTree::WindowSegmentValue (idx_t l_idx, idx_t begin, idx_t end) {
@@ -179,7 +194,16 @@ void WindowSegmentTree::Compute(Vector &result, idx_t rid, idx_t begin, idx_t en
179194 if (inputs.ColumnCount () == 0 ) {
180195 D_ASSERT (GetTypeIdSize (result_type.InternalType ()) == sizeof (idx_t ));
181196 auto data = FlatVector::GetData<idx_t >(result);
182- data[rid] = end - begin;
197+ // Slice to any filtered rows
198+ if (!filter_mask.AllValid ()) {
199+ idx_t filtered = 0 ;
200+ for (idx_t i = begin; i < end; ++i) {
201+ filtered += filter_mask.RowIsValid (i);
202+ }
203+ data[rid] = filtered;
204+ } else {
205+ data[rid] = end - begin;
206+ }
183207 return ;
184208 }
185209
@@ -220,8 +244,8 @@ void WindowSegmentTree::Compute(Vector &result, idx_t rid, idx_t begin, idx_t en
220244 active = FrameBounds (active_chunks.first * STANDARD_VECTOR_SIZE,
221245 MinValue ((active_chunks.second + 1 ) * STANDARD_VECTOR_SIZE, coll.Count ()));
222246
223- aggregate.window (inputs.data .data (), bind_info, inputs.ColumnCount (), state.data (), frame, prev, result, rid ,
224- active.first );
247+ aggregate.window (inputs.data .data (), filter_mask, bind_info, inputs.ColumnCount (), state.data (), frame, prev,
248+ result, rid, active.first );
225249 return ;
226250 }
227251
0 commit comments