@@ -424,14 +424,30 @@ def errors_to_ignore(self, exe: Executor) -> list[str]:
424424 Oid ,
425425 ) + tuple (RANGE_TYPES )
426426
427- def aggregate_fns (self , column : Column ) -> list [str ]:
427+ def aggregate_fns (self , column : Column , window : bool = False ) -> list [str ]:
428428 """Aggregate function templates valid for the column's type.
429429
430430 Used both in window position (OVER ..) and in GROUP BY position. The
431431 collection aggregates (array_agg/list_agg/jsonb_agg/string_agg)
432432 exercise the "collection" reduce rendering, distinct from the
433433 accumulable sum/count path. Type exclusions are empirically derived,
434- e.g. array_agg rejects char and cannot nest map/list/array."""
434+ e.g. array_agg rejects char and cannot nest map/list/array.
435+
436+ TODO: Reenable when CPU-200 is fixed.
437+
438+ `window` drops the collection aggregates. In GROUP BY position they
439+ emit one collected value per group, which is linear in the input. In
440+ window position every row of a partition receives an aggregate over
441+ the whole partition, so the reduce's output arrangement holds N rows
442+ of O(N) bytes each and a single partition of N rows costs O(N^2) on
443+ the replica. Nothing bounds that. `LIMIT` lands in the peek's
444+ `Finish`, above the dataflow that already built the whole collection,
445+ and `max_result_size` only measures the final peek result. Views
446+ whose partition-key column is a literal put every row in one
447+ partition, and CDC source tables carry up to
448+ `MySqlSource.prepopulate_rows` rows rather than `MAX_ROWS`, so N
449+ reaches the tens of thousands. See the `window-collection-aggregate`
450+ scenario in test/bounded-memory."""
435451 dt = column .data_type
436452 fns = ["COUNT({})" ]
437453 if dt in NUMBER_TYPES :
@@ -450,6 +466,9 @@ def aggregate_fns(self, column: Column) -> list[str]:
450466 fns .extend (["BOOL_AND({})" , "BOOL_OR({})" ])
451467 if dt not in self ._MINMAX_EXCLUDED :
452468 fns .extend (["MAX({})" , "MIN({})" ])
469+ if window :
470+ # TODO: Reenable when CPU-200 is fixed.
471+ return fns
453472 # Collection aggregates.
454473 fns .append ("jsonb_agg({})" )
455474 if dt != Char :
@@ -653,7 +672,7 @@ def where_clause() -> str:
653672 column1 = self .rng .choice (all_columns )
654673 column2 = self .rng .choice (all_columns )
655674 column3 = self .rng .choice (all_columns )
656- window_fn = self .rng .choice (self .aggregate_fns (column1 ))
675+ window_fn = self .rng .choice (self .aggregate_fns (column1 , window = True ))
657676 select_list .append (
658677 f"{ window_fn .format (column1 )} OVER (PARTITION BY { column2 } ORDER BY { column3 } )"
659678 )
0 commit comments