1.4 KiB
UNDF: UNDF-2026-000000396
flink-0003: AggregateReduceGroupingRule — List.contains() inside for loop
Defect ID
flink-0003
File:Line
flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/plan/rules/logical/AggregateReduceGroupingRule.java:88
Description
In onMatch():
List<Integer> newGroupingList = newGrouping.toList(); // List<Integer>
for (int column : originalGrouping) { // O(G) iterations
if (newGroupingList.contains(column)) { // O(G) linear scan each time
...
}
}
newGroupingList is a List<Integer>. Each .contains() call does a linear scan
O(G) where G = number of grouping columns. Total: O(G²).
This fires during query planning on every aggregate that has reducible grouping keys — i.e., every GROUP BY with functional dependencies. In queries with wide GROUP BY clauses (e.g., 50+ columns in analytics), this is O(2500) instead of O(50).
Complexity
- Slow: O(G²) — List.contains() = O(G)
- Fast: O(G) — HashSet.contains() = O(1)
Severity
MEDIUM
Speedup Estimate
~G× improvement; at G=50 grouping columns, ~50x speedup in the planning phase.
Fix
Replace newGroupingList with Set<Integer> newGroupingSet = new HashSet<>(newGrouping.toList()).
The list is only used for .contains() and .size() — both work identically on HashSet.