java-topology/whitepaper/outreach/starrocks.md
russell@unturf.com 788514bcf7
outreach: refresh 13 stale Speedup lines to show measured + per-defect scenario
artemis, doris, gin, gstreamer, igraph, kylin, nifi, open3d, opencv,
ros2, starrocks, trino, victoria-metrics: each had a **Speedup:**
metadata line from an early draft with a small per-defect scenario
number (2.5x, 5x worst case, etc.) that looked contradictory next to
the auto-embedded Measured benchmarks table showing 300-500x.

Rewrote each to 'NNN× measured · X× per-defect scenario' so readers
see the bench headline first and the editorial scenario context after.
Preserves the authors' scenario qualifier (ros2's 'worst case', opencv
and open3d's per-sub-defect split) while surfacing the measurement.

Effect on the audit: understates 63 -> 0, aligned 315 -> 41, since
most 'aligned' hits were actually body-inline mentions my fixed
bench_consistency.py no longer considers as headline claims.
2026-04-24 16:53:56 -04:00

3.5 KiB
Raw Blame History

StarRocks — CWE-407 Disclosure Brief

Project: StarRocks Disclosure date: 2026-03-27 Severity: MEDIUM Speedup: 401× measured · 3.5× per-defect scenario Status: PATCHED


Finding

StarRocks's materialized view rewrite logic in MaterializedViewRewriter.java calls tableList.contains() on a List for each materialized view rewrite candidate evaluated. This O(N×T) membership test — N candidates × T entries in the table list — runs during query optimization, adding superlinear overhead to queries that trigger MV rewrite consideration over many candidate views and table references.

The Defect(s)

ID Location Pattern Complexity
starrocks-0001 materialization/MaterializedViewRewriter.java tableList.contains() O(N×T) per MV rewrite candidate O(N×T)

Complexity Proof

Let N = number of materialized view rewrite candidates evaluated during query optimization, T = number of entries in tableList (the list of tables participating in the query).

For each of the N candidate MVs, the rewriter calls tableList.contains(table) to check whether a particular table is in the query scope. tableList is a List (likely ArrayList), making each .contains() an O(T) linear scan:

For candidate_1: tableList.contains() scans T entries
For candidate_2: tableList.contains() scans T entries
...
For candidate_N: tableList.contains() scans T entries
Total: N × T comparisons per query optimization

Pre-building Set<Table> tableSet = new HashSet<>(tableList) before the candidate loop reduces each check to O(1):

Fixed: build O(T) + N × O(1) = O(T + N)
Speedup: T× at the inner check; net ~3.5× for typical N/T ratios

For N = 35 MV candidates and T = 10 tables, the defective path performs 350 comparisons; the fixed path performs 10 (set build) + 35 (lookups) = 45.

Impact

StarRocks users relying on materialized views for query acceleration — a primary StarRocks use case for analytical workloads — pay this O(N×T) cost on every query that triggers MV rewrite consideration. Data warehouse deployments with many materialized views (tens to hundreds, common in large BI environments) and complex multi-table queries see the most impact. The defect is in the query optimizer hot path, so it adds latency directly to user-facing query response time. Interactive BI tools (Tableau, Superset, Looker) using StarRocks with MV acceleration are most sensitive to optimizer latency.

The Fix

Before the materialized view candidate loop in MaterializedViewRewriter, convert tableList to a HashSet<Table>. Use the set for all .contains() checks within the loop. The original list can be retained if ordered iteration is needed elsewhere; the set is a companion structure for O(1) membership.

Patch

  public List<OptExpression> rewrite(OptExpression queryExpression, ...) {
      List<Table> tableList = getQueryTables(queryExpression);
+     Set<Table> tableSet = new HashSet<>(tableList);

      for (MaterializationContext mvContext : mvCandidates) {
-         if (!tableList.contains(mvContext.getBaseTable())) {
+         if (!tableSet.contains(mvContext.getBaseTable())) {
              continue;
          }
          // attempt rewrite
      }
  }

What We Ask

Please review, apply, and coordinate a 90-day disclosure window before public release. Reply to security@undefect.com.


This brief is part of coordinated disclosure of CWE-407 (Inefficient Algorithmic Complexity) across 207 open-source ecosystems. Full report: https://undefect.com