avantgardnerio commented on code in PR #24035:
URL: https://github.com/apache/datafusion/pull/24035#discussion_r3741789327
##########
datafusion/physical-plan/src/windows/bounded_window_agg_exec.rs:
##########
@@ -76,8 +76,29 @@ use hashbrown::hash_table::HashTable;
use indexmap::IndexMap;
use log::debug;
+/// Callback receiver for per-partition window state.
+pub trait WindowStateObserver: Send + Sync {
+ /// Invoked once per (output-partition-index, PARTITION BY tuple) as each
+ /// PARTITION BY group closes.
+ ///
+ /// # Arguments
+ ///
+ /// * `partition_idx` - Output partition index of the
[`BoundedWindowAggExec`]
+ /// stream firing this callback.
+ /// * `partition_key` - The PARTITION BY tuple that just closed.
+ /// * `states` - One entry per window expression on the exec, in the same
+ /// order as [`BoundedWindowAggExec::window_expr`]; `None` for
+ /// non-aggregate window functions.
+ fn finalized(
+ &self,
Review Comment:
> Is it possible to call this with the relevant
Yes, done.
##########
datafusion/physical-plan/src/windows/bounded_window_agg_exec.rs:
##########
@@ -1042,9 +1103,45 @@ pub struct BoundedWindowAggStream {
/// partitions, so finished partitions are pruned eagerly instead and no
/// such bound is needed.
most_recent_row: Option<RecordBatch>,
+ /// Output partition index this stream serves; passed as the first
+ /// argument to [`WindowStateObserver::finalized`].
+ partition_idx: usize,
+ /// If set, invoked from [`Self::publish_finalized_states`] with the
+ /// finalized per-window-expression state for every partition key that is
+ /// about to be dropped.
+ state_observer: Option<Arc<dyn WindowStateObserver>>,
}
impl BoundedWindowAggStream {
+ /// Fire the [`WindowStateObserver`] for every partition key whose
+ /// `WindowAggState::is_end` is true.
+ fn publish_finalized_states(&mut self) -> Result<()> {
+ let Some(observer) = &self.state_observer else {
+ return Ok(());
+ };
+ let Some((first, rest)) = self.window_agg_states.split_first_mut()
else {
+ return Ok(());
+ };
+ for (key, ws) in first.iter_mut() {
+ if !ws.state.is_end {
+ continue;
+ }
+ let mut states: Vec<Option<Vec<ScalarValue>>> =
Review Comment:
Yes, done.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]